Browse Source

优化级联添加通道流程

ui-optimization
648540858 3 years ago
parent
commit
9442c37ce7
  1. 2
      src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java
  2. 5
      src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java
  3. 2
      src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
  4. 29
      src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
  5. 18
      src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java
  6. 6
      src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
  7. 25
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java
  8. 45
      src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java
  9. 1
      web_src/index.html
  10. 6
      web_src/src/components/PushVideoList.vue
  11. 2
      web_src/src/components/UiHeader.vue
  12. 3
      web_src/src/components/dialog/catalogEdit.vue
  13. 14
      web_src/src/components/dialog/chooseChannel.vue
  14. 33
      web_src/src/components/dialog/chooseChannelForCatalog.vue
  15. 279
      web_src/src/components/dialog/chooseChannelForGb.vue
  16. 241
      web_src/src/components/dialog/chooseChannelForStream.vue
  17. 161
      web_src/src/components/dialog/getCatalog.vue
  18. 14
      web_src/static/css/iconfont.css
  19. BIN
      web_src/static/css/iconfont.woff2
  20. BIN
      web_src/static/favicon.ico

2
src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java

@ -17,7 +17,7 @@ public interface IGbStreamService {
* @param count
* @return
*/
PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId);
PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId,String query,Boolean pushing,String mediaServerId);
/**

5
src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java

@ -52,9 +52,9 @@ public class GbStreamServiceImpl implements IGbStreamService {
private EventPublisher eventPublisher;
@Override
public PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId) {
public PageInfo<GbStream> getAll(Integer page, Integer count, String platFormId, String catalogId, String query, Boolean pushing, String mediaServerId) {
PageHelper.startPage(page, count);
List<GbStream> all = gbStreamMapper.selectAll(platFormId);
List<GbStream> all = gbStreamMapper.selectAll(platFormId, catalogId, query, pushing, mediaServerId);
return new PageInfo<>(all);
}
@ -70,6 +70,7 @@ public class GbStreamServiceImpl implements IGbStreamService {
boolean result = false;
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
ParentPlatform parentPlatform = platformMapper.getParentPlatByServerGBId(platformId);
if (catalogId == null) catalogId = parentPlatform.getCatalogId();
try {
List<DeviceChannel> deviceChannelList = new ArrayList<>();
for (GbStream gbStream : gbStreams) {

2
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java

@ -239,7 +239,7 @@ public interface IVideoManagerStorager {
/**
* 查询通道信息不区分设备(已关联平台或全部)
*/
PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, Boolean channelType, String platformId, Boolean inPlatform);
PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, Boolean channelType, String platformId, String catalogId);
/**
* 查询设备的通道信息

29
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java

@ -93,28 +93,31 @@ public interface DeviceChannelMapper {
void startPlay(String deviceId, String channelId, String streamId);
@Select(value = {" <script>" +
"SELECT * FROM ( "+
" SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " +
"SELECT dc.channelId, "+
"dc.deviceId, " +
"dc.name, " +
"de.manufacturer, " +
"de.hostAddress, " +
"(SELECT count(0) FROM device_channel WHERE parentId = dc.channelId) as subCount, " +
"(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId AND pc.platformId = #{platformId}) as platformId, " +
"(SELECT pc.catalogId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId AND pc.platformId = #{platformId} ) as catalogId " +
"pgc.platformId as platformId, " +
"pgc.catalogId as catalogId " +
"FROM device_channel dc " +
"LEFT JOIN device de ON dc.deviceId = de.deviceId " +
"LEFT JOIN platform_gb_channel pgc on de.deviceId = pgc.deviceId and pgc.channelId = dc.channelId " +
"LEFT JOIN device_channel dc2 ON dc2.deviceId = de.deviceId AND dc2.parentId = dc.channelId " +
" WHERE 1=1 " +
" <if test='query != null'> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
" <if test='online == true' > AND dc.status=1</if> " +
" <if test='online == false' > AND dc.status=0</if> " +
") dcr" +
" WHERE 1=1 " +
" <if test='hasSubChannel!= null and hasSubChannel == true' > AND subCount >0</if> " +
" <if test='hasSubChannel!= null and hasSubChannel == false' > AND subCount=0</if> " +
" <if test='platformId != null and inPlatform == true ' > AND platformId='${platformId}'</if> " +
" <if test='platformId != null and inPlatform == false ' > AND (platformId != '${platformId}' OR platformId is NULL ) </if> " +
" ORDER BY deviceId, channelId ASC" +
" <if test='hasSubChannel!= null and hasSubChannel == true' > AND dc2.channelId is not null</if> " +
" <if test='hasSubChannel!= null and hasSubChannel == false' > AND dc2.channelId is null</if> " +
" <if test='catalogId == null ' > AND pgc.platformId is null AND pgc.catalogId is null</if> " +
" <if test='catalogId != null ' > AND pgc.platformId =#{platformId} AND pgc.catalogId = #{catalogId}</if> " +
" ORDER BY dc.deviceId, dc.channelId ASC" +
" </script>"})
List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform);
List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, String catalogId);
@Select("SELECT * FROM device_channel WHERE channelId=#{channelId}")
List<DeviceChannel> queryChannelByChannelId( String channelId);

18
src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java

@ -37,10 +37,20 @@ public interface GbStreamMapper {
@Delete("DELETE FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
int del(String app, String stream);
@Select("SELECT gs.*, pgs.platformId AS platformId, pgs.catalogId AS catalogId FROM gb_stream gs " +
"LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream AND (pgs.platformId = #{platformId} OR pgs.platformId is null)" +
"order by gs.id asc ")
List<GbStream> selectAll(String platformId);
@Select("<script> "+
"SELECT gs.*, pgs.platformId AS platformId, pgs.catalogId AS catalogId FROM gb_stream gs " +
"LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " +
"WHERE " +
"1=1 " +
" <if test='catalogId != null'> AND pgs.platformId = #{platformId} AND pgs.catalogId = #{catalogId}</if> " +
" <if test='catalogId == null'> AND pgs.platformId is null AND pgs.catalogId is null</if> " +
" <if test='query != null'> AND (gs.app LIKE '%${query}%' OR gs.stream LIKE '%${query}%' OR gs.gbId LIKE '%${query}%' OR gs.name LIKE '%${query}%')</if> " +
" <if test='pushing == true' > AND gs.status=1</if>" +
" <if test='pushing == false' > AND gs.status=0</if>" +
" <if test='mediaServerId != null' > AND gs.mediaServerId=#{mediaServerId} </if>" +
" order by gs.id asc " +
"</script>")
List<GbStream> selectAll(String platformId, String catalogId, String query, Boolean pushing, String mediaServerId);
@Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}")
StreamProxyItem selectOne(String app, String stream);

6
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java

@ -575,16 +575,16 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
@Override
public PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online,
Boolean channelType, String platformId, Boolean inPlatform) {
Boolean channelType, String platformId, String catalogId) {
PageHelper.startPage(page, count);
List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, inPlatform);
List<ChannelReduce> all = deviceChannelMapper.queryChannelListInAll(query, online, channelType, platformId, catalogId);
return new PageInfo<>(all);
}
@Override
public List<ChannelReduce> queryChannelListInParentPlatform(String platformId) {
return deviceChannelMapper.queryChannelListInAll(null, null, null, platformId, true);
return deviceChannelMapper.queryChannelListInAll(null, null, null, platformId, null);
}
@Override

25
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java

@ -12,6 +12,7 @@ import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
@Api(tags = "视频流关联到级联平台")
@ -40,15 +41,33 @@ public class GbStreamController {
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "当前页", required = true , dataTypeClass = Integer.class),
@ApiImplicitParam(name = "count", value = "每页条数", required = true , dataTypeClass = Integer.class),
@ApiImplicitParam(name = "platformId", value = "平台ID", required = true , dataTypeClass = Integer.class),
@ApiImplicitParam(name = "platformId", value = "平台ID", required = true , dataTypeClass = String.class),
@ApiImplicitParam(name = "catalogId", value = "目录ID", required = false , dataTypeClass = String.class),
@ApiImplicitParam(name="query", value = "查询内容", required = false , dataTypeClass = String.class),
@ApiImplicitParam(name="pushing", value = "是否正在推流", required = false , dataTypeClass = Boolean.class),
@ApiImplicitParam(name="mediaServerId", value = "流媒体ID", required = false , dataTypeClass = String.class),
})
@GetMapping(value = "/list")
@ResponseBody
public PageInfo<GbStream> list(@RequestParam(required = true)Integer page,
@RequestParam(required = true)Integer count,
@RequestParam(required = true)String platformId){
@RequestParam(required = true)String platformId,
@RequestParam(required = false)String catalogId,
@RequestParam(required = false)String query,
@RequestParam(required = false)Boolean pushing,
@RequestParam(required = false)String mediaServerId){
if (StringUtils.isEmpty(catalogId)) {
catalogId = null;
}
if (StringUtils.isEmpty(query)) {
query = null;
}
if (StringUtils.isEmpty(mediaServerId)) {
mediaServerId = null;
}
return gbStreamService.getAll(page, count, platformId);
return gbStreamService.getAll(page, count, platformId, catalogId, query, pushing, mediaServerId);
}

45
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java

@ -65,6 +65,25 @@ public class PlatformController {
result.put("password", sipConfig.getPassword());
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
* 获取级联服务器信息
* @return
*/
@ApiOperation("获取国标服务的配置")
@GetMapping("/info/{id}")
public ResponseEntity<WVPResult<ParentPlatform>> getPlatform(@PathVariable String id) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(id);
WVPResult<ParentPlatform> wvpResult = new WVPResult<>();
if (parentPlatform != null) {
wvpResult.setCode(0);
wvpResult.setMsg("success");
wvpResult.setData(parentPlatform);
}else {
wvpResult.setCode(-1);
wvpResult.setMsg("未查询到此平台");
}
return new ResponseEntity<>(wvpResult, HttpStatus.OK);
}
/**
* 分页查询级联平台
@ -282,29 +301,33 @@ public class PlatformController {
@ApiImplicitParam(name = "page", value = "当前页", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "count", value = "每页条数", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "platformId", value = "上级平台ID", dataTypeClass = String.class),
@ApiImplicitParam(name = "catalogId", value = "目录ID", dataTypeClass = String.class),
@ApiImplicitParam(name = "query", value = "查询内容", dataTypeClass = String.class),
@ApiImplicitParam(name = "online", value = "是否在线", dataTypeClass = Boolean.class),
@ApiImplicitParam(name = "choosed", value = "是否已选中", dataTypeClass = Boolean.class),
@ApiImplicitParam(name = "channelType", value = "通道类型", dataTypeClass = Boolean.class),
})
@GetMapping("/channel_list")
@ResponseBody
public PageInfo<ChannelReduce> channelList(int page, int count,
@RequestParam(required = false) String platformId,
@RequestParam(required = false) String catalogId,
@RequestParam(required = false) String query,
@RequestParam(required = false) Boolean online,
@RequestParam(required = false) Boolean choosed,
@RequestParam(required = false) Boolean channelType){
// if (logger.isDebugEnabled()) {
// logger.debug("查询所有所有通道API调用");
// }
PageInfo<ChannelReduce> channelReduces = null;
if (platformId != null ) {
channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, platformId, choosed);
}else {
channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, null, false);
if(StringUtils.isEmpty(platformId)) {
platformId = null;
}
if(StringUtils.isEmpty(query)) {
query = null;
}
if(StringUtils.isEmpty(platformId) || StringUtils.isEmpty(catalogId)) {
catalogId = null;
}
PageInfo<ChannelReduce> channelReduces = storager.queryAllChannelList(page, count, query, online, channelType, platformId, catalogId);
return channelReduces;
}
@ -371,11 +394,11 @@ public class PlatformController {
}
List<PlatformCatalog> platformCatalogList = storager.getChildrenCatalogByPlatform(platformId, parentId);
// 查询下属的国标通道
List<PlatformCatalog> catalogsForChannel = storager.queryChannelInParentPlatformAndCatalog(platformId, parentId);
// List<PlatformCatalog> catalogsForChannel = storager.queryChannelInParentPlatformAndCatalog(platformId, parentId);
// 查询下属的直播流通道
List<PlatformCatalog> catalogsForStream = storager.queryStreamInParentPlatformAndCatalog(platformId, parentId);
platformCatalogList.addAll(catalogsForChannel);
platformCatalogList.addAll(catalogsForStream);
// List<PlatformCatalog> catalogsForStream = storager.queryStreamInParentPlatformAndCatalog(platformId, parentId);
// platformCatalogList.addAll(catalogsForChannel);
// platformCatalogList.addAll(catalogsForStream);
WVPResult<List<PlatformCatalog>> result = new WVPResult<>();
result.setCode(0);
result.setMsg("success");

1
web_src/index.html

@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>国标28181</title>
<link rel="shortcut icon" href="static/favicon.ico" type="image/x-icon">
<link rel="stylesheet" type="text/css" href="./static/css/iconfont.css">
<link rel="stylesheet" type="text/css" href="./static/css/login.css">
</head>

6
web_src/src/components/PushVideoList.vue

@ -35,11 +35,7 @@
<devicePlayer ref="devicePlayer"></devicePlayer>
<addStreamTOGB ref="addStreamTOGB"></addStreamTOGB>
<el-table ref="pushListTable" :data="pushList" border style="width: 100%" :height="winHeight" @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream">
<el-table-column
align="center"
type="selection"
:reserve-selection="true"
width="55">
<el-table-column align="center" type="selection" :reserve-selection="true" width="55">
</el-table-column>
<el-table-column prop="name" label="名称" align="center">
</el-table-column>

2
web_src/src/components/UiHeader.vue

@ -3,7 +3,7 @@
<el-menu router :default-active="activeIndex" menu-trigger="click" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal">
<el-menu-item index="/">控制台</el-menu-item>
<el-menu-item index="/live">实时监控</el-menu-item>
<el-menu-item index="/deviceList">设备列表</el-menu-item>
<el-menu-item index="/deviceList">国标设备</el-menu-item>
<el-menu-item index="/pushVideoList">推流列表</el-menu-item>
<el-menu-item index="/streamProxyList">拉流代理</el-menu-item>
<el-menu-item index="/cloudRecord">云端录像</el-menu-item>

3
web_src/src/components/dialog/catalogEdit.vue

@ -77,8 +77,7 @@ export default {
})
.then((res)=> {
if (res.data.code === 0) {
console.log("添加/修改成功")
if (this.submitCallback)this.submitCallback()
if (this.submitCallback)this.submitCallback(this.form)
}else {
this.$message({
showClose: true,

14
web_src/src/components/dialog/chooseChannel.vue

@ -20,14 +20,14 @@
<el-tab-pane label="国标通道" name="gbChannel">
<el-container>
<el-main style="background-color: #FFF;">
<chooseChannelForGb ref="chooseChannelForGb" :catalogId="catalogId" :platformId=platformId :updateChoosedCallback="updateChooseChannelCallback"></chooseChannelForGb>
<chooseChannelForGb ref="chooseChannelForGb" :catalogId="catalogId" :catalogName="catalogName" :platformId=platformId ></chooseChannelForGb>
</el-main>
</el-container>
</el-tab-pane>
<el-tab-pane label="直播流通道" name="streamchannel">
<el-container>
<el-main style="background-color: #FFF;">
<chooseChannelFoStream ref="chooseChannelFoStream" :catalogId="catalogId" :platformId=platformId :updateChoosedCallback="updateChooseChannelCallback"></chooseChannelFoStream>
<chooseChannelFoStream ref="chooseChannelFoStream" :catalogId="catalogId" :catalogName="catalogName" :currentCatalogId="currentCatalogId" :platformId=platformId ></chooseChannelFoStream>
</el-main>
</el-container>
</el-tab-pane>
@ -61,6 +61,8 @@ export default {
catalogTabActiveName: "catalog",
platformId: "",
catalogId: "",
catalogName: "",
currentCatalogId: "",
platformName: "",
defaultCatalogId: "",
showDialog: false,
@ -108,14 +110,10 @@ export default {
console.log(error);
});
},
catalogIdChange: function (id) {
console.log("中间模块收到: " + id)
catalogIdChange: function (id, name) {
this.catalogId = id;
this.catalogName = name;
},
updateChooseChannelCallback (id){
console.log("中间模块收到选择通道变化: " + id)
this.$refs.chooseChannelForCatalog.refreshCatalogById(id)
}
}
};
</script>

33
web_src/src/components/dialog/chooseChannelForCatalog.vue

@ -7,14 +7,16 @@
empty-text="未知节点"
node-key="id"
default-expand-all
:highlight-current="true"
:highlight-current="false"
:expand-on-click-node="false"
:props="props"
:load="loadNode"
@node-contextmenu="contextmenuEventHandler"
@node-click="nodeClickHandler"
lazy>
<span class="custom-tree-node" slot-scope="{ node, data }" style="width: 100%">
<el-radio v-if="node.data.type === 0" style="margin-right: 0" v-model="chooseId" :label="node.data.id">{{''}}</el-radio>
<el-radio v-if="node.data.type === 0 || node.data.type === -1" style="margin-right: 0" v-model="chooseId" :label="node.data.id">{{''}}</el-radio>
<span v-if="node.data.type === -1 && node.level === 1" style="font-size: 12px" class="iconfont icon-ziyuan"></span>
<span v-if="node.data.type === 0 && node.level === 1" class="el-icon-s-home"></span>
<span v-if="node.data.type === 0 && node.level > 1" class="el-icon-folder-opened"></span>
<span v-if="node.data.type === 1" class="iconfont icon-shexiangtou"></span>
@ -42,7 +44,7 @@ export default {
this.defaultCatalogIdSign = this.defaultCatalogId;
this.initData();
setTimeout(()=>{
if (this.catalogIdChange)this.catalogIdChange(this.defaultCatalogId);
if (this.catalogIdChange)this.catalogIdChange(this.defaultCatalogId, this.platformName);
}, 100)
},
@ -59,6 +61,7 @@ export default {
defaultCatalogIdSign: null,
chooseNode: null,
chooseId: "",
chooseName: "",
catalogTree: null,
contextmenuShow: false
@ -69,10 +72,6 @@ export default {
console.log(newData)
this.initData()
},
chooseId(newData, oldData){
console.log("发送: " + newData)
if (this.catalogIdChange)this.catalogIdChange(newData);
},
},
methods: {
initData: function () {
@ -123,9 +122,12 @@ export default {
editCatalog: function (data, node){
let that = this;
//
that.$refs.catalogEdit.openDialog(true, data.id, data.name, data.parentId, (data)=>{
that.$refs.catalogEdit.openDialog(true, data.id, data.name, data.parentId, (newData)=>{
node.parent.loaded = false
node.parent.expand();
if (data.id === this.chooseId && newData.name !== data.name) {
if (this.catalogIdChange)this.catalogIdChange(this.chooseId, newData.name);
}
});
},
@ -172,11 +174,17 @@ export default {
},
loadNode: function(node, resolve){
if (node.level === 0) {
resolve([{
resolve([
{
name: "未分配",
id: null,
type: -1
},{
name: this.platformName,
id: this.platformId,
type: 0
}]);
}
]);
}
if (node.level >= 1){
this.getCatalog(node.data.id, resolve)
@ -291,6 +299,11 @@ export default {
return false;
},
nodeClickHandler: function (data, node, tree){
this.chooseId = data.id;
this.chooseName = data.name;
if (this.catalogIdChange)this.catalogIdChange(this.chooseId, this.chooseName);
}
}
};
</script>

279
web_src/src/components/dialog/chooseChannelForGb.vue

@ -1,6 +1,10 @@
<template>
<div id="chooseChannelForGb" >
<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
<div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
<span v-if="catalogId == null">{{catalogName}}的直播流</span>
<span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播流</span>
</div>
<div style="background-color: #FFFFFF; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
搜索: <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
通道类型: <el-select size="mini" @change="search" style="margin-right: 1rem; width:6rem" v-model="channelType" placeholder="请选择" default-first-option>
@ -9,21 +13,18 @@
<el-option label="子目录" value="true"></el-option>
</el-select>
选择状态: <el-select size="mini" style="margin-right: 1rem; width:6rem" v-model="choosed" @change="search" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option>
<el-option label="已选择" value="true"></el-option>
<el-option label="未选择" value="false"></el-option>
</el-select>
在线状态: <el-select size="mini" style="margin-right: 1rem; width:6rem" @change="search" v-model="online" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option>
<el-option label="在线" value="true"></el-option>
<el-option label="离线" value="false"></el-option>
</el-select>
<!-- <el-checkbox @change="shareAllCheckedChange">全部共享</el-checkbox>-->
<el-button v-if="catalogId !== null" icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button>
<el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" @click="batchAdd">批量添加</el-button>
</div>
<el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" :height="winHeight">
<el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" :height="winHeight" :row-key="(row)=> row.deviceId + row.channelId" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" :reserve-selection="true" width="55">
</el-table-column>
<el-table-column prop="channelId" label="通道编号" width="180" align="center">
</el-table-column>
<el-table-column prop="name" label="通道名称" show-overflow-tooltip align="center">
@ -50,10 +51,12 @@
</el-table>
<el-pagination style="float: right;margin-top: 1rem;" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
</el-pagination>
<getCatalog ref="getCatalog" :platformId="platformId" ></getCatalog>
</div>
</template>
<script>
import getCatalog from './getCatalog'
export default {
name: 'chooseChannelForGb',
computed: {
@ -65,10 +68,13 @@ export default {
// };
// }
},
props: ['platformId','catalogId', 'updateChoosedCallback'],
props: ['platformId','catalogId', 'catalogName'],
created() {
this.initData();
},
components: {
getCatalog,
},
data() {
return {
gbChannels: [],
@ -80,7 +86,8 @@ export default {
currentPage: 1,
count: 10,
total: 0,
eventEnanle: false,
eventEnable: false,
multipleSelection: [],
winHeight: window.innerHeight - 400,
};
@ -88,8 +95,10 @@ export default {
watch:{
platformId(newData, oldData){
console.log(newData)
this.initData()
this.getChannelList()
},
catalogId(newData, oldData){
this.getChannelList()
},
},
methods: {
@ -105,28 +114,24 @@ export default {
console.log(val)
this.initData();
},
rowcheckedChange: function (val, row) {
console.log(val)
console.log(row)
},
add: function (row) {
console.log(row)
row.catalogId = this.catalogId
row.platformId = this.platformId
this.getCatalogFromUser((catalogId)=> {
this.$axios({
method:"post",
url:"/api/platform/update_channel_for_gb",
data:{
platformId: this.platformId,
channelReduces: [row],
catalogId: this.catalogId
catalogId: catalogId
}
}).then((res)=>{
console.log("保存成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
})
},
remove: function (row) {
console.log(row)
@ -140,91 +145,87 @@ export default {
}
}).then((res)=>{
console.log("移除成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(row.catalogId)
row.platformId = null;
row.catalogId = null
}).catch(function (error) {
console.log(error);
});
},
checkedChange: function (val) {
let that = this;
if (!that.eventEnanle) {
return;
}
let newData = {};
let addData = [];
let delData = [];
if (val.length > 0) {
for (let i = 0; i < val.length; i++) {
const element = val[i];
let key = element.deviceId + "_" + element.channelId;
newData[key] = element;
if (!!!that.gbChoosechannel[key]){
addData.push(element)
}else{
delete that.gbChoosechannel[key]
}
}
let oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}else{
let oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}
that.gbChoosechannel = newData;
if (Object.keys(addData).length >0) {
that.$axios({
method:"post",
url:"/api/platform/update_channel_for_gb",
data:{
platformId: that.platformId,
channelReduces: addData,
catalogId: that.catalogId
}
}).then((res)=>{
console.log("保存成功")
if(that.updateChoosedCallback)that.updateChoosedCallback(that.catalogId)
}).catch(function (error) {
console.log(error);
});
}
if (delData.length >0) {
that.$axios({
method:"delete",
url:"/api/platform/del_channel_for_gb",
data:{
platformId: that.platformId,
channelReduces: delData
}
}).then((res)=>{
console.log("移除成功")
let nodeIds = new Array();
for (let i = 0; i < delData.length; i++) {
nodeIds.push(delData[i].channelId)
}
if(that.updateChoosedCallback)that.updateChoosedCallback(null, nodeIds)
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
}
},
shareAllCheckedChange: function (val) {
},
// checkedChange: function (val) {
// let that = this;
// if (!that.eventEnable) {
// return;
// }
// let newData = {};
// let addData = [];
// let delData = [];
// if (val.length > 0) {
// for (let i = 0; i < val.length; i++) {
// const element = val[i];
// let key = element.deviceId + "_" + element.channelId;
// newData[key] = element;
// if (!!!that.gbChoosechannel[key]){
// addData.push(element)
// }else{
// delete that.gbChoosechannel[key]
// }
// }
//
// let oldKeys = Object.keys(that.gbChoosechannel);
// if (oldKeys.length > 0) {
// for (let i = 0; i < oldKeys.length; i++) {
// const key = oldKeys[i];
// delData.push(that.gbChoosechannel[key])
// }
// }
//
// }else{
// let oldKeys = Object.keys(that.gbChoosechannel);
// if (oldKeys.length > 0) {
// for (let i = 0; i < oldKeys.length; i++) {
// const key = oldKeys[i];
// delData.push(that.gbChoosechannel[key])
// }
// }
// }
//
// that.gbChoosechannel = newData;
// if (Object.keys(addData).length >0) {
// that.$axios({
// method:"post",
// url:"/api/platform/update_channel_for_gb",
// data:{
// platformId: that.platformId,
// channelReduces: addData,
// catalogId: that.catalogId
// }
// }).then((res)=>{
// console.log("")
// }).catch(function (error) {
// console.log(error);
// });
// }
// if (delData.length >0) {
// that.$axios({
// method:"delete",
// url:"/api/platform/del_channel_for_gb",
// data:{
// platformId: that.platformId,
// channelReduces: delData
// }
// }).then((res)=>{
// console.log("")
// let nodeIds = new Array();
// for (let i = 0; i < delData.length; i++) {
// nodeIds.push(delData[i].channelId)
// }
// }).catch(function (error) {
// console.log(error);
// });
// }
// },
// shareAllCheckedChange: function (val) {
//
// },
getChannelList: function () {
let that = this;
@ -236,7 +237,7 @@ export default {
count: that.count,
query: that.searchSrt,
online: that.online,
choosed: that.choosed,
catalogId: that.catalogId,
platformId: that.platformId,
channelType: that.channelType
}
@ -248,20 +249,7 @@ export default {
//
that.$nextTick(() => {
that.$refs.gbChannelsTable.doLayout();
//
var chooseGBS = [];
for (let i = 0; i < res.data.list.length; i++) {
const row = res.data.list[i];
console.log(row.platformId)
if (row.platformId == that.platformId) {
that.$refs.gbChannelsTable.toggleRowSelection(row, true);
chooseGBS.push(row)
that.gbChoosechannel[row.deviceId+ "_" + row.channelId] = row;
}
}
that.eventEnanle = true;
// that.checkedChange(chooseGBS)
that.eventEnable = true;
})
console.log(that.gbChoosechannel)
})
@ -276,10 +264,55 @@ export default {
handleGBSelectionChange: function() {
this.initData();
},
// catalogIdChange: function(id) {
// this.catalogId = id;
// console.log(" " + id)
// },
batchDel: function() {
this.$confirm(`确认这${this.multipleSelection.length}个通道吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios({
method:"delete",
url:"/api/platform/del_channel_for_gb",
data:{
platformId: this.platformId,
channelReduces: this.multipleSelection
}
}).then((res)=>{
console.log("移除成功")
this.$refs.gbChannelsTable.clearSelection()
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
}).catch(() => {
});
},
batchAdd: function() {
this.getCatalogFromUser((catalogId)=> {
this.$axios({
method: "post",
url: "/api/platform/update_channel_for_gb",
data: {
platformId: this.platformId,
channelReduces: this.multipleSelection,
catalogId: catalogId,
}
}).then((res) => {
console.log("保存成功")
this.$refs.gbChannelsTable.clearSelection()
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
});
},
handleSelectionChange: function (val) {
this.multipleSelection = val;
},
getCatalogFromUser(callback){
this.$refs.getCatalog.openDialog(callback)
},
}
};
</script>

241
web_src/src/components/dialog/chooseChannelForStream.vue

@ -1,6 +1,33 @@
<template>
<div id="chooseChannelFoStream" >
<el-table ref="gbStreamsTable" :data="gbStreams" border style="width: 100%" :height="winHeight">
<div style="font-size: 17px; color: #606060; white-space: nowrap; line-height: 30px; font-family: monospace;">
<span v-if="catalogId == null">{{catalogName}}的直播流</span>
<span v-if="catalogId != null">{{catalogName}}({{catalogId}})的直播流</span>
</div>
<div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;font-size: 14px;">
搜索: <el-input @input="getChannelList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" prefix-icon="el-icon-search" v-model="searchSrt" clearable> </el-input>
<!-- 流媒体: <el-select size="mini" @change="getChannelList" style="margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" default-first-option>-->
<!-- <el-option label="全部" value=""></el-option>-->
<!-- <el-option-->
<!-- v-for="item in mediaServerList"-->
<!-- :key="item.id"-->
<!-- :label="item.id"-->
<!-- :value="item.id">-->
<!-- </el-option>-->
<!-- </el-select>-->
推流状态: <el-select size="mini" style="margin-right: 1rem;" @change="getChannelList" v-model="pushing" placeholder="请选择" default-first-option>
<el-option label="全部" value=""></el-option>
<el-option label="推流进行中" value="true"></el-option>
<el-option label="推流未进行" value="false"></el-option>
</el-select>
<el-button v-if="catalogId !== null" icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="gbStreams.length === 0 || multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button>
<el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" :disabled="gbStreams.length === 0 || multipleSelection.length === 0" @click="batchAdd">批量添加</el-button>
</div>
<el-table ref="gbStreamsTable" :data="gbStreams" border style="width: 100%" :height="winHeight" :row-key="(row)=> row.app + row.stream" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" :reserve-selection="true" width="55">
</el-table-column>
<el-table-column prop="name" label="名称" show-overflow-tooltip align="center">
</el-table-column>
<el-table-column prop="app" label="应用名" show-overflow-tooltip align="center">
@ -20,18 +47,21 @@
<el-table-column label="操作" width="100" align="center" fixed="right" >
<template slot-scope="scope">
<el-button-group>
<el-button size="mini" icon="el-icon-plus" v-if="!scope.row.platformId" @click="add(scope.row)">添加</el-button>
<el-button size="mini" icon="el-icon-delete" v-if="scope.row.platformId" type="danger" @click="remove(scope.row)">移除</el-button>
<el-button size="mini" icon="el-icon-plus" v-if="!scope.row.platformId" @click="add(scope.row, scope)">添加</el-button>
<el-button size="mini" icon="el-icon-delete" v-if="scope.row.platformId" type="danger" @click="remove(scope.row, scope)">移除</el-button>
</el-button-group>
</template>
</el-table-column>
</el-table>
<el-pagination style="float: right;margin-top: 1rem;" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
</el-pagination>
<getCatalog ref="getCatalog" :platformId="platformId" ></getCatalog>
</div>
</template>
<script>
import MediaServer from './../service/MediaServer'
import getCatalog from './getCatalog'
export default {
name: 'chooseChannelFoStream',
computed: {
@ -43,73 +73,81 @@ export default {
// };
// }
},
props: ['platformId', 'catalogId', 'updateChoosedCallback'],
props: ['platformId', 'catalogId', 'catalogName'],
created() {
this.initData();
},
components: {
getCatalog,
},
data() {
return {
gbStreams: [],
gbChoosechannel:{},
searchSrt: "",
channelType: "",
online: "",
choosed: "",
currentPage: 1,
count: 10,
total: 0,
eventEnanle: false,
searchSrt: "",
pushing: "",
mediaServerId: "",
mediaServerList: [],
mediaServerObj : new MediaServer(),
eventEnable: false,
multipleSelection: [],
winHeight: window.innerHeight - 350,
};
},
watch:{
platformId(newData, oldData){
console.log(newData)
this.initData()
this.getChannelList()
},
catalogId(newData, oldData){
this.getChannelList()
},
},
methods: {
initData: function() {
this.mediaServerObj.getOnlineMediaServerList((data)=>{
this.mediaServerList = data.data;
})
this.getChannelList();
},
currentChange: function (val) {
this.currentPage = val;
this.initData();
this.getChannelList();
},
handleSizeChange: function (val) {
this.count = val;
console.log(val)
this.initData();
this.getChannelList();
},
rowcheckedChanage: function (val, row) {
console.log(val)
console.log(row)
},
add: function (row) {
console.log(row)
row.catalogId = this.catalogId
row.platformId = this.platformId
add: function (row, scope) {
this.getCatalogFromUser((catalogId)=>{
this.$axios({
method:"post",
url:"/api/gbStream/add",
data:{
platformId: this.platformId,
catalogId: this.catalogId,
catalogId: catalogId,
gbStreams: [row],
}
}).then((res)=>{
console.log("保存成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
// this.gbStreams.splice(scope.$index,1)
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
},
remove: function (row) {
console.log(row)
})
},
remove: function (row, scope) {
this.$axios({
method:"delete",
url:"/api/gbStream/del",
@ -119,91 +157,11 @@ export default {
}
}).then((res)=>{
console.log("移除成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(row.catalogId)
row.platformId = null;
row.catalogId = null
}).catch(function (error) {
console.log(error);
});
},
checkedChanage: function (val) {
var that = this;
if (!that.eventEnanle) {
return;
}
var newData = {};
var addData = [];
var delData = [];
if (val.length > 0) {
for (let i = 0; i < val.length; i++) {
const element = val[i];
var key = element.app + "_" + element.stream;
newData[key] = element;
if (!!!that.gbChoosechannel[key]){
addData.push(element)
}else{
delete that.gbChoosechannel[key]
}
}
var oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}else{
var oldKeys = Object.keys(that.gbChoosechannel);
if (oldKeys.length > 0) {
for (let i = 0; i < oldKeys.length; i++) {
const key = oldKeys[i];
delData.push(that.gbChoosechannel[key])
}
}
}
that.gbChoosechannel = newData;
if (Object.keys(addData).length >0) {
console.log(addData)
that.$axios({
method:"post",
url:"/api/gbStream/add",
data:{
platformId: that.platformId,
catalogId: that.catalogId,
gbStreams: addData,
}
}).then((res)=>{
console.log("保存成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
}).catch(function (error) {
console.log(error);
});
}
if (Object.keys(delData).length >0) {
console.log(delData)
that.$axios({
method:"delete",
url:"/api/gbStream/del",
data:{
platformId: that.platformId,
gbStreams: delData,
}
}).then((res)=>{
console.log("移除成功")
if(this.updateChoosedCallback)this.updateChoosedCallback(this.catalogId)
// this.gbStreams.splice(scope.$index,1)
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
}
},
shareAllCheckedChanage: function (val) {
this.chooseChanage(null, val)
},
getChannelList: function () {
let that = this;
@ -215,10 +173,10 @@ export default {
page: that.currentPage,
count: that.count,
query: that.searchSrt,
online: that.online,
choosed: that.choosed,
pushing: that.online,
platformId: that.platformId,
channelType: that.channelType
catalogId: that.catalogId,
mediaServerId: that.mediaServerId
}
})
.then(function (res) {
@ -229,29 +187,62 @@ export default {
that.$nextTick(() => {
that.$refs.gbStreamsTable.doLayout();
//
var chooseGBS = [];
for (let i = 0; i < res.data.list.length; i++) {
const row = res.data.list[i];
console.log(row.platformId)
if (row.platformId == that.platformId) {
that.$refs.gbStreamsTable.toggleRowSelection(row, true);
chooseGBS.push(row)
that.gbChoosechannel[row.app+ "_" + row.stream] = row;
}
}
that.eventEnanle = true;
// that.checkedChanage(chooseGBS)
that.eventEnable = true;
})
console.log(that.gbChoosechannel)
})
.catch(function (error) {
console.log(error);
});
},
handleGBSelectionChange: function() {
this.initData();
batchDel: function() {
this.$confirm(`确认这${this.multipleSelection.length}个通道吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$axios({
method:"delete",
url:"/api/gbStream/del",
data:{
platformId: this.platformId,
gbStreams: this.multipleSelection,
}
}).then((res)=>{
console.log("移除成功")
this.$refs.gbStreamsTable.clearSelection()
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
}).catch(() => {
});
},
batchAdd: function() {
this.getCatalogFromUser((catalogId)=>{
this.$axios({
method:"post",
url:"/api/gbStream/add",
data:{
platformId: this.platformId,
catalogId: catalogId,
gbStreams: this.multipleSelection,
}
}).then((res)=>{
console.log("保存成功")
this.$refs.gbStreamsTable.clearSelection()
this.getChannelList();
}).catch(function (error) {
console.log(error);
});
})
},
getCatalogFromUser(callback){
this.$refs.getCatalog.openDialog(callback)
},
handleSelectionChange: function (val) {
this.multipleSelection = val;
},
}
};

161
web_src/src/components/dialog/getCatalog.vue

@ -0,0 +1,161 @@
<template>
<div id="getCatalog" >
<el-dialog title="选择要添加到的节点" v-if="showDialog" width="50%" :append-to-body="true" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()" center>
<div>
<el-tree class="el-scrollbar"
ref="tree"
id="catalogTree"
empty-text="未知节点"
node-key="id"
default-expand-all
:highlight-current="false"
:expand-on-click-node="false"
:props="props"
:load="loadNode"
@node-click="nodeClickHandler"
lazy>
<span class="custom-tree-node" slot-scope="{ node, data }" style="width: 100%">
<el-radio v-if="node.data.type === 0 || node.data.type === -1" style="margin-right: 0" v-model="chooseId" :label="node.data.id">{{''}}</el-radio>
<span v-if="node.data.type === -1 && node.level === 1" style="font-size: 12px" class="iconfont icon-ziyuan"></span>
<span v-if="node.data.type === 0 && node.level === 1" class="el-icon-s-home"></span>
<span v-if="node.data.type === 0 && node.level > 1" class="el-icon-folder-opened"></span>
<span v-if="node.data.type === 1" class="iconfont icon-shexiangtou"></span>
<span v-if="node.data.type === 2" class="iconfont icon-zhibo"></span>
<span style=" padding-left: 1px">{{ node.label }}</span>
<span>
<i style="margin-left: 5rem; color: #9d9d9d; padding-right: 20px" v-if="node.data.id === defaultCatalogIdSign">默认</i>
</span>
</span>
</el-tree>
</div>
<div style="float: right; height: 13rem">
<el-button type="primary" size="mini" @click="submit()" >确认</el-button>
<el-button @click="close()" size="mini">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: 'getCatalog',
beforeCreate(){
},
created() {
this.chooseId = this.defaultCatalogId;
this.defaultCatalogIdSign = this.defaultCatalogId;
this.initData();
setTimeout(()=>{
if (this.catalogIdChange)this.catalogIdChange(this.defaultCatalogId);
}, 100)
},
props: ['platformId'],
data() {
return {
props: {
label: 'name',
children: 'children',
isLeaf: 'leaf'
},
platformName: null,
defaultCatalogId: null,
catalogIdResult: null,
showDialog: false,
defaultCatalogIdSign: null,
chooseNode: null,
chooseId: "",
catalogTree: null,
contextmenuShow: false,
};
},
methods: {
openDialog(catalogIdResult) {
this.showDialog = true
this.catalogIdResult = catalogIdResult
},
initData: function () {
this.getCatalog();
},
getCatalog: function(parentId, callback) {
let that = this;
this.$axios({
method:"get",
url:`/api/platform/catalog`,
params: {
platformId: that.platformId,
parentId: parentId
}
})
.then((res)=> {
if (res.data.code === 0) {
if (typeof(callback) === 'function') {
callback(res.data.data)
}
}
})
.catch(function (error) {
console.log(error);
});
},
loadNode: function(node, resolve){
if (node.level === 0) {
this.$axios({
method:"get",
url:`/api/platform/info/` + this.platformId,
})
.then((res)=> {
if (res.data.code === 0) {
this.platformName = res.data.data.name;
this.defaultCatalogId = res.data.data.catalogId;
resolve([
{
name: "未分配",
id: null,
type: -1
},{
name: this.platformName,
id: this.platformId,
type: 0
}
]);
}
})
.catch(function (error) {
console.log(error);
});
}
if (node.level >= 1){
this.getCatalog(node.data.id, resolve)
}
},
nodeClickHandler: function (data, node, tree){
this.chooseId = data.id;
},
close: function() {
this.showDialog = false;
},
submit: function() {
if (this.catalogIdResult)this.catalogIdResult(this.chooseId)
this.showDialog = false;
},
}
};
</script>
<style>
#catalogTree{
display: inline-block;
}
</style>

14
web_src/static/css/iconfont.css

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 1291092 */
src: url('iconfont.woff2?t=1640922722742') format('woff2'),
url('iconfont.woff?t=1640922722742') format('woff'),
url('iconfont.ttf?t=1640922722742') format('truetype');
src: url('iconfont.woff2?t=1644809302709') format('woff2'),
url('iconfont.woff?t=1644809302709') format('woff'),
url('iconfont.ttf?t=1644809302709') format('truetype');
}
.iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-ziyuan:before {
content: "\e7d5";
}
.icon-shexiangtou1:before {
content: "\e7d4";
}
.icon-wxbzhuye:before {
content: "\e7d1";
}

BIN
web_src/static/css/iconfont.woff2

Binary file not shown.

BIN
web_src/static/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Loading…
Cancel
Save