diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 962f376d9..66bad9a97 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -588,11 +588,6 @@ public class ZLMRESTfulUtils { } public ZLMResult addStreamProxy(MediaServer mediaServer, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type, Integer timeOut) { - try { - url = URLEncoder.encode(url, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new ControllerException(ErrorCode.ERROR100.getCode(),"url编码失败"); - } Map param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 28a720c64..833742590 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -282,12 +282,7 @@ public class MediaServiceImpl implements IMediaService { // 拉流代理 StreamProxy streamProxy = streamProxyService.getStreamProxyByAppAndStream(app, stream); if (streamProxy != null) { - if (streamProxy.isEnableRemoveNoneReader()) { - // 无人观看自动移除 - streamProxyService.delteByAppAndStream(app, stream); - log.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, stream, streamProxy.getSrcUrl()); - return true; - } else if (streamProxy.isEnableDisableNoneReader()) { + if (streamProxy.isEnableDisableNoneReader()) { // 无人观看停用 // 修改数据 streamProxyService.stopByAppAndStream(app, stream); diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxy.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxy.java index 4f9e5e91c..14f2a6d47 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxy.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxy.java @@ -60,9 +60,6 @@ public class StreamProxy extends CommonGBChannel { @Schema(description = "是否启用MP4") private boolean enableMp4; - @Schema(description = "是否 无人观看时删除") - private boolean enableRemoveNoneReader; - @Schema(description = "是否 无人观看时自动停用") private boolean enableDisableNoneReader; diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxyParam.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxyParam.java index d791c3195..3954fdf26 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxyParam.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/bean/StreamProxyParam.java @@ -46,9 +46,6 @@ public class StreamProxyParam { @Schema(description = "是否启用MP4") private boolean enableMp4; - @Schema(description = "是否 无人观看时删除") - private boolean enableRemoveNoneReader; - @Schema(description = "是否 无人观看时自动停用") private boolean enableDisableNoneReader; @@ -65,7 +62,6 @@ public class StreamProxyParam { streamProxy.setEnable(enable); streamProxy.setEnableAudio(enableAudio); streamProxy.setEnableMp4(enableMp4); - streamProxy.setEnableRemoveNoneReader(enableRemoveNoneReader); streamProxy.setEnableDisableNoneReader(enableDisableNoneReader); streamProxy.setFfmpegCmdKey(ffmpegCmdKey); streamProxy.setGbName(name); diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java index d1eb92e35..1bd05730c 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java @@ -10,7 +10,6 @@ import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.streamProxy.bean.StreamProxy; -import com.genersoft.iot.vmp.streamProxy.bean.StreamProxyParam; import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyPlayService; import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; @@ -21,6 +20,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; @@ -28,7 +28,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; -import jakarta.servlet.http.HttpServletRequest; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; @@ -89,54 +88,6 @@ public class StreamProxyController { return streamProxyService.getStreamProxyByAppAndStream(app, stream); } - @Operation(summary = "保存代理(已存在会覆盖)", security = @SecurityRequirement(name = JwtUtils.HEADER), parameters = { - @Parameter(name = "param", description = "代理参数", required = true), - }) - @PostMapping(value = "/save") - @ResponseBody - public DeferredResult> save(HttpServletRequest request, @RequestBody StreamProxyParam param){ - log.info("添加代理: " + JSONObject.toJSONString(param)); - if (ObjectUtils.isEmpty(param.getMediaServerId())) { - param.setMediaServerId("auto"); - } - if (ObjectUtils.isEmpty(param.getType())) { - param.setType("default"); - } - DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - ErrorCallback callback = (code, msg, streamInfo) -> { - if (code == InviteErrorCode.SUCCESS.getCode()) { - WVPResult wvpResult = WVPResult.success(); - if (streamInfo != null) { - if (userSetting.getUseSourceIpAsStreamIp()) { - streamInfo=streamInfo.clone();//深拷贝 - String host; - try { - URL url=new URL(request.getRequestURL().toString()); - host=url.getHost(); - } catch (MalformedURLException e) { - host=request.getLocalAddr(); - } - streamInfo.changeStreamIp(host); - } - if (!ObjectUtils.isEmpty(streamInfo.getMediaServer().getTranscodeSuffix()) - && !"null".equalsIgnoreCase(streamInfo.getMediaServer().getTranscodeSuffix())) { - streamInfo.setStream(streamInfo.getStream() + "_" + streamInfo.getMediaServer().getTranscodeSuffix()); - } - wvpResult.setData(new StreamContent(streamInfo)); - }else { - wvpResult.setCode(code); - wvpResult.setMsg(msg); - } - - result.setResult(wvpResult); - }else { - result.setResult(WVPResult.fail(code, msg)); - } - }; - streamProxyService.save(param, callback); - return result; - } - @Operation(summary = "新增代理", security = @SecurityRequirement(name = JwtUtils.HEADER), parameters = { @Parameter(name = "param", description = "代理参数", required = true), }) diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java index db19e5961..e9970b626 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java @@ -13,10 +13,10 @@ public interface StreamProxyMapper { @Insert("INSERT INTO wvp_stream_proxy (type, app, stream,relates_media_server_id, src_url, " + "timeout, ffmpeg_cmd_key, rtsp_type, enable_audio, enable_mp4, enable, pulling, " + - "enable_remove_none_reader, enable_disable_none_reader, server_id, create_time) VALUES" + + "enable_disable_none_reader, server_id, create_time) VALUES" + "(#{type}, #{app}, #{stream}, #{relatesMediaServerId}, #{srcUrl}, " + "#{timeout}, #{ffmpegCmdKey}, #{rtspType}, #{enableAudio}, #{enableMp4}, #{enable}, #{pulling}, " + - "#{enableRemoveNoneReader}, #{enableDisableNoneReader}, #{serverId}, #{createTime} )") + "#{enableDisableNoneReader}, #{serverId}, #{createTime} )") @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") int add(StreamProxy streamProxyDto); @@ -32,7 +32,6 @@ public interface StreamProxyMapper { "enable_audio=#{enableAudio}, " + "enable=#{enable}, " + "pulling=#{pulling}, " + - "enable_remove_none_reader=#{enableRemoveNoneReader}, " + "enable_disable_none_reader=#{enableDisableNoneReader}, " + "enable_mp4=#{enableMp4} " + "WHERE id=#{id}") diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/IStreamProxyService.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/IStreamProxyService.java index 183067c2f..ce3fef1e2 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/IStreamProxyService.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/IStreamProxyService.java @@ -4,7 +4,6 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.streamProxy.bean.StreamProxy; -import com.genersoft.iot.vmp.streamProxy.bean.StreamProxyParam; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; import com.github.pagehelper.PageInfo; @@ -12,12 +11,6 @@ import java.util.Map; public interface IStreamProxyService { - /** - * 保存视频代理 - * @param param - */ - void save(StreamProxyParam param, ErrorCallback callback); - /** * 分页查询 * @param page diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java index 54cf8a4ca..fdd5eb9ff 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java @@ -18,7 +18,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; import com.genersoft.iot.vmp.service.bean.ErrorCallback; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.streamProxy.bean.StreamProxy; -import com.genersoft.iot.vmp.streamProxy.bean.StreamProxyParam; import com.genersoft.iot.vmp.streamProxy.dao.StreamProxyMapper; import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyPlayService; import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyService; @@ -137,35 +136,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } - @Override - @Transactional - public void save(StreamProxyParam param, ErrorCallback callback) { - // 兼容旧接口 - StreamProxy streamProxyInDb = getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (streamProxyInDb != null && streamProxyInDb.getPulling() != null && streamProxyInDb.getPulling()) { - playService.stopProxy(streamProxyInDb); - } - if (param.getMediaServerId().equals("auto")) { - param.setMediaServerId(null); - } - StreamProxy streamProxy = param.buildStreamProxy(userSetting.getServerId()); - - if (streamProxyInDb == null) { - add(streamProxy); - } else { - try { - playService.stopProxy(streamProxyInDb); - } catch (ControllerException ignored) { - } - streamProxyMapper.delete(streamProxyInDb.getId()); - add(streamProxy); - } - - if (param.isEnable()) { - playService.startProxy(streamProxy, callback); - } - } - @Override @Transactional public void add(StreamProxy streamProxy) { @@ -329,11 +299,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { streamProxy.setGbStatus("OFF"); channelListForOffline.add(streamProxy.buildCommonGBChannel()); } - // 移除开启了无人观看自动移除的流 - if (streamProxy.getGbDeviceId() == null && streamProxy.isEnableRemoveNoneReader()) { - streamProxiesForRemove.add(streamProxy); - streamProxyMapForDb.remove(streamProxy.getApp() + streamProxy.getStream()); - } } } if (!channelListForOffline.isEmpty()) { @@ -360,7 +325,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (streamProxies.isEmpty()) { return; } - List streamProxiesForRemove = new ArrayList<>(); List streamProxiesForSendMessage = new ArrayList<>(); List channelListForOffline = new ArrayList<>(); @@ -368,18 +332,11 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (streamProxy.getGbId() > 0 && "ON".equalsIgnoreCase(streamProxy.getGbStatus())) { channelListForOffline.add(streamProxy.buildCommonGBChannel()); } - if (streamProxy.getGbId() == 0 && streamProxy.isEnableRemoveNoneReader()) { - streamProxiesForRemove.add(streamProxy); - } if ("ON".equalsIgnoreCase(streamProxy.getGbStatus())) { streamProxiesForSendMessage.add(streamProxy); } } - if (!streamProxiesForRemove.isEmpty()) { - // 移除开启了无人观看自动移除的流 - streamProxyMapper.deleteByList(streamProxiesForRemove); - } - if (!streamProxiesForRemove.isEmpty()) { + if (!channelListForOffline.isEmpty()) { // 修改国标关联的国标通道的状态 gbChannelService.offline(channelListForOffline); } diff --git a/src/main/java/com/genersoft/iot/vmp/web/custom/service/CameraChannelService.java b/src/main/java/com/genersoft/iot/vmp/web/custom/service/CameraChannelService.java index c293f7b87..931914d74 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/custom/service/CameraChannelService.java +++ b/src/main/java/com/genersoft/iot/vmp/web/custom/service/CameraChannelService.java @@ -351,6 +351,17 @@ public class CameraChannelService implements CommandLineRunner { */ private List addIconPathAndPositionForCameraChannelList(List channels, String geoCoordSys) { // 读取redis 图标信息 + /* + { + "brand": "三永", + "createdTime": 1715845840000, + "displayInSelect": true, + "id": 12, + "imagesPath": "images/lt132", + "machineName": "图传对讲单兵", + "machineType": "LT132" + }, + */ JSONArray jsonArray = (JSONArray) redisTemplate.opsForValue().get("machineInfo"); Map pathMap = new HashMap<>(); if (jsonArray != null && !jsonArray.isEmpty()) { diff --git a/web/src/views/common/DeviceTree.vue b/web/src/views/common/DeviceTree.vue index ac474e1bd..b7cb3d958 100755 --- a/web/src/views/common/DeviceTree.vue +++ b/web/src/views/common/DeviceTree.vue @@ -72,7 +72,7 @@ export default { }, data() { return { - showRegion: true, + showRegion: false, defaultProps: { children: 'children', label: 'name', @@ -149,7 +149,6 @@ export default { } }, refresh: function(id) { - console.log(id) if (this.showRegion) { this.$refs.regionTree.refresh(id) }else { diff --git a/web/src/views/common/GroupTree.vue b/web/src/views/common/GroupTree.vue index d7328d12a..d9b60de95 100755 --- a/web/src/views/common/GroupTree.vue +++ b/web/src/views/common/GroupTree.vue @@ -73,7 +73,7 @@
    -
  • +
    • -
    • +
    • { - this.refreshNode(node) - } - }, - { - label: '新建节点', - icon: 'el-icon-plus', - disabled: false, - onClick: () => { - this.addGroup(data.id, node) - } - }, - { - label: '编辑节点', - icon: 'el-icon-edit', - disabled: node.level === 1, - onClick: () => { - this.editGroup(data, node) - } - }, - { - label: '删除节点', - icon: 'el-icon-delete', - disabled: node.level === 1, - divided: true, - onClick: () => { - this.$confirm('确定删除?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(() => { - this.removeGroup(data.id, node) - }).catch(() => { + console.log(2) + console.log(node.data.type) + if (this.edit && node.data.type === 0) { - }) - } + const menuItem = [ + { + label: '刷新节点', + icon: 'el-icon-refresh', + disabled: false, + onClick: () => { + this.refreshNode(node) } - ] + }, + { + label: '新建节点', + icon: 'el-icon-plus', + disabled: false, + onClick: () => { + this.addGroup(data.id, node) + } + }, + { + label: '编辑节点', + icon: 'el-icon-edit', + disabled: node.level === 1, + onClick: () => { + this.editGroup(data, node) + } + }, + { + label: '删除节点', + icon: 'el-icon-delete', + disabled: node.level === 1, + divided: true, + onClick: () => { + this.$confirm('确定删除?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.removeGroup(data.id, node) + }).catch(() => { - if (this.enableAddChannel) { - menuItem.push( - { - label: '添加设备', - icon: 'el-icon-plus', - disabled: node.level <= 2, - onClick: () => { - this.addChannelFormDevice(data.id, node) - } - } - ) - menuItem.push( - { - label: '移除设备', - icon: 'el-icon-delete', - disabled: node.level <= 2, - divided: true, - onClick: () => { - this.removeChannelFormDevice(data.id, node) - } - } - ) - menuItem.push( - { - label: '添加通道', - icon: 'el-icon-plus', - disabled: node.level <= 2, - onClick: () => { - this.addChannel(data.id, node) - } - } - ) - } - allMenuItem.push(...menuItem) - } - if (this.contextmenu) { - for (let i = 0; i < this.contextmenu.length; i++) { - let item = this.contextmenu[i] - if (item.type === node.data.type) { - allMenuItem.push({ - label: item.label, - icon: item.icon, - onClick: () => { - item.onClick(event, data, node) - } }) } } - } - if (allMenuItem.length === 0) { - return - } + ] - this.$contextmenu({ - items: allMenuItem, - event, // 鼠标事件信息 - customClass: 'custom-class', // 自定义菜单 class - zIndex: 3000 // 菜单样式 z-index - }) + if (this.enableAddChannel) { + menuItem.push( + { + label: '添加设备', + icon: 'el-icon-plus', + disabled: node.level <= 2, + onClick: () => { + this.addChannelFormDevice(data.id, node) + } + } + ) + menuItem.push( + { + label: '移除设备', + icon: 'el-icon-delete', + disabled: node.level <= 2, + divided: true, + onClick: () => { + this.removeChannelFormDevice(data.id, node) + } + } + ) + menuItem.push( + { + label: '添加通道', + icon: 'el-icon-plus', + disabled: node.level <= 2, + onClick: () => { + this.addChannel(data.id, node) + } + } + ) + } + allMenuItem.push(...menuItem) } + if (this.contextmenu && node.data.type === 1) { + console.log(this.contextmenu) + for (let i = 0; i < this.contextmenu.length; i++) { + let item = this.contextmenu[i] + if (item.type === node.data.type) { + allMenuItem.push({ + label: item.label, + icon: item.icon, + onClick: () => { + item.onClick(event, data, node) + } + }) + } + } + } + if (allMenuItem.length === 0) { + return + } + + this.$contextmenu({ + items: allMenuItem, + event, // 鼠标事件信息 + customClass: 'custom-class', // 自定义菜单 class + zIndex: 3000 // 菜单样式 z-index + }) return false }, @@ -458,8 +461,6 @@ export default { }) }, groupSync: function() { - - this.groupSyncLoading = true this.$store.dispatch('group/sync').then(data => { this.$message.success({ @@ -472,24 +473,40 @@ export default { }).finally(() => { this.groupSyncLoading = false }) + }, + contextmenuEventHandlerForLi(event, data) { + console.log(data) + const allMenuItem = [] + if (this.contextmenu) { + for (let i = 0; i < this.contextmenu.length; i++) { + let item = this.contextmenu[i] + allMenuItem.push({ + label: item.label, + icon: item.icon, + onClick: () => { + item.onClick(event, { + id: data.gbId + }) + } + }) + } + } + if (allMenuItem.length === 0) { + return + } + + this.$contextmenu({ + items: allMenuItem, + event, // 鼠标事件信息 + customClass: 'custom-class', // 自定义菜单 class + zIndex: 3000 // 菜单样式 z-index + }) } } } - diff --git a/web/src/views/common/MapComponent.vue b/web/src/views/common/MapComponent.vue index 9d62362c2..776052af4 100755 --- a/web/src/views/common/MapComponent.vue +++ b/web/src/views/common/MapComponent.vue @@ -254,7 +254,7 @@ export default { if (overlay) { olMap.removeOverlay(overlay) } - var element = document.getElementById(id) + let element = document.getElementById(id) if (element) { element.remove() } @@ -278,82 +278,73 @@ export default { * @param option */ addPointLayer(data, clickEvent, option) { - if (data.length > 0) { - let vectorLayer = this.createPointLayer(data, clickEvent, option) - olMap.addLayer(vectorLayer) - return vectorLayer - } + let vectorLayer = this.createPointLayer(data, clickEvent, option) + olMap.addLayer(vectorLayer) + return vectorLayer }, createPointLayer(data, clickEvent, option){ + const features = [] + let maxZoom = (option && option.maxZoom) ? option.maxZoom : olMap.getView().getMaxZoom() + let minZoom = (option && option.minZoom) ? option.minZoom : olMap.getView().getMinZoom() + let declutter = option && option.declutter if (data.length > 0) { - const features = [] - let maxZoom = (option && option.maxZoom) ? option.maxZoom : olMap.getView().getMaxZoom() - let minZoom = (option && option.minZoom) ? option.minZoom : olMap.getView().getMinZoom() - let declutter = option && option.declutter - for (let i = 0; i < data.length; i++) { const feature = new Feature(new Point(fromLonLat(data[i].position))) feature.setId(data[i].id) feature.customData = data[i].data feature.setProperties({ - status: data[i].status, + status: data[i].status }) - // const style = new Style() - // style.setImage(new Icon({ - // anchor: data[i].image.anchor, - // crossOrigin: 'Anonymous', - // src: data[i].image.src, - // opacity: 1 - // })) - // feature.setStyle(style) features.push(feature) } - const source = new VectorSource() + } + const source = new VectorSource() + if (features.length > 0) { source.addFeatures(features) - const vectorLayer = new WebGLVectorLayer({ - source: source, - maxZoom: maxZoom, - minZoom: minZoom, - style: { - // 必须提供 style 配置,可以是对象或函数 - // 'circle-radius': 10, - // 'circle-fill-color': 'red', - // 'circle-stroke-color': 'white', - // 'circle-stroke-width': 0.5 - 'icon-src': 'static/images/gis/sprite.png', - 'icon-width': 120, - 'icon-height': 40, - 'icon-size': [40, 40], - 'icon-anchor': [0.5, 1], - 'icon-offset-origin': 'bottom-left', - 'icon-offset': [ - 'match', - ['get', 'status'], - 'ON', - [0, 0], - 'OFF', - [40, 0], - 'checked', - [80, 0], - [120, 60] - ] + } + const vectorLayer = new WebGLVectorLayer({ + source: source, + maxZoom: maxZoom, + minZoom: minZoom, + style: { + // 必须提供 style 配置,可以是对象或函数 + // 'circle-radius': 10, + // 'circle-fill-color': 'red', + // 'circle-stroke-color': 'white', + // 'circle-stroke-width': 0.5 + 'icon-src': 'static/images/gis/sprite.png', + 'icon-width': 120, + 'icon-height': 40, + 'icon-size': [40, 40], + 'icon-anchor': [0.5, 1], + 'icon-offset-origin': 'bottom-left', + 'icon-offset': [ + 'match', + ['get', 'status'], + 'ON', + [0, 0], + 'OFF', + [40, 0], + 'checked', + [80, 0], + [120, 60] + ] + } + }) + if (clickEvent && typeof clickEvent === 'function') { + vectorLayer.on('click', (event) => { + + if (event.features.length > 0) { + const items = [] + for (let i = 0; i < event.features.length; i++) { + items.push(event.features[i].customData) + } + clickEvent(items) } }) - if (clickEvent && typeof clickEvent === 'function') { - vectorLayer.on('click', (event) => { - - if (event.features.length > 0) { - const items = [] - for (let i = 0; i < event.features.length; i++) { - items.push(event.features[i].customData) - } - clickEvent(items) - } - }) - } - - return vectorLayer } + return vectorLayer + }, createPointLayer2(data, clickEvent, option){ if (data.length > 0) { @@ -401,20 +392,44 @@ export default { return vectorLayer } }, + hasFeature (layer, id) { + if (layer instanceof LayerGroup) { + // 目前LayerGroup的情况肯定含有这个 + return true + }else { + if (layer.getSource().getFeatureById(id)) { + return true + } + } + return false + }, + addFeature (layer, data) { + + const feature = new Feature(new Point(fromLonLat(data.position))) + feature.setId(data.id) + feature.customData = data.data + feature.setProperties({ + status: data.status + }) + layer.getSource().addFeature(feature) + }, updatePointLayer(layer, data, postponement) { layer.getSource().clear(true) + if (!data || data.length == 0) { + return + } const features = [] for (let i = 0; i < data.length; i++) { const feature = new Feature(new Point(fromLonLat(data[i].position))) feature.setId(data[i].id) feature.customData = data[i].data - const cloneStyle = new Style() - cloneStyle.setImage(new Icon({ - anchor: data[i].image.anchor, - crossOrigin: 'Anonymous', - src: data[i].image.src - })) - feature.setStyle(cloneStyle) + // const cloneStyle = new Style() + // cloneStyle.setImage(new Icon({ + // anchor: data[i].image.anchor, + // crossOrigin: 'Anonymous', + // src: data[i].image.src + // })) + // feature.setStyle(cloneStyle) features.push(feature) } layer.getSource().addFeatures(features) @@ -437,6 +452,7 @@ export default { let vectorLayer = this.createPointLayer(data.get(zoom), clickEvent, { minZoom : zoom }) + vectorLayer.setProperties('layerId', zoom) if (vectorLayer) { layers.push(vectorLayer) } @@ -454,6 +470,9 @@ export default { removeLayer(layer) { olMap.removeLayer(layer) }, + clearLayer(layer) { + layer.getSource().clear(true) + }, setFeatureImageById(layer, featureId, image) { let feature = layer.getSource().getFeatureById(featureId) if (!feature) { @@ -470,6 +489,11 @@ export default { olMap.render() }, setFeaturePositionById(layer, featureId, data) { + if (layer instanceof LayerGroup) { + + }else { + + } let featureOld = layer.getSource().getFeatureById(featureId) if (featureOld) { layer.getSource().removeFeature(featureOld) diff --git a/web/src/views/common/RegionTree.vue b/web/src/views/common/RegionTree.vue index 7fce95cd4..c4bb82980 100755 --- a/web/src/views/common/RegionTree.vue +++ b/web/src/views/common/RegionTree.vue @@ -86,7 +86,7 @@
      -
    • +
    • { + this.refreshNode(node) + } + }, + { + label: '新建节点', + icon: 'el-icon-plus', + disabled: false, + onClick: () => { + this.addRegion(data.id, node) + } + }, + { + label: '编辑节点', + icon: 'el-icon-edit', + disabled: node.level === 1, + onClick: () => { + this.editCatalog(data, node) + } + }, + { + label: '删除节点', + icon: 'el-icon-delete', + disabled: node.level === 1, + divided: true, + onClick: () => { + this.$confirm('确定删除?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + this.removeRegion(data.id, node) + }).catch(() => { - const menuItem = [ + }) + } + } + ] + if (this.enableAddChannel) { + menuItem.push( { - label: '刷新节点', - icon: 'el-icon-refresh', - disabled: false, - onClick: () => { - this.refreshNode(node) - } - }, - { - label: '新建节点', + label: '添加设备', icon: 'el-icon-plus', - disabled: false, - onClick: () => { - this.addRegion(data.id, node) - } - }, - { - label: '编辑节点', - icon: 'el-icon-edit', disabled: node.level === 1, onClick: () => { - this.editCatalog(data, node) + this.addChannelFormDevice(data.id, node) } - }, + } + ) + menuItem.push( { - label: '删除节点', + label: '移除设备', icon: 'el-icon-delete', disabled: node.level === 1, divided: true, onClick: () => { - this.$confirm('确定删除?', '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning' - }).then(() => { - this.removeRegion(data.id, node) - }).catch(() => { - - }) + this.removeChannelFormDevice(data.id, node) } } - ] - if (this.enableAddChannel) { - menuItem.push( - { - label: '添加设备', - icon: 'el-icon-plus', - disabled: node.level === 1, - onClick: () => { - this.addChannelFormDevice(data.id, node) - } + ) + menuItem.push( + { + label: '添加通道', + icon: 'el-icon-plus', + disabled: node.level === 1, + onClick: () => { + this.addChannel(data.id, node) } - ) - menuItem.push( - { - label: '移除设备', - icon: 'el-icon-delete', - disabled: node.level === 1, - divided: true, - onClick: () => { - this.removeChannelFormDevice(data.id, node) - } - } - ) - menuItem.push( - { - label: '添加通道', - icon: 'el-icon-plus', - disabled: node.level === 1, - onClick: () => { - this.addChannel(data.id, node) - } - } - ) - } - allMenuItem.push(...menuItem) + } + ) } + allMenuItem.push(...menuItem) } - if (this.contextmenu) { + if (this.contextmenu && node.data.type === 1) { for (let i = 0; i < this.contextmenu.length; i++) { let item = this.contextmenu[i] if (item.type === node.data.type) { @@ -457,34 +454,45 @@ export default { leaf: true, id: data.gbId }) + }, + contextmenuEventHandlerForLi(event, data) { + console.log(data) + const allMenuItem = [] + if (this.contextmenu) { + for (let i = 0; i < this.contextmenu.length; i++) { + let item = this.contextmenu[i] + allMenuItem.push({ + label: item.label, + icon: item.icon, + onClick: () => { + item.onClick(event, { + id: data.gbId + }) + } + }) + } + } + if (allMenuItem.length === 0) { + return + } + + this.$contextmenu({ + items: allMenuItem, + event, // 鼠标事件信息 + customClass: 'custom-class', // 自定义菜单 class + zIndex: 3000 // 菜单样式 z-index + }) } } } - diff --git a/web/src/views/common/jessibuca.vue b/web/src/views/common/jessibuca.vue index 60580c6c9..1e1581f6c 100755 --- a/web/src/views/common/jessibuca.vue +++ b/web/src/views/common/jessibuca.vue @@ -9,7 +9,7 @@
      - +
      @@ -224,6 +224,15 @@ export default { this.err = '' this.performance = '' }, + stop: function() { + if (jessibucaPlayer[this._uid]) { + jessibucaPlayer[this._uid].pause() + jessibucaPlayer[this._uid].clearView() + } + this.playing = false + this.err = '' + this.performance = '' + }, screenshot: function() { if (jessibucaPlayer[this._uid]) { jessibucaPlayer[this._uid].screenshot() diff --git a/web/src/views/map/index.vue b/web/src/views/map/index.vue index 98c12c363..4f1dbc1cd 100755 --- a/web/src/views/map/index.vue +++ b/web/src/views/map/index.vue @@ -46,7 +46,7 @@
-
+
@@ -137,6 +137,7 @@ let cameraListForSource = [] let cameraList = [] let cameraListForLevelMap = new Map() let cameraLayerExtent = [] +let channelLayer = null export default { name: 'Map', components: { @@ -153,7 +154,6 @@ export default { feature: null, device: null, infoBoxId: null, - channelLayer: null, labelStyle: { width: '56px' }, @@ -168,8 +168,7 @@ export default { saveDrawThinLoading: false, layerStyle: 0, drawThinLayer: null, - layerGroupSource: null, - infoBoxTempLayer: null + layerGroupSource: null } }, created() { @@ -179,87 +178,6 @@ export default { }, methods: { - treeChannelClickEvent: function (id) { - this.closeInfoBox() - this.$store.dispatch('commonChanel/queryOne', id) - .then(data => { - if (!data.gbLongitude || data.gbLongitude < 0) { - return - } - let zoomExtent = this.$refs.mapComponent.getZoomExtent() - this.$refs.mapComponent.panTo([data.gbLongitude, data.gbLatitude], zoomExtent[1], () => { - this.showChannelInfo(data) - }) - }) - }, - zoomIn: function() { - this.$refs.mapComponent.zoomIn() - }, - zoomOut: function() { - this.$refs.mapComponent.zoomOut() - }, - getContextmenu: function (event) { - return [ - { - label: '播放通道', - icon: 'el-icon-video-play', - type: 1, - onClick: (event, data, node) => { - this.$store.dispatch('commonChanel/queryOne', data.id) - .then(data => { - this.play(data) - }) - } - }, - { - label: '编辑位置', - icon: 'el-icon-edit', - type: 1, - onClick: (event, data, node) => { - this.$store.dispatch('commonChanel/queryOne', data.id) - .then(data => { - this.edit(data) - }) - } - } - // , - // { - // label: '轨迹查询', - // icon: 'el-icon-map-location', - // type: 1, - // onClick: (event, data, node) => { - // - // } - // } - ] - }, - showChannelInfo: function(data) { - this.channel = data - if (this.infoBoxTempLayer) { - this.$refs.mapComponent.removeLayer(this.infoBoxTempLayer) - this.infoBoxTempLayer = null - } - if (this.layerStyle === 0 || this.layerStyle === 2) { - // 此时增加临时图标 - let position = [data.gbLongitude, data.gbLatitude] - let cameraData = { - id: data.gbId, - position: position, - data: data, - status: data.gbStatus, - image: { - anchor: [0.5, 1], - src: this.getImageByChannel(data) - } - } - - this.infoBoxTempLayer = this.$refs.mapComponent.addPointLayer([cameraData]) - } - let position = [data.gbLongitude, data.gbLatitude] - this.infoBoxId = this.$refs.mapComponent.openInfoBox(position, this.$refs.infobox, [0, -50]) - }, - zoomChange: function(zoom) {}, - initChannelLayer: function () { this.mapTileList = this.$refs.mapComponent.mapTileList @@ -315,6 +233,87 @@ export default { this.updateChannelLayer() }) }, + refreshLayer(){ + this.closeInfoBox() + this.$refs.mapComponent.clearLayer(channelLayer) + this.initChannelLayer() + }, + treeChannelClickEvent: function (id) { + this.closeInfoBox() + this.$store.dispatch('commonChanel/queryOne', id) + .then(data => { + if (!data.gbLongitude || data.gbLongitude < 0 || !data.gbLatitude || data.gbLatitude < 0) { + this.$message.warning({ + showClose: true, + message: '无位置信息' + }) + return + } + let zoomExtent = this.$refs.mapComponent.getZoomExtent() + this.$refs.mapComponent.panTo([data.gbLongitude, data.gbLatitude], zoomExtent[1], () => { + this.showChannelInfo(data) + }) + }) + }, + zoomIn: function() { + this.$refs.mapComponent.zoomIn() + }, + zoomOut: function() { + this.$refs.mapComponent.zoomOut() + }, + getContextmenu: function (event) { + return [ + { + label: '播放通道', + icon: 'el-icon-video-play', + type: 1, + onClick: (event, data, node) => { + console.log(data) + this.$store.dispatch('commonChanel/queryOne', data.id) + .then(data => { + this.play(data) + }) + } + }, + { + label: '编辑位置', + icon: 'el-icon-edit', + type: 1, + onClick: (event, data, node) => { + this.$store.dispatch('commonChanel/queryOne', data.id) + .then(data => { + this.edit(data) + }) + } + } + // , + // { + // label: '轨迹查询', + // icon: 'el-icon-map-location', + // type: 1, + // onClick: (event, data, node) => { + // + // } + // } + ] + }, + showChannelInfo: function(data) { + this.channel = data + // 此时增加临时图标 + let position = [data.gbLongitude, data.gbLatitude] + let cameraData = { + id: data.gbId, + position: position, + data: data, + status: data.gbStatus + } + if (!this.$refs.mapComponent.hasFeature(channelLayer, data.gbId)) { + this.$refs.mapComponent.addFeature(channelLayer, cameraData, ) + } + this.infoBoxId = this.$refs.mapComponent.openInfoBox(position, this.$refs.infobox, [0, -50]) + }, + zoomChange: function(zoom) {}, + changeMapTile: function (index) { if (this.showDrawThin) { this.$message.warning({ @@ -330,14 +329,11 @@ export default { return } this.layerStyle = index - this.$refs.mapComponent.removeLayer(this.channelLayer) + this.$refs.mapComponent.removeLayer(channelLayer) this.channelLayer = null this.updateChannelLayer() }, updateChannelLayer: function() { - if (this.layerStyle === 0) { - return - } let clientEvent = data => { this.closeInfoBox() this.$nextTick(() => { @@ -350,24 +346,30 @@ export default { } switch (this.layerStyle) { + case 0: + channelLayer = this.$refs.mapComponent.addPointLayer([], clientEvent, null) + console.log(22222) + console.log(channelLayer) + break case 1: + // 直接展示 - if (this.channelLayer) { - this.channelLayer = this.$refs.mapComponent.updatePointLayer(this.channelLayer, cameraList, true) + if (channelLayer) { + channelLayer = this.$refs.mapComponent.updatePointLayer(channelLayer, cameraList, true) }else { console.log(cameraList.length) setTimeout(()=>{ - this.channelLayer = this.$refs.mapComponent.addPointLayer(cameraList, clientEvent, null) + channelLayer = this.$refs.mapComponent.addPointLayer(cameraList, clientEvent, null) }) } break case 2: // 碰撞检测 - if (this.channelLayer) { - this.channelLayer = this.$refs.mapComponent.updatePointLayer(this.channelLayer, cameraList, true) + if (channelLayer) { + channelLayer = this.$refs.mapComponent.updatePointLayer(channelLayer, cameraList, true) }else { setTimeout(()=>{ - this.channelLayer = this.$refs.mapComponent.addPointLayer(cameraList, clientEvent, { + channelLayer = this.$refs.mapComponent.addPointLayer(cameraList, clientEvent, { declutter: true }) }) @@ -375,13 +377,8 @@ export default { break case 3: // 抽稀图层 - if (this.channelLayer) { - this.channelLayer = this.$refs.mapComponent.updatePointLayerGroup(this.channelLayer, cameraListForLevelMap, true) - }else { - setTimeout(() => { - this.channelLayer = this.$refs.mapComponent.addPointLayerGroup(cameraListForLevelMap, clientEvent) - }) - } + this.$refs.mapComponent.removeLayer(channelLayer) + channelLayer = this.$refs.mapComponent.addPointLayerGroup(cameraListForLevelMap, clientEvent) break // case 4: // // 聚合图层 @@ -402,10 +399,6 @@ export default { } this.channel = null this.dragChannel = null - if (this.infoBoxTempLayer) { - this.$refs.mapComponent.removeLayer(this.infoBoxTempLayer) - this.infoBoxTempLayer = null - } }, play: function (channel) { const loading = this.$loading({ @@ -461,17 +454,12 @@ export default { }else { this.showEditInfo(channel) } - // 标记可编辑图标为红色 - this.$refs.mapComponent.setFeaturePositionById(this.channelLayer, channel.gbId, { + this.$refs.mapComponent.setFeaturePositionById(channelLayer, channel.gbId, { id: channel.gbId, position: position, data: channel, - status: 'checked', - image: { - anchor: [0.5, 1], - src: 'static/images/gis/camera1-red.png' - } + status: 'checked' }) }, showEditInfo: function(data) { @@ -484,15 +472,11 @@ export default { channel.gbLongitude = channel.oldLongitude channel.gbLatitude = channel.oldLatitude channel['edit'] = false - this.$refs.mapComponent.setFeaturePositionById(this.channelLayer, channel.gbId, { + this.$refs.mapComponent.setFeaturePositionById(channelLayer, channel.gbId, { id: channel.gbId, position: [channel.gbLongitude, channel.gbLatitude], data: channel, - status: channel.gbStatus, - image: { - anchor: [0.5, 1], - src: this.getImageByChannel(channel) - } + status: channel.gbStatus }) }, submitEdit: function(channel) { @@ -506,15 +490,12 @@ export default { this.closeInfoBox() channel['edit'] = false this.$refs.mapComponent.dragInteraction.removeFeatureId(channel.gbId) - this.$refs.mapComponent.setFeaturePositionById(this.channelLayer, channel.gbId, { + + this.$refs.mapComponent.setFeaturePositionById(channelLayer, channel.gbId, { id: channel.gbId, position: position, data: channel, - status: channel.gbStatus, - image: { - anchor: [0.5, 1], - src: this.getImageByChannel(channel) - } + status: channel.gbStatus }) // 刷星树菜单 this.$refs.deviceTree.refresh('channel' + channel.gbId) @@ -574,7 +555,7 @@ export default { }, quicklyDrawThin: function (){ if (this.channelLayer) { - this.$refs.mapComponent.removeLayer(this.channelLayer) + this.$refs.mapComponent.removeLayer(channelLayer) } if (this.drawThinLayer !== null) { this.$refs.mapComponent.removeLayer(this.drawThinLayer) @@ -614,8 +595,8 @@ export default { this.$refs.mapComponent.startDrawBox((extent) => { // 清理默认的摄像头图层 - if (this.channelLayer) { - this.$refs.mapComponent.removeLayer(this.channelLayer) + if (channelLayer) { + this.$refs.mapComponent.clearLayer(channelLayer) } this.$message.info({ showClose: true, diff --git a/web/src/views/streamProxy/edit.vue b/web/src/views/streamProxy/edit.vue index a16672d87..f5f8421f9 100644 --- a/web/src/views/streamProxy/edit.vue +++ b/web/src/views/streamProxy/edit.vue @@ -200,16 +200,7 @@ export default { }, noneReaderHandler: function() { console.log(this.streamProxy) - if (!this.streamProxy.noneReader || this.streamProxy.noneReader === 0) { - this.streamProxy.enableDisableNoneReader = false - this.streamProxy.enableRemoveNoneReader = false - } else if (this.streamProxy.noneReader === 1) { - this.streamProxy.enableDisableNoneReader = true - this.streamProxy.enableRemoveNoneReader = false - } else if (this.streamProxy.noneReader === 2) { - this.streamProxy.enableDisableNoneReader = false - this.streamProxy.enableRemoveNoneReader = true - } + this.streamProxy.enableDisableNoneReader = this.streamProxy.noneReader && this.streamProxy.noneReader === 1 } } }