Commit 43ef195543c087d88ac3eea98067b81d7e2b10c2

Authored by 648540858
2 parents e4622d17 ba8fffd9

Merge branch '2.6.8' into wvp-28181-2.0

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
#	src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -157,6 +157,7 @@ public class VideoManagerConstants {
157 157  
158 158 public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
159 159 public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
  160 + public static final String WVP_OTHER_SEND_RTP_INFO = "VMP_OTHER_SEND_RTP_INFO_";
160 161  
161 162 /**
162 163 * Redis Const
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -385,7 +385,9 @@ public class ZLMHttpHookListener {
385 385 }
386 386 GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
387 387 if (gbStream != null) {
388   - eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist()?CatalogEvent.ON:CatalogEvent.OFF);
  388 + if (userSetting.isUsePushingAsStatus()) {
  389 + eventPublisher.catalogEventPublishForStream(null, gbStream, param.isRegist()?CatalogEvent.ON:CatalogEvent.OFF);
  390 + }
389 391 }
390 392 if (type != null) {
391 393 // 发送流变化redis消息
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
... ... @@ -304,7 +304,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
304 304 @Override
305 305 public void sendStreamChangeMsg(String type, JSONObject jsonObject) {
306 306 String key = VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + type;
307   - logger.info("[redis 流变化事件] {}: {}", key, jsonObject.toString());
  307 + logger.info("[redis 流变化事件] 发送 {}: {}", key, jsonObject.toString());
308 308 redisTemplate.convertAndSend(key, jsonObject);
309 309 }
310 310  
... ... @@ -540,14 +540,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
540 540 @Override
541 541 public void sendMobilePositionMsg(JSONObject jsonObject) {
542 542 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_MOBILE_POSITION;
543   - logger.info("[redis发送通知] 移动位置 {}: {}", key, jsonObject.toString());
  543 + logger.info("[redis发送通知] 发送 移动位置 {}: {}", key, jsonObject.toString());
544 544 redisTemplate.convertAndSend(key, jsonObject);
545 545 }
546 546  
547 547 @Override
548 548 public void sendStreamPushRequestedMsg(MessageForPushChannel msg) {
549 549 String key = VideoManagerConstants.VM_MSG_STREAM_PUSH_REQUESTED;
550   - logger.info("[redis发送通知] 推流被请求 {}: {}/{}", key, msg.getApp(), msg.getStream());
  550 + logger.info("[redis发送通知] 发送 推流被请求 {}: {}/{}", key, msg.getApp(), msg.getStream());
551 551 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
552 552 }
553 553  
... ... @@ -555,7 +555,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
555 555 public void sendAlarmMsg(AlarmChannelMessage msg) {
556 556 // 此消息用于对接第三方服务下级来的消息内容
557 557 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM;
558   - logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg));
  558 + logger.info("[redis发送通知] 发送 报警{}: {}", key, JSON.toJSON(msg));
559 559 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
560 560 }
561 561  
... ... @@ -568,7 +568,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
568 568 @Override
569 569 public void sendStreamPushRequestedMsgForStatus() {
570 570 String key = VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED;
571   - logger.info("[redis通知]获取所有推流设备的状态");
  571 + logger.info("[redis通知] 发送 获取所有推流设备的状态");
572 572 JSONObject jsonObject = new JSONObject();
573 573 jsonObject.put(key, key);
574 574 redisTemplate.convertAndSend(key, jsonObject);
... ... @@ -596,6 +596,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
596 596 @Override
597 597 public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) {
598 598 String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS;
  599 + logger.info("[redis通知] 发送 推送设备/通道状态, {}/{}-{}", deviceId, channelId, online);
599 600 StringBuilder msg = new StringBuilder();
600 601 msg.append(deviceId);
601 602 if (channelId != null) {
... ... @@ -626,14 +627,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
626 627 @Override
627 628 public void sendPlatformStartPlayMsg(MessageForPushChannel msg) {
628 629 String key = VideoManagerConstants.VM_MSG_STREAM_START_PLAY_NOTIFY;
629   - logger.info("[redis发送通知] 推流被上级平台观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
  630 + logger.info("[redis发送通知] 发送 推流被上级平台观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
630 631 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
631 632 }
632 633  
633 634 @Override
634 635 public void sendPlatformStopPlayMsg(MessageForPushChannel msg) {
635 636 String key = VideoManagerConstants.VM_MSG_STREAM_STOP_PLAY_NOTIFY;
636   - logger.info("[redis发送通知] 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
  637 + logger.info("[redis发送通知] 发送 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
637 638 redisTemplate.convertAndSend(key, JSON.toJSON(msg));
638 639 }
639 640 }
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/bean/OtherRtpSendInfo.java 0 → 100644
  1 +package com.genersoft.iot.vmp.vmanager.bean;
  2 +
  3 +public class OtherRtpSendInfo {
  4 +
  5 + /**
  6 + * 发流IP
  7 + */
  8 + private String ip;
  9 +
  10 + /**
  11 + * 发流端口
  12 + */
  13 + private int port;
  14 +
  15 + /**
  16 + * 收流IP
  17 + */
  18 + private String receiveIp;
  19 +
  20 + /**
  21 + * 收流端口
  22 + */
  23 + private int receivePort;
  24 +
  25 + /**
  26 + * 会话ID
  27 + */
  28 + private String callId;
  29 +
  30 + /**
  31 + * 流ID
  32 + */
  33 + private String stream;
  34 +
  35 + /**
  36 + * 推流应用名
  37 + */
  38 + private String pushApp;
  39 +
  40 + /**
  41 + * 推流流ID
  42 + */
  43 + private String pushStream;
  44 +
  45 + /**
  46 + * 推流SSRC
  47 + */
  48 + private String pushSSRC;
  49 +
  50 +
  51 +
  52 + public String getIp() {
  53 + return ip;
  54 + }
  55 +
  56 + public void setIp(String ip) {
  57 + this.ip = ip;
  58 + }
  59 +
  60 + public int getPort() {
  61 + return port;
  62 + }
  63 +
  64 + public void setPort(int port) {
  65 + this.port = port;
  66 + }
  67 +
  68 + public String getReceiveIp() {
  69 + return receiveIp;
  70 + }
  71 +
  72 + public void setReceiveIp(String receiveIp) {
  73 + this.receiveIp = receiveIp;
  74 + }
  75 +
  76 + public int getReceivePort() {
  77 + return receivePort;
  78 + }
  79 +
  80 + public void setReceivePort(int receivePort) {
  81 + this.receivePort = receivePort;
  82 + }
  83 +
  84 + public String getCallId() {
  85 + return callId;
  86 + }
  87 +
  88 + public void setCallId(String callId) {
  89 + this.callId = callId;
  90 + }
  91 +
  92 + public String getStream() {
  93 + return stream;
  94 + }
  95 +
  96 + public void setStream(String stream) {
  97 + this.stream = stream;
  98 + }
  99 +
  100 + public String getPushApp() {
  101 + return pushApp;
  102 + }
  103 +
  104 + public void setPushApp(String pushApp) {
  105 + this.pushApp = pushApp;
  106 + }
  107 +
  108 + public String getPushStream() {
  109 + return pushStream;
  110 + }
  111 +
  112 + public void setPushStream(String pushStream) {
  113 + this.pushStream = pushStream;
  114 + }
  115 +
  116 + public String getPushSSRC() {
  117 + return pushSSRC;
  118 + }
  119 +
  120 + public void setPushSSRC(String pushSSRC) {
  121 + this.pushSSRC = pushSSRC;
  122 + }
  123 +
  124 + @Override
  125 + public String toString() {
  126 + return "OtherRtpSendInfo{" +
  127 + "ip='" + ip + '\'' +
  128 + ", port=" + port +
  129 + ", receiveIp='" + receiveIp + '\'' +
  130 + ", receivePort=" + receivePort +
  131 + ", callId='" + callId + '\'' +
  132 + ", stream='" + stream + '\'' +
  133 + '}';
  134 + }
  135 +}
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
1 1 package com.genersoft.iot.vmp.vmanager.rtp;
2 2  
  3 +import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  5 +import com.genersoft.iot.vmp.conf.DynamicTask;
3 6 import com.genersoft.iot.vmp.conf.SipConfig;
4 7 import com.genersoft.iot.vmp.conf.UserSetting;
5 8 import com.genersoft.iot.vmp.conf.VersionInfo;
6 9 import com.genersoft.iot.vmp.conf.exception.ControllerException;
7 10 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
8 11 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
  12 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
9 13 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
  14 +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
  15 +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout;
10 16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
11   -import com.genersoft.iot.vmp.service.*;
  17 +import com.genersoft.iot.vmp.service.IDeviceChannelService;
  18 +import com.genersoft.iot.vmp.service.IDeviceService;
  19 +import com.genersoft.iot.vmp.service.IMediaServerService;
12 20 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 21 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  22 +import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
14 23 import io.swagger.v3.oas.annotations.Operation;
15 24 import io.swagger.v3.oas.annotations.Parameter;
16 25 import io.swagger.v3.oas.annotations.tags.Tag;
  26 +import okhttp3.OkHttpClient;
  27 +import okhttp3.Request;
  28 +import org.slf4j.Logger;
  29 +import org.slf4j.LoggerFactory;
17 30 import org.springframework.beans.factory.annotation.Autowired;
18 31 import org.springframework.beans.factory.annotation.Value;
  32 +import org.springframework.data.redis.core.RedisTemplate;
19 33 import org.springframework.web.bind.annotation.GetMapping;
20 34 import org.springframework.web.bind.annotation.RequestMapping;
21 35 import org.springframework.web.bind.annotation.ResponseBody;
22 36 import org.springframework.web.bind.annotation.RestController;
23 37  
  38 +import java.io.IOException;
  39 +import java.util.HashMap;
  40 +import java.util.Map;
  41 +
24 42 @SuppressWarnings("rawtypes")
25 43 @Tag(name = "第三方服务对接")
26 44  
... ... @@ -31,8 +49,10 @@ public class RtpController {
31 49 @Autowired
32 50 private ZLMServerFactory zlmServerFactory;
33 51  
  52 + private final static Logger logger = LoggerFactory.getLogger(RtpController.class);
  53 +
34 54 @Autowired
35   - private ZlmHttpHookSubscribe zlmHttpHookSubscribe;
  55 + private ZlmHttpHookSubscribe hookSubscribe;
36 56  
37 57 @Autowired
38 58 private IMediaServerService mediaServerService;
... ... @@ -53,11 +73,11 @@ public class RtpController {
53 73 private IDeviceChannelService channelService;
54 74  
55 75 @Autowired
56   - private IStreamPushService pushService;
  76 + private DynamicTask dynamicTask;
57 77  
58 78  
59 79 @Autowired
60   - private IStreamProxyService proxyService;
  80 + private RedisTemplate<Object, Object> redisTemplate;
61 81  
62 82  
63 83 @Value("${server.port}")
... ... @@ -77,12 +97,76 @@ public class RtpController {
77 97 @Parameter(name = "stream", description = "形成的流的ID", required = true)
78 98 @Parameter(name = "tcpMode", description = "收流模式, 0为UDP, 1为TCP被动", required = true)
79 99 @Parameter(name = "callBack", description = "回调地址,如果收流超时会通道回调通知,回调为get请求,参数为callId", required = true)
80   - public SendRtpItem openRtpServer(Boolean isSend, String ssrc, String callId, String stream, Integer tcpMode, String callBack) {
81   - MediaServerItem mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
  100 + public OtherRtpSendInfo openRtpServer(Boolean isSend, String ssrc, String callId, String stream, Integer tcpMode, String callBack) {
  101 +
  102 + logger.info("[第三方服务对接->开启收流和获取发流信息] isSend->{}, ssrc->{}, callId->{}, stream->{}, tcpMode->{}, callBack->{}",
  103 + isSend, ssrc, callId, stream, tcpMode==0?"UDP":"TCP被动", callBack);
  104 +
  105 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
82 106 if (mediaServerItem == null) {
83 107 throw new ControllerException(ErrorCode.ERROR100.getCode(),"没有可用的MediaServer");
84 108 }
85   - return null;
  109 + if (stream == null) {
  110 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"stream参数不可为空");
  111 + }
  112 + if (isSend != null && isSend && callId == null) {
  113 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"isSend为true时,CallID不能为空");
  114 + }
  115 + int ssrcInt = 0;
  116 + if (ssrc != null) {
  117 + try {
  118 + ssrcInt = Integer.parseInt(ssrc);
  119 + }catch (NumberFormatException e) {
  120 + throw new ControllerException(ErrorCode.ERROR100.getCode(),"ssrc格式错误");
  121 + }
  122 +
  123 + }
  124 + int localPort = zlmServerFactory.createRTPServer(mediaServerItem, stream, ssrcInt, null, false, tcpMode);
  125 + // 注册回调如果rtp收流超时则通过回调发送通知
  126 + if (callBack != null) {
  127 + HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, mediaServerItem.getId());
  128 + // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
  129 + hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
  130 + (mediaServerItemInUse, response)->{
  131 + if (stream.equals(response.getString("stream_id"))) {
  132 + logger.info("[开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调", callId);
  133 + OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
  134 + OkHttpClient client = httpClientBuilder.build();
  135 + String url = callBack + "?callId=" + callId;
  136 + Request request = new Request.Builder().get().url(url).build();
  137 + try {
  138 + client.newCall(request).execute();
  139 + } catch (IOException e) {
  140 + logger.error("[开启收流和获取发流信息] 等待收流超时 callId->{}, 发送回调失败", callId, e);
  141 + }
  142 + }
  143 + });
  144 + }
  145 + OtherRtpSendInfo otherRtpSendInfo = new OtherRtpSendInfo();
  146 + otherRtpSendInfo.setReceiveIp(mediaServerItem.getSdpIp());
  147 + otherRtpSendInfo.setReceivePort(localPort);
  148 + otherRtpSendInfo.setCallId(callId);
  149 + otherRtpSendInfo.setStream(stream);
  150 + if (isSend != null && isSend) {
  151 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  152 + // 预创建发流信息
  153 + int port = zlmServerFactory.keepPort(mediaServerItem, callId, 0, ssrc1 -> {
  154 + return redisTemplate.opsForValue().get(key) != null;
  155 + });
  156 +
  157 + // 将信息写入redis中,以备后用
  158 + redisTemplate.opsForValue().set(key, otherRtpSendInfo);
  159 + // 设置超时任务,超时未使用,则自动移除,并关闭端口保持, 默认五分钟
  160 + dynamicTask.startDelay(key, ()->{
  161 + logger.info("[第三方服务对接->开启收流和获取发流信息] 端口保持超时 callId->{}", callId);
  162 + redisTemplate.delete(key);
  163 + zlmServerFactory.releasePort(mediaServerItem, callId);
  164 + }, 300000);
  165 + otherRtpSendInfo.setIp(mediaServerItem.getSdpIp());
  166 + otherRtpSendInfo.setPort(port);
  167 + logger.info("[开启收流和获取发流信息] 结果,callId->{}, {}", callId, otherRtpSendInfo);
  168 + }
  169 + return otherRtpSendInfo;
86 170 }
87 171  
88 172 @GetMapping(value = "/receive/close")
... ... @@ -90,7 +174,9 @@ public class RtpController {
90 174 @Operation(summary = "关闭收流")
91 175 @Parameter(name = "stream", description = "流的ID", required = true)
92 176 public void closeRtpServer(String stream) {
93   -
  177 + logger.info("[第三方服务对接->关闭收流] stream->{}", stream);
  178 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  179 + zlmServerFactory.closeRtpServer(mediaServerItem,stream);
94 180 }
95 181  
96 182 @GetMapping(value = "/send/start")
... ... @@ -103,9 +189,46 @@ public class RtpController {
103 189 @Parameter(name = "stream", description = "待发送流Id", required = true)
104 190 @Parameter(name = "callId", description = "整个过程的唯一标识,不传则使用随机端口发流", required = true)
105 191 @Parameter(name = "onlyAudio", description = "是否只有音频", required = true)
  192 + @Parameter(name = "isUdp", description = "是否为UDP", required = true)
106 193 @Parameter(name = "streamType", description = "流类型,1为es流,2为ps流, 默认es流", required = false)
107   - public void sendRTP(String ssrc, String ip, Integer port, String app, String stream, String callId, Boolean onlyAudio, Integer streamType) {
  194 + public void sendRTP(String ssrc, String ip, Integer port, String app, String stream, String callId, Boolean onlyAudio, Boolean isUdp, Integer streamType) {
  195 + logger.info("[第三方服务对接->发送流] ssrc->{}, ip->{}, port->{}, app->{}, stream->{}, callId->{}, onlyAudio->{}, streamType->{}",
  196 + ssrc, ip, port, app, stream, callId, onlyAudio, streamType == 1? "ES":"PS");
  197 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  198 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  199 + OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key);
  200 + if (sendInfo != null) {
  201 + zlmServerFactory.releasePort(mediaServerItem, sendInfo.getCallId());
  202 + }else {
  203 + sendInfo = new OtherRtpSendInfo();
  204 + }
  205 + sendInfo.setPushApp(app);
  206 + sendInfo.setPushStream(stream);
  207 + sendInfo.setPushSSRC(ssrc);
  208 +
  209 + Map<String, Object> param = new HashMap<>(12);
  210 + param.put("vhost","__defaultVhost__");
  211 + param.put("app",app);
  212 + param.put("stream",stream);
  213 + param.put("ssrc", ssrc);
  214 +
  215 + param.put("dst_url",ip);
  216 + param.put("dst_port", port);
  217 + String is_Udp = isUdp ? "1" : "0";
  218 + param.put("is_udp", is_Udp);
  219 + param.put("src_port", sendInfo.getPort());
  220 + param.put("use_ps", streamType==2 ? "1" : "0");
  221 + param.put("only_audio", onlyAudio ? "1" : "0");
108 222  
  223 + JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, param);
  224 + if (jsonObject.getInteger("code") == 0) {
  225 + logger.info("[第三方服务对接->发送流] 发流成功,callId->{}", callId);
  226 + redisTemplate.opsForValue().set(key, sendInfo);
  227 + }else {
  228 + redisTemplate.delete(key);
  229 + logger.info("[第三方服务对接->发送流] 发流失败,callId->{}, {}", callId, jsonObject.getString("msg"));
  230 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "[发流失败] " + jsonObject.getString("msg"));
  231 + }
109 232 }
110 233  
111 234  
... ... @@ -115,7 +238,25 @@ public class RtpController {
115 238 @Operation(summary = "关闭发送流")
116 239 @Parameter(name = "callId", description = "整个过程的唯一标识,不传则使用随机端口发流", required = true)
117 240 public void closeSendRTP(String callId) {
118   -
  241 + logger.info("[第三方服务对接->关闭发送流] callId->{}", callId);
  242 + String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + callId;
  243 + OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key);
  244 + if (sendInfo == null){
  245 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "未开启发流");
  246 + }
  247 + Map<String, Object> param = new HashMap<>();
  248 + param.put("vhost","__defaultVhost__");
  249 + param.put("app",sendInfo.getPushApp());
  250 + param.put("stream",sendInfo.getPushStream());
  251 + param.put("ssrc",sendInfo.getPushSSRC());
  252 + MediaServerItem mediaServerItem = mediaServerService.getDefaultMediaServer();
  253 + Boolean result = zlmServerFactory.stopSendRtpStream(mediaServerItem, param);
  254 + if (!result) {
  255 + logger.info("[第三方服务对接->关闭发送流] 失败 callId->{}", callId);
  256 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "停止发流失败");
  257 + }else {
  258 + logger.info("[第三方服务对接->关闭发送流] 成功 callId->{}", callId);
  259 + }
119 260 }
120 261  
121 262 }
... ...
web_src/src/components/dialog/catalogEdit.vue
... ... @@ -12,15 +12,6 @@
12 12 >
13 13 <div id="shared" style="margin-top: 1rem;margin-right: 100px;">
14 14 <el-form ref="form" :rules="rules" :model="form" label-width="140px" >
15   -<!-- <el-form-item >-->
16   -<!-- 建议的类型:-->
17   -<!-- <br/>-->
18   -<!-- &emsp;&emsp;行政区划(可选2位/4位/6位/8位/10位数字,例如:130432,表示河北省邯郸市广平县)-->
19   -<!-- <br/>-->
20   -<!-- &emsp;&emsp;业务分组(第11、12、13位215,例如:34020000002150000001)-->
21   -<!-- <br/>-->
22   -<!-- &emsp;&emsp;虚拟组织(第11、12、13位216,例如:34020000002160000001)-->
23   -<!-- </el-form-item>-->
24 15 <el-form-item label="节点编号" prop="id" >
25 16 <el-input v-model="form.id" :disabled="isEdit" clearable></el-input>
26 17 </el-form-item>
... ... @@ -63,7 +54,11 @@ export default {
63 54 return callback(new Error('行政区划编号必须为2/4/6/8位'));
64 55 }
65 56 if (this.form.parentId !== this.platformDeviceId && this.form.parentId.length >= value.trim().length) {
66   - return callback(new Error('行政区划编号长度应该每次两位递增'));
  57 + if (this.form.parentId.length === 20) {
  58 + return callback(new Error('业务分组/虚拟组织下不可创建行政区划'));
  59 + }else {
  60 + return callback(new Error('行政区划编号长度应该每次两位递增'));
  61 + }
67 62 }
68 63 }else {
69 64 if (value.trim().length !== 20) {
... ... @@ -122,27 +117,31 @@ export default {
122 117 this.level = level;
123 118 },
124 119 onSubmit: function () {
125   - console.log("onSubmit");
126   - console.log(this.form);
127   - this.$axios({
128   - method:"post",
129   - url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
130   - data: this.form
131   - }).then((res)=> {
132   - if (res.data.code === 0) {
133   - if (this.submitCallback)this.submitCallback(this.form)
134   - }else {
135   - this.$message({
136   - showClose: true,
137   - message: res.data.msg,
138   - type: "error",
  120 + this.$refs["form"].validate((valid) => {
  121 + if (valid) {
  122 + this.$axios({
  123 + method:"post",
  124 + url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
  125 + data: this.form
  126 + }).then((res)=> {
  127 + if (res.data.code === 0) {
  128 + if (this.submitCallback)this.submitCallback(this.form)
  129 + }else {
  130 + this.$message({
  131 + showClose: true,
  132 + message: res.data.msg,
  133 + type: "error",
  134 + });
  135 + }
  136 + this.close();
  137 + })
  138 + .catch((error)=> {
  139 + console.log(error);
139 140 });
140   - }
141   - this.close();
142   - })
143   - .catch((error)=> {
144   - console.log(error);
145   - });
  141 + } else {
  142 + return false;
  143 + }
  144 + });
146 145 },
147 146 close: function () {
148 147 this.isEdit = false;
... ...