Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-AIEngine
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-AIEngine
Commits
7aef45d7
Commit
7aef45d7
authored
Mar 30, 2021
by
wangdong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
e3651a8c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
334 additions
and
131 deletions
+334
-131
src/main/index.js
src/main/index.js
+69
-34
src/renderer/components/LandingPage.vue
src/renderer/components/LandingPage.vue
+15
-4
src/renderer/components/SshPage/SshPage.vue
src/renderer/components/SshPage/SshPage.vue
+46
-0
src/renderer/components/sliceInfos/BaseStationInfo.vue
src/renderer/components/sliceInfos/BaseStationInfo.vue
+86
-52
src/renderer/components/sliceInfos/SliceInformation.vue
src/renderer/components/sliceInfos/SliceInformation.vue
+73
-17
src/renderer/components/sliceInfos/UeLists.vue
src/renderer/components/sliceInfos/UeLists.vue
+3
-4
src/renderer/router/index.js
src/renderer/router/index.js
+16
-18
src/utils/flexranAPI.js
src/utils/flexranAPI.js
+26
-2
No files found.
src/main/index.js
View file @
7aef45d7
import
{
app
,
BrowserWindow
,
BrowserView
,
ipcMain
,
Menu
,
shell
,
screen
,
remote
}
from
'
electron
'
import
{
app
,
BrowserWindow
,
BrowserView
,
ipcMain
,
Menu
,
shell
,
screen
,
ipcRenderer
}
from
'
electron
'
import
{
runInDebugContext
}
from
'
vm
'
const
isMac
=
process
.
platform
===
'
darwin
'
let
FlexRAN
=
false
const
template
=
[
...
...
@@ -25,14 +26,14 @@ const template = [
label
:
'
FlexRAN Drone® Mosaic5G
'
,
click
()
{
//shell.openExternal('http://192.168.1.36');
if
(
!
FlexRAN
){
//
if(!FlexRAN){
openFlexran
()
FlexRAN
=
!
FlexRAN
}
else
{
closeFlexran
()
FlexRAN
=
!
FlexRAN
}
//
FlexRAN = !FlexRAN
//
}
//
else{
//
closeFlexran()
//
FlexRAN = !FlexRAN
//
}
},
},
...
...
@@ -45,21 +46,45 @@ const template = [
{
label
:
'
OAI核心网
'
,
click
()
{
createNewWindow
(
"
http://10.25.20.227:2222/ssh/host/192.168.1.12?autologin=1&user=root&pass=199710
"
)
createNewWindow
(
"
192.168.1.12
"
)
},
},
{
label
:
'
OAI基站
'
,
click
()
{
createNewWindow
(
"
http://10.25.20.227:2222/ssh/host/192.168.1.193?autologin=1&user=root&pass=199710
"
)
createNewWindow
(
"
192.168.1.193
"
)
},
},
{
label
:
'
OAI-SIM
'
,
click
()
{
createNewWindow
(
"
http://10.25.20.227:2222/ssh/host/192.168.1.212?autologin=1&user=root&pass=199710
"
)
createNewWindow
(
"
192.168.1.212
"
)
},
},
{
label
:
'
AI-Engine
'
,
click
()
{
createNewWindow
(
"
192.168.1.150
"
,
'
tony
'
,
'
199710
'
)
},
},
]
},
{
label
:
'
运行
'
,
submenu
:
[
{
label
:
'
运行OAI基站(USRP B210)
'
,
click
()
{
runeNB
()
},
},
{
label
:
'
运行OAI基站(L2-nFAPI)
'
,
click
()
{
runeNBl2
()
},
}
]
},
...
...
@@ -91,24 +116,32 @@ const winURL = process.env.NODE_ENV === 'development'
?
`http://localhost:9080`
:
`file://
${
__dirname
}
/index.html`
function
runeNB
(){
mainWindow
.
webContents
.
send
(
'
eNB
'
,
'
/page1
'
);
}
function
runeNBl2
(){
mainWindow
.
webContents
.
send
(
'
eNBl2
'
,
'
/page1
'
);
}
function
createNewWindow
(
url
){
function
createNewWindow
(
host
,
user
,
pass
){
let
win
/**
* Initial window options
*/
win
=
new
BrowserWindow
({
minWidth
:
4
00
,
minHeight
:
6
00
,
width
:
4
00
,
minWidth
:
3
00
,
minHeight
:
3
00
,
width
:
3
00
,
height
:
600
,
useContentSize
:
true
,
parent
:
mainWindow
,
webPreferences
:
{
nodeIntegration
:
true
,
webSecurity
:
false
}
})
win
.
loadURL
(
url
)
win
.
loadURL
(
winURL
+
`/#/ssh/
${
host
}
/start_enb/
${
user
==
undefined
?
'
root
'
:
user
}
/
${
pass
==
undefined
?
'
199710
'
:
pass
}
/`
)
newWindows
.
push
(
win
)
}
...
...
@@ -138,30 +171,32 @@ Menu.setApplicationMenu( Menu.buildFromTemplate(template));
})
}
function
openFlexran
(){
view
=
new
BrowserView
()
mainWindow
.
setBrowserView
(
view
)
console
.
log
(
mainWindow
.
getContentBounds
())
view
.
setBounds
({
x
:
1364
,
y
:
0
,
width
:
556
,
height
:
mainWindow
.
getContentBounds
()[
"
height
"
]
})
view
.
webContents
.
loadURL
(
"
http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710
"
)
view
.
setAutoResize
({
width
:
true
,
height
:
true
,
horizontal
:
true
,
vertical
:
true
})
// child = new BrowserWindow({
// minWidth:1920,
// minHeight:1000,
// width: screen.getPrimaryDisplay().workAreaSize.width,
// height: screen.getPrimaryDisplay().workAreaSize.height,
// useContentSize: true,
// webPreferences: {
// nodeIntegration: true,
// webSecurity: false
// }
// })
// view = new BrowserView()
// mainWindow.setBrowserView(view)
// console.log(mainWindow.getContentBounds())
// view.setBounds({ x: 1364, y: 0, width: 556, height: mainWindow.getContentBounds()["height"] })
// view.webContents.loadURL("http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710")
// view.setAutoResize({width:true,height:true, horizontal:true,vertical:true})
child
=
new
BrowserWindow
({
minWidth
:
500
,
minHeight
:
500
,
width
:
500
,
height
:
500
,
parent
:
mainWindow
,
useContentSize
:
true
,
webPreferences
:
{
nodeIntegration
:
true
,
webSecurity
:
false
}
})
// view1 = new BrowserView()
// child.setBrowserView(view1)
// console.log(child.getContentBounds())
// view1.setBounds({ x: 1364, y: 0, width: 556, height: child.getContentBounds()["height"] })
// view1.webContents.loadURL("http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710")
// view1.setAutoResize({width:true,height:true, horizontal:true,vertical:true})
// child.loadURL("http://192.168.1.36")
console
.
log
(
winURL
)
child
.
loadURL
(
'
http://ustb-oai.com:2224
'
)
}
function
closeFlexran
(){
...
...
src/renderer/components/LandingPage.vue
View file @
7aef45d7
<
template
>
<div
id=
"first"
>
<header><img
src=
"~@/assets/ustb-oai.com.png"
alt=
"electron-vue"
width=
"400px"
></header>
<div
id=
"wrapper"
>
<main>
<div
id=
"left"
class=
"left-side"
>
<img
src=
"~@/assets/ustb-oai.com.png"
alt=
"electron-vue"
width=
"350px"
>
<slice-information></slice-information>
</div>
...
...
@@ -11,6 +11,8 @@
<base-station-info></base-station-info>
</div>
</main>
</div>
</div>
</
template
>
...
...
@@ -19,6 +21,7 @@
import
SystemInformation
from
'
./LandingPage/SystemInformation
'
import
SliceInformation
from
'
./sliceInfos/SliceInformation
'
import
BaseStationInfo
from
'
./sliceInfos/BaseStationInfo
'
import
SshPage
from
'
./SshPage/SshPage
'
import
UeLists
from
'
./sliceInfos/UeLists
'
import
*
as
flexranAPI
from
"
../../utils/flexranAPI
"
import
{
ipcRenderer
}
from
'
electron
'
...
...
@@ -27,7 +30,7 @@
export
default
{
name
:
'
landing-page
'
,
components
:
{
SystemInformation
,
'
slice-information
'
:
SliceInformation
,
"
ue-lists
"
:
UeLists
,
"
base-station-info
"
:
BaseStationInfo
},
components
:
{
SystemInformation
,
'
slice-information
'
:
SliceInformation
,
"
ue-lists
"
:
UeLists
,
"
base-station-info
"
:
BaseStationInfo
,
"
ssh-page
"
:
SshPage
},
mounted
(){
},
...
...
@@ -53,10 +56,15 @@
margin
:
0
;
padding
:
0
;
}
html
,
body
,
#app
{
height
:
100%
;
}
body
{
font-family
:
'Source Sans Pro'
,
sans-serif
;
}
img
{
filter
:
grayscale
(
70%
);
display
:
fixed
;
bottom
:
2px
;
}
header
{
margin-top
:
15px
;
...
...
@@ -74,11 +82,14 @@ header {
}
#left
{
padding-right
:
10px
;
}
.right-side
{
margin-top
:
76.39px
;
}
main
{
display
:
flex
;
justify-content
:
space-between
;
margin-right
:
5
5
6px
;
margin-right
:
56px
;
}
main
>
div
{
flex-basis
:
50%
;
}
...
...
@@ -88,7 +99,7 @@ header {
flex-direction
:
column
;
}
#first
{
height
:
100%
;
}
...
...
src/renderer/components/SshPage/SshPage.vue
0 → 100644
View file @
7aef45d7
<
template
>
<div
style=
"height:100%"
>
<iframe
id=
"show-iframe"
style=
"height:95%;width:100%"
frameborder=
0
name=
"showHere"
scrolling=
auto
:src=
"src"
></iframe>
<img
src=
"~@/assets/ustb-oai.com.png"
alt=
"electron-vue"
height=
"4%"
>
</div>
</
template
>
<
script
>
import
Vue
from
"
vue
"
;
import
vueJsonTreeView
from
"
vue-json-tree-view
"
;
import
*
as
flexranAPI
from
"
../../../utils/flexranAPI
"
;
Vue
.
use
(
vueJsonTreeView
);
export
default
{
data
()
{
return
{
dataList
:[],
host
:
''
,
action
:
''
,
src
:
'
http://10.25.20.227:2222/ssh/host/192.168.1.210?autologin=1&user=root&pass=199710
'
};
},
mounted
()
{
this
.
host
=
this
.
$route
.
params
.
host
this
.
action
=
this
.
$route
.
params
.
action
this
.
user
=
this
.
$route
.
params
.
user
this
.
pass
=
this
.
$route
.
params
.
pass
this
.
src
=
`http://10.25.20.227:2222/ssh/host/
${
this
.
host
}
?autologin=1&user=
${
this
.
user
}
&pass=
${
this
.
pass
}
`
},
methods
:{
getJS
(){
var
child
=
document
.
getElementById
(
"
show-iframe
"
).
contentWindow
;
let
a
=
child
.
document
.
getElementById
(
"
menu
"
);
console
.
log
(
a
)
}
},
};
</
script
>
<
style
>
html
,
body
,
#app
{
height
:
100%
;
}
.left
{}
</
style
>
src/renderer/components/sliceInfos/BaseStationInfo.vue
View file @
7aef45d7
<
template
>
<div>
<el-card>
<el-table
:data=
"dataList"
border
stripe
>
<el-table-column
type=
"index"
label=
"UE"
>
</el-table-column>
<el-table-column
prop=
"rnti"
label=
"RNTI"
width=
"100"
>
</el-table-column
>
<el-table-column
prop=
"Mbs"
label=
"速度
"
>
</el-table-column>
<el-table-column
label=
"切片"
>
<template
slot-scope=
"scope"
>
<el-tag
size=
"medium"
effect=
"dark"
>
{{
scope
.
row
.
label
}}
</el-tag>
</
template
>
</el-table-column
>
<el-table-column
prop=
"imsi"
label=
"IMSI"
>
</el-table-column>
</el-table>
</el-card>
</div>
<div>
<el-card>
<el-table
:data=
"dataList"
border
stripe
>
<el-table-column
type=
"index"
label=
"UE"
></el-table-column>
<el-table-column
prop=
"rnti"
label=
"RNTI"
width=
"100"
>
</el-table-column>
<el-table-column
prop=
"Mbs"
label=
"速度"
>
</el-table-column>
<el-table-column
label=
"切片"
>
<template
slot-scope=
"scope"
>
<el-dropdown
>
<el-button
type=
"primary"
>
{{
scope
.
row
.
label
}}
</el-button>
<el-dropdown-menu
slot=
"dropdown
"
>
<el-dropdown-item
v-for=
"(item1, index1) in slices"
:key=
"index1"
v-bind=
"item1"
>
分配至:切片
{{
item1
.
id
}}
<el-tag
effect=
"dark"
@
click=
"changeslice(scope.row.imsi,item1.id)"
>
{{
item1
.
label
}}
</el-tag></el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
</
template
>
</el-table-column>
<el-table-column
prop=
"imsi"
label=
"IMSI"
>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<
script
>
import
Vue
from
"
vue
"
;
import
vueJsonTreeView
from
"
vue-json-tree-view
"
;
import
*
as
flexranAPI
from
"
../../../utils/flexranAPI
"
import
Vue
from
"
vue
"
;
import
vueJsonTreeView
from
"
vue-json-tree-view
"
;
import
*
as
flexranAPI
from
"
../../../utils/flexranAPI
"
;
export
default
{
data
(){
return
{
dataList
:[],
}
data
()
{
return
{
dataList
:
[],
slices
:
[],
};
},
created
()
{
this
.
getDataList
();
},
methods
:
{
getDataList
()
{
this
.
timeInterval
=
setInterval
(
async
()
=>
{
let
res
=
await
flexranAPI
.
GET_MAC_STATS
({});
this
.
dataList
=
res
.
mac_stats
[
0
].
ue_list
;
this
.
slices
=
res
.
eNB_config
[
0
].
eNB
.
cellConfig
[
0
].
sliceConfig
.
dl
.
slices
;
},
1000
);
},
created
(){
this
.
getDataList
()
},
methods
:{
getDataList
(){
this
.
timeInterval
=
setInterval
(
async
()
=>
{
let
res
=
await
flexranAPI
.
GET_MAC_STATS
({})
this
.
dataList
=
res
.
mac_stats
[
0
].
ue_list
console
.
log
(
this
.
dataList
)
},
1000
);
changeslice
(
imsi
,
to
)
{
this
.
$confirm
(
`是否将
${
imsi
}
切换到切片
${
to
}
`
,
'
提示
'
,
{
confirmButtonText
:
'
确定
'
,
cancelButtonText
:
'
取消
'
,
type
:
'
info
'
}).
then
(()
=>
{
flexranAPI
.
CHANGE_SLICE_ASSOC
({
"
ueConfig
"
:
[
{
"
imsi
"
:
imsi
,
"
dlSliceId
"
:
to
,
}
]
},
-
1
).
then
((
res
)
=>
{
console
.
log
(
res
)
if
(
res
.
status
==
'
Ok
'
){
this
.
$message
({
type
:
'
success
'
,
message
:
'
切换成功!
'
});
}
else
{
this
.
$message
({
type
:
'
error
'
,
message
:
res
.
status
});
}
})
}
}).
catch
(()
=>
{
this
.
$message
({
type
:
'
info
'
,
message
:
'
已取消切换
'
});
});
}
}
},
};
</
script
>
<
style
lang=
"less"
scoped
>
</
style
>
src/renderer/components/sliceInfos/SliceInformation.vue
View file @
7aef45d7
...
...
@@ -7,34 +7,27 @@
</el-table-column>
<el-table-column
label=
"吞吐量(Mps)"
>
<template
slot-scope=
"scope"
>
{{
scope
.
row
.
ddqn
.
thrpt
}}
{{
scope
.
row
.
ddqn
.
thrpt
}}
</
template
>
</el-table-column>
<el-table-column
label=
"时延(ms)"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
ddqn
.
delay
}}
{{
scope
.
row
.
ddqn
.
delay
}}
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"PRB(x2)"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
ddqn
.
mrb
}}
{{
scope
.
row
.
ddqn
.
mrb
}}
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"RB使用情况"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
ddqn
.
arb
}}
{{
scope
.
row
.
ddqn
.
arb
}}
</
template
>
</el-table-column>
</el-table-column>
</el-table>
</el-card>
<!-- <iframe id="show-iframe" style="height:500px;width:100%" frameborder=0 name="showHere" scrolling=auto :src="src"></iframe> -->
</div>
</template>
...
...
@@ -42,17 +35,75 @@
import
Vue
from
"
vue
"
;
import
vueJsonTreeView
from
"
vue-json-tree-view
"
;
import
*
as
flexranAPI
from
"
../../../utils/flexranAPI
"
;
// 渲染进程接收主进程的传参
const
{
ipcRenderer
}
=
require
(
"
electron
"
);
Vue
.
use
(
vueJsonTreeView
);
export
default
{
data
()
{
return
{
dataList
:[],
dataList
:
[],
src
:
"
http://ustb-oai.com:2224
"
,
};
},
mounted
()
{
let
a
=
{
"
dl
"
:
{
"
algorithm
"
:
"
DDQN
"
,
"
slices
"
:
[
{
"
id
"
:
0
,
"
label
"
:
"
Besteffort
"
,
"
ddqn
"
:
{
"
typeid
"
:
0
,
"
arb
"
:
0
,
"
mrb
"
:
0
,
}
}
]
}
}
ipcRenderer
.
on
(
"
eNB
"
,
(
event
,
arg
)
=>
{
if
(
arg
)
{
flexranAPI
.
START_ENB
({})
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
'
Loading
'
,
spinner
:
'
el-icon-loading
'
,
background
:
'
rgba(0, 0, 0, 0.7)
'
});
setTimeout
(()
=>
{
flexranAPI
.
ADD_SLICE
(
a
,
-
1
)
loading
.
close
();
this
.
$message
({
message
:
'
成功启动OAI基站
'
,
type
:
'
success
'
});
},
4000
);
}
});
ipcRenderer
.
on
(
"
eNBl2
"
,
(
event
,
arg
)
=>
{
if
(
arg
)
{
flexranAPI
.
START_ENB_L2
({})
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
'
Loading
'
,
spinner
:
'
el-icon-loading
'
,
background
:
'
rgba(0, 0, 0, 0.7)
'
});
setTimeout
(()
=>
{
loading
.
close
();
this
.
$message
({
message
:
'
成功启动OAI基站
'
,
type
:
'
success
'
});
},
2000
);
}
});
this
.
timeInterval
=
setInterval
(()
=>
{
flexranAPI
.
GET_MAC_STATS
().
then
((
result
)
=>
{
this
.
dataList
=
result
.
eNB_config
[
0
].
eNB
.
cellConfig
[
0
].
sliceConfig
.
dl
.
slices
;
this
.
dataList
=
result
.
eNB_config
[
0
].
eNB
.
cellConfig
[
0
].
sliceConfig
.
dl
.
slices
;
});
},
1000
);
},
...
...
@@ -60,6 +111,11 @@ export default {
</
script
>
<
style
scoped
>
html
,
body
,
#app
{
height
:
100%
;
}
.title
{
color
:
#888
;
font-size
:
18px
;
...
...
src/renderer/components/sliceInfos/UeLists.vue
View file @
7aef45d7
...
...
@@ -54,8 +54,9 @@ export default {
},
mounted
()
{
this
.
timeInterval
=
setInterval
(()
=>
{
console
.
log
(
result
.
eNB_config
[
0
].
eNB
.
cellConfig
[
0
].
sliceConfig
.
dl
)
flexranAPI
.
GET_MAC_STATS
().
then
((
result
)
=>
{
try
{
this
.
slice_conf
=
result
.
eNB_config
[
0
].
eNB
.
cellConfig
[
0
].
sliceConfig
.
dl
;
this
.
ue_list
=
result
.
mac_stats
[
0
].
ue_list
;
...
...
@@ -65,9 +66,7 @@ export default {
);
this
.
ue_list
[
i
].
label
=
slice_type
[
0
].
label
;
}
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
},
1000
);
},
...
...
src/renderer/router/index.js
View file @
7aef45d7
import
Vue
from
'
vue
'
import
Router
from
'
vue-router
'
import
BaseStationInfo
from
'
../components/sliceInfos/BaseStationInfo
'
import
SshPage
from
'
../components/SshPage/SshPage
'
Vue
.
use
(
Router
)
// 渲染进程接收主进程的传参
const
{
ipcRenderer
}
=
require
(
'
electron
'
);
ipcRenderer
.
on
(
'
href
'
,
(
event
,
arg
)
=>
{
if
(
arg
)
{
router
.
push
({
path
:
arg
});
let
router
=
[
{
path
:
'
/
'
,
name
:
'
landing-page
'
,
component
:
require
(
'
@/components/LandingPage
'
).
default
},
{
path
:
'
/ssh/:host/:action/:user/:pass
'
,
name
:
'
ssh-page
'
,
component
:
SshPage
}
});
]
export
default
new
Router
({
routes
:
[
{
path
:
'
/
'
,
name
:
'
landing-page
'
,
component
:
require
(
'
@/components/LandingPage
'
).
default
},
{
path
:
'
*
'
,
redirect
:
'
/
'
}
]
routes
:
router
})
src/utils/flexranAPI.js
View file @
7aef45d7
...
...
@@ -12,6 +12,30 @@ import { service, request } from './network_services'
data
})
}
/**
* @description 启动eNB
* @param {Object} data NONE
*/
export
function
START_ENB
(
data
=
{})
{
// 接口请求
return
request
({
url
:
'
http://192.168.1.12:8110/api/startenb
'
,
method
:
'
get
'
,
data
})
}
/**
* @description 启动eNBl2
* @param {Object} data NONE
*/
export
function
START_ENB_L2
(
data
=
{})
{
// 接口请求
return
request
({
url
:
'
http://192.168.1.12:8110/api/startenbl2
'
,
method
:
'
get
'
,
data
})
}
/**
* @description 获取IPV4
* @param {Object} data {"imsi":"208920100001105"}
...
...
@@ -115,7 +139,7 @@ import { service, request } from './network_services'
export
function
CHANGE_SLICE_ASSOC
(
data
=
{},
ENB_ID
)
{
// 接口请求
return
request
({
url
:
'
/ue_slice_assoc/enb/
'
+
ENB_ID
,
url
:
'
http://ustb-oai.com:9999
/ue_slice_assoc/enb/
'
+
ENB_ID
,
method
:
'
post
'
,
data
})
...
...
@@ -155,7 +179,7 @@ import { service, request } from './network_services'
export
function
ADD_SLICE
(
data
=
{},
ENB_ID
)
{
// 接口请求
return
request
({
url
:
'
/slice/enb/
'
+
ENB_ID
,
url
:
'
http://ustb-oai.com:9999
/slice/enb/
'
+
ENB_ID
,
method
:
'
post
'
,
data
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment