Commit 31219f0c0edfc214ca75731a892013a92a4ce0fb

Authored by liujun001
1 parent 97a90ac6

根据车辆编号查询设备通道信息

src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
@@ -5,453 +5,457 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -5,453 +5,457 @@ import io.swagger.v3.oas.annotations.media.Schema;
5 5
6 /** 6 /**
7 * 国标设备/平台 7 * 国标设备/平台
  8 + *
8 * @author lin 9 * @author lin
9 */ 10 */
10 @Schema(description = "国标设备/平台") 11 @Schema(description = "国标设备/平台")
11 public class Device { 12 public class Device {
12 13
13 - /**  
14 - * 设备国标编号  
15 - */  
16 - @Schema(description = "设备国标编号")  
17 - private String deviceId;  
18 -  
19 - /**  
20 - * 设备名  
21 - */  
22 - @Schema(description = "名称")  
23 - private String name;  
24 -  
25 - /**  
26 - * 生产厂商  
27 - */  
28 - @Schema(description = "生产厂商")  
29 - private String manufacturer;  
30 -  
31 - /**  
32 - * 型号  
33 - */  
34 - @Schema(description = "型号")  
35 - private String model;  
36 -  
37 - /**  
38 - * 固件版本  
39 - */  
40 - @Schema(description = "固件版本")  
41 - private String firmware;  
42 -  
43 - /**  
44 - * 传输协议  
45 - * UDP/TCP  
46 - */  
47 - @Schema(description = "传输协议(UDP/TCP)")  
48 - private String transport;  
49 -  
50 - /**  
51 - * 数据流传输模式  
52 - * UDP:udp传输  
53 - * TCP-ACTIVE:tcp主动模式  
54 - * TCP-PASSIVE:tcp被动模式  
55 - */  
56 - @Schema(description = "数据流传输模式")  
57 - private String streamMode;  
58 -  
59 - /**  
60 - * wan地址_ip  
61 - */  
62 - @Schema(description = "IP")  
63 - private String ip;  
64 -  
65 - /**  
66 - * wan地址_port  
67 - */  
68 - @Schema(description = "端口")  
69 - private int port;  
70 -  
71 - /**  
72 - * wan地址  
73 - */  
74 - @Schema(description = "wan地址")  
75 - private String hostAddress;  
76 -  
77 - /**  
78 - * 在线  
79 - */  
80 - @Schema(description = "是否在线,true为在线,false为离线")  
81 - private boolean onLine;  
82 -  
83 -  
84 - /**  
85 - * 注册时间  
86 - */  
87 - @Schema(description = "注册时间")  
88 - private String registerTime;  
89 -  
90 -  
91 - /**  
92 - * 心跳时间  
93 - */  
94 - @Schema(description = "心跳时间")  
95 - private String keepaliveTime;  
96 -  
97 -  
98 - /**  
99 - * 心跳间隔  
100 - */  
101 - @Schema(description = "心跳间隔")  
102 - private int keepaliveIntervalTime;  
103 -  
104 - /**  
105 - * 通道个数  
106 - */  
107 - @Schema(description = "通道个数")  
108 - private int channelCount;  
109 -  
110 - /**  
111 - * 注册有效期  
112 - */  
113 - @Schema(description = "注册有效期")  
114 - private int expires;  
115 -  
116 - /**  
117 - * 创建时间  
118 - */  
119 - @Schema(description = "创建时间")  
120 - private String createTime;  
121 -  
122 - /**  
123 - * 更新时间  
124 - */  
125 - @Schema(description = "更新时间")  
126 - private String updateTime;  
127 -  
128 - /**  
129 - * 设备使用的媒体id, 默认为null  
130 - */  
131 - @Schema(description = "设备使用的媒体id, 默认为null")  
132 - private String mediaServerId;  
133 -  
134 - /**  
135 - * 字符集, 支持 UTF-8 与 GB2312  
136 - */  
137 - @Schema(description = "符集, 支持 UTF-8 与 GB2312")  
138 - private String charset ;  
139 -  
140 - /**  
141 - * 目录订阅周期,0为不订阅  
142 - */  
143 - @Schema(description = "目录订阅周期,o为不订阅")  
144 - private int subscribeCycleForCatalog;  
145 -  
146 - /**  
147 - * 移动设备位置订阅周期,0为不订阅  
148 - */  
149 - @Schema(description = "移动设备位置订阅周期,0为不订阅")  
150 - private int subscribeCycleForMobilePosition;  
151 -  
152 - /**  
153 - * 移动设备位置信息上报时间间隔,单位:秒,默认值5  
154 - */  
155 - @Schema(description = "移动设备位置信息上报时间间隔,单位:秒,默认值5")  
156 - private int mobilePositionSubmissionInterval = 5;  
157 -  
158 - /**  
159 - * 报警订阅周期,0为不订阅  
160 - */  
161 - @Schema(description = "报警心跳时间订阅周期,0为不订阅")  
162 - private int subscribeCycleForAlarm;  
163 -  
164 - /**  
165 - * 是否开启ssrc校验,默认关闭,开启可以防止串流  
166 - */  
167 - @Schema(description = "是否开启ssrc校验,默认关闭,开启可以防止串流")  
168 - private boolean ssrcCheck = false;  
169 -  
170 - /**  
171 - * 地理坐标系, 目前支持 WGS84,GCJ02  
172 - */  
173 - @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")  
174 - private String geoCoordSys;  
175 -  
176 - @Schema(description = "密码")  
177 - private String password;  
178 -  
179 - @Schema(description = "收流IP")  
180 - private String sdpIp;  
181 -  
182 - @Schema(description = "SIP交互IP(设备访问平台的IP)")  
183 - private String localIp;  
184 -  
185 - @Schema(description = "是否作为消息通道")  
186 - private boolean asMessageChannel;  
187 -  
188 - @Schema(description = "设备注册的事务信息")  
189 - private SipTransactionInfo sipTransactionInfo;  
190 -  
191 - @Schema(description = "控制语音对讲流程,释放收到ACK后发流")  
192 - private boolean broadcastPushAfterAck;  
193 -  
194 - public String getDeviceId() {  
195 - return deviceId;  
196 - }  
197 -  
198 - public void setDeviceId(String deviceId) {  
199 - this.deviceId = deviceId;  
200 - }  
201 -  
202 - public String getName() {  
203 - return name;  
204 - }  
205 -  
206 - public void setName(String name) {  
207 - this.name = name;  
208 - }  
209 -  
210 - public String getManufacturer() {  
211 - return manufacturer;  
212 - }  
213 -  
214 - public void setManufacturer(String manufacturer) {  
215 - this.manufacturer = manufacturer;  
216 - }  
217 -  
218 - public String getModel() {  
219 - return model;  
220 - }  
221 -  
222 - public void setModel(String model) {  
223 - this.model = model;  
224 - }  
225 -  
226 - public String getFirmware() {  
227 - return firmware;  
228 - }  
229 -  
230 - public void setFirmware(String firmware) {  
231 - this.firmware = firmware;  
232 - }  
233 -  
234 - public String getTransport() {  
235 - return transport;  
236 - }  
237 -  
238 - public void setTransport(String transport) {  
239 - this.transport = transport;  
240 - }  
241 -  
242 - public String getStreamMode() {  
243 - return streamMode;  
244 - }  
245 -  
246 - public Integer getStreamModeForParam() {  
247 - if (streamMode == null) {  
248 - return 0;  
249 - }  
250 - if (streamMode.equalsIgnoreCase("UDP")) {  
251 - return 0;  
252 - }else if (streamMode.equalsIgnoreCase("TCP-PASSIVE")) {  
253 - return 1;  
254 - }else if (streamMode.equalsIgnoreCase("TCP-ACTIVE")) {  
255 - return 2;  
256 - }  
257 - return 0;  
258 - }  
259 -  
260 - public void setStreamMode(String streamMode) {  
261 - this.streamMode = streamMode;  
262 - }  
263 -  
264 - public String getIp() {  
265 - return ip;  
266 - }  
267 -  
268 - public void setIp(String ip) {  
269 - this.ip = ip;  
270 - }  
271 -  
272 - public int getPort() {  
273 - return port;  
274 - } 14 + /**
  15 + * 设备国标编号
  16 + */
  17 + @Schema(description = "设备国标编号")
  18 + private String deviceId;
  19 +
  20 + /**
  21 + * 设备名
  22 + */
  23 + @Schema(description = "名称")
  24 + private String name;
  25 +
  26 + /**
  27 + * 生产厂商
  28 + */
  29 + @Schema(description = "生产厂商")
  30 + private String manufacturer;
  31 +
  32 + /**
  33 + * 型号
  34 + */
  35 + @Schema(description = "型号")
  36 + private String model;
  37 +
  38 + /**
  39 + * 固件版本
  40 + */
  41 + @Schema(description = "固件版本")
  42 + private String firmware;
  43 +
  44 + /**
  45 + * 传输协议
  46 + * UDP/TCP
  47 + */
  48 + @Schema(description = "传输协议(UDP/TCP)")
  49 + private String transport;
  50 +
  51 + /**
  52 + * 数据流传输模式
  53 + * UDP:udp传输
  54 + * TCP-ACTIVE:tcp主动模式
  55 + * TCP-PASSIVE:tcp被动模式
  56 + */
  57 + @Schema(description = "数据流传输模式")
  58 + private String streamMode;
  59 +
  60 + /**
  61 + * wan地址_ip
  62 + */
  63 + @Schema(description = "IP")
  64 + private String ip;
  65 +
  66 + /**
  67 + * wan地址_port
  68 + */
  69 + @Schema(description = "端口")
  70 + private int port;
  71 +
  72 + /**
  73 + * wan地址
  74 + */
  75 + @Schema(description = "wan地址")
  76 + private String hostAddress;
  77 +
  78 + /**
  79 + * 在线
  80 + */
  81 + @Schema(description = "是否在线,true为在线,false为离线")
  82 + private boolean onLine;
  83 +
  84 +
  85 + /**
  86 + * 注册时间
  87 + */
  88 + @Schema(description = "注册时间")
  89 + private String registerTime;
  90 +
  91 +
  92 + /**
  93 + * 心跳时间
  94 + */
  95 + @Schema(description = "心跳时间")
  96 + private String keepaliveTime;
  97 +
  98 +
  99 + /**
  100 + * 心跳间隔
  101 + */
  102 + @Schema(description = "心跳间隔")
  103 + private int keepaliveIntervalTime;
  104 +
  105 + /**
  106 + * 通道个数
  107 + */
  108 + @Schema(description = "通道个数")
  109 + private int channelCount;
  110 +
  111 + /**
  112 + * 注册有效期
  113 + */
  114 + @Schema(description = "注册有效期")
  115 + private int expires;
  116 +
  117 + /**
  118 + * 创建时间
  119 + */
  120 + @Schema(description = "创建时间")
  121 + private String createTime;
  122 +
  123 + /**
  124 + * 更新时间
  125 + */
  126 + @Schema(description = "更新时间")
  127 + private String updateTime;
  128 +
  129 + /**
  130 + * 设备使用的媒体id, 默认为null
  131 + */
  132 + @Schema(description = "设备使用的媒体id, 默认为null")
  133 + private String mediaServerId;
  134 +
  135 + /**
  136 + * 字符集, 支持 UTF-8 与 GB2312
  137 + */
  138 + @Schema(description = "符集, 支持 UTF-8 与 GB2312")
  139 + private String charset;
  140 +
  141 + /**
  142 + * 目录订阅周期,0为不订阅
  143 + */
  144 + @Schema(description = "目录订阅周期,o为不订阅")
  145 + private int subscribeCycleForCatalog;
  146 +
  147 + /**
  148 + * 移动设备位置订阅周期,0为不订阅
  149 + */
  150 + @Schema(description = "移动设备位置订阅周期,0为不订阅")
  151 + private int subscribeCycleForMobilePosition;
  152 +
  153 + /**
  154 + * 移动设备位置信息上报时间间隔,单位:秒,默认值5
  155 + */
  156 + @Schema(description = "移动设备位置信息上报时间间隔,单位:秒,默认值5")
  157 + private int mobilePositionSubmissionInterval = 5;
  158 +
  159 + /**
  160 + * 报警订阅周期,0为不订阅
  161 + */
  162 + @Schema(description = "报警心跳时间订阅周期,0为不订阅")
  163 + private int subscribeCycleForAlarm;
  164 +
  165 + /**
  166 + * 是否开启ssrc校验,默认关闭,开启可以防止串流
  167 + */
  168 + @Schema(description = "是否开启ssrc校验,默认关闭,开启可以防止串流")
  169 + private boolean ssrcCheck = false;
  170 +
  171 + /**
  172 + * 地理坐标系, 目前支持 WGS84,GCJ02
  173 + */
  174 + @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")
  175 + private String geoCoordSys;
  176 +
  177 + @Schema(description = "密码")
  178 + private String password;
  179 +
  180 + @Schema(description = "收流IP")
  181 + private String sdpIp;
  182 +
  183 + @Schema(description = "SIP交互IP(设备访问平台的IP)")
  184 + private String localIp;
  185 +
  186 + @Schema(description = "是否作为消息通道")
  187 + private boolean asMessageChannel;
  188 +
  189 + @Schema(description = "设备注册的事务信息")
  190 + private SipTransactionInfo sipTransactionInfo;
  191 +
  192 + @Schema(description = "控制语音对讲流程,释放收到ACK后发流")
  193 + private boolean broadcastPushAfterAck;
  194 + @Schema(description = "车辆编号")
  195 + private String carNo;
  196 +
  197 + public String getDeviceId() {
  198 + return deviceId;
  199 + }
275 200
276 - public void setPort(int port) {  
277 - this.port = port;  
278 - }  
279 -  
280 - public String getHostAddress() {  
281 - return hostAddress;  
282 - }  
283 -  
284 - public void setHostAddress(String hostAddress) {  
285 - this.hostAddress = hostAddress;  
286 - }  
287 -  
288 - public boolean isOnLine() {  
289 - return onLine;  
290 - }  
291 -  
292 - public void setOnLine(boolean onLine) {  
293 - this.onLine = onLine;  
294 - }  
295 -  
296 - public int getChannelCount() {  
297 - return channelCount;  
298 - }  
299 -  
300 - public void setChannelCount(int channelCount) {  
301 - this.channelCount = channelCount;  
302 - }  
303 -  
304 - public String getRegisterTime() {  
305 - return registerTime;  
306 - }  
307 -  
308 - public void setRegisterTime(String registerTime) {  
309 - this.registerTime = registerTime;  
310 - }  
311 -  
312 - public String getKeepaliveTime() {  
313 - return keepaliveTime;  
314 - }  
315 -  
316 - public void setKeepaliveTime(String keepaliveTime) {  
317 - this.keepaliveTime = keepaliveTime;  
318 - }  
319 -  
320 - public int getExpires() {  
321 - return expires;  
322 - }  
323 -  
324 - public void setExpires(int expires) {  
325 - this.expires = expires;  
326 - }  
327 -  
328 - public String getCreateTime() {  
329 - return createTime;  
330 - }  
331 -  
332 - public void setCreateTime(String createTime) {  
333 - this.createTime = createTime;  
334 - }  
335 -  
336 - public String getUpdateTime() {  
337 - return updateTime;  
338 - }  
339 -  
340 - public void setUpdateTime(String updateTime) {  
341 - this.updateTime = updateTime;  
342 - }  
343 -  
344 - public String getMediaServerId() {  
345 - return mediaServerId;  
346 - }  
347 -  
348 - public void setMediaServerId(String mediaServerId) {  
349 - this.mediaServerId = mediaServerId;  
350 - }  
351 -  
352 - public String getCharset() {  
353 - return charset;  
354 - }  
355 -  
356 - public void setCharset(String charset) {  
357 - this.charset = charset;  
358 - } 201 + public void setDeviceId(String deviceId) {
  202 + this.deviceId = deviceId;
  203 + }
359 204
360 - public int getSubscribeCycleForCatalog() {  
361 - return subscribeCycleForCatalog;  
362 - } 205 + public String getName() {
  206 + return name;
  207 + }
363 208
364 - public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {  
365 - this.subscribeCycleForCatalog = subscribeCycleForCatalog;  
366 - } 209 + public void setName(String name) {
  210 + this.name = name;
  211 + }
367 212
368 - public int getSubscribeCycleForMobilePosition() {  
369 - return subscribeCycleForMobilePosition;  
370 - } 213 + public String getManufacturer() {
  214 + return manufacturer;
  215 + }
371 216
372 - public void setSubscribeCycleForMobilePosition(int subscribeCycleForMobilePosition) {  
373 - this.subscribeCycleForMobilePosition = subscribeCycleForMobilePosition;  
374 - } 217 + public void setManufacturer(String manufacturer) {
  218 + this.manufacturer = manufacturer;
  219 + }
375 220
376 - public int getMobilePositionSubmissionInterval() {  
377 - return mobilePositionSubmissionInterval;  
378 - } 221 + public String getModel() {
  222 + return model;
  223 + }
379 224
380 - public void setMobilePositionSubmissionInterval(int mobilePositionSubmissionInterval) {  
381 - this.mobilePositionSubmissionInterval = mobilePositionSubmissionInterval;  
382 - } 225 + public void setModel(String model) {
  226 + this.model = model;
  227 + }
383 228
384 - public int getSubscribeCycleForAlarm() {  
385 - return subscribeCycleForAlarm;  
386 - } 229 + public String getFirmware() {
  230 + return firmware;
  231 + }
387 232
388 - public void setSubscribeCycleForAlarm(int subscribeCycleForAlarm) {  
389 - this.subscribeCycleForAlarm = subscribeCycleForAlarm;  
390 - } 233 + public void setFirmware(String firmware) {
  234 + this.firmware = firmware;
  235 + }
391 236
392 - public boolean isSsrcCheck() {  
393 - return ssrcCheck;  
394 - } 237 + public String getTransport() {
  238 + return transport;
  239 + }
395 240
396 - public void setSsrcCheck(boolean ssrcCheck) {  
397 - this.ssrcCheck = ssrcCheck;  
398 - } 241 + public void setTransport(String transport) {
  242 + this.transport = transport;
  243 + }
399 244
400 - public String getGeoCoordSys() {  
401 - return geoCoordSys;  
402 - } 245 + public String getStreamMode() {
  246 + return streamMode;
  247 + }
403 248
404 - public void setGeoCoordSys(String geoCoordSys) {  
405 - this.geoCoordSys = geoCoordSys;  
406 - } 249 + public Integer getStreamModeForParam() {
  250 + if (streamMode == null) {
  251 + return 0;
  252 + }
  253 + if (streamMode.equalsIgnoreCase("UDP")) {
  254 + return 0;
  255 + } else if (streamMode.equalsIgnoreCase("TCP-PASSIVE")) {
  256 + return 1;
  257 + } else if (streamMode.equalsIgnoreCase("TCP-ACTIVE")) {
  258 + return 2;
  259 + }
  260 + return 0;
  261 + }
407 262
408 - public String getPassword() {  
409 - return password;  
410 - } 263 + public void setStreamMode(String streamMode) {
  264 + this.streamMode = streamMode;
  265 + }
411 266
412 - public void setPassword(String password) {  
413 - this.password = password;  
414 - } 267 + public String getIp() {
  268 + return ip;
  269 + }
415 270
416 - public String getSdpIp() {  
417 - return sdpIp;  
418 - } 271 + public void setIp(String ip) {
  272 + this.ip = ip;
  273 + }
419 274
420 - public void setSdpIp(String sdpIp) {  
421 - this.sdpIp = sdpIp;  
422 - } 275 + public int getPort() {
  276 + return port;
  277 + }
423 278
424 - public String getLocalIp() {  
425 - return localIp;  
426 - } 279 + public void setPort(int port) {
  280 + this.port = port;
  281 + }
427 282
428 - public void setLocalIp(String localIp) {  
429 - this.localIp = localIp;  
430 - } 283 + public String getHostAddress() {
  284 + return hostAddress;
  285 + }
431 286
432 - public int getKeepaliveIntervalTime() {  
433 - return keepaliveIntervalTime;  
434 - } 287 + public void setHostAddress(String hostAddress) {
  288 + this.hostAddress = hostAddress;
  289 + }
435 290
436 - public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {  
437 - this.keepaliveIntervalTime = keepaliveIntervalTime;  
438 - } 291 + public boolean isOnLine() {
  292 + return onLine;
  293 + }
  294 +
  295 + public void setOnLine(boolean onLine) {
  296 + this.onLine = onLine;
  297 + }
439 298
440 - public boolean isAsMessageChannel() {  
441 - return asMessageChannel;  
442 - } 299 + public int getChannelCount() {
  300 + return channelCount;
  301 + }
443 302
444 - public void setAsMessageChannel(boolean asMessageChannel) {  
445 - this.asMessageChannel = asMessageChannel;  
446 - } 303 + public void setChannelCount(int channelCount) {
  304 + this.channelCount = channelCount;
  305 + }
447 306
448 - public SipTransactionInfo getSipTransactionInfo() {  
449 - return sipTransactionInfo;  
450 - } 307 + public String getRegisterTime() {
  308 + return registerTime;
  309 + }
  310 +
  311 + public void setRegisterTime(String registerTime) {
  312 + this.registerTime = registerTime;
  313 + }
  314 +
  315 + public String getKeepaliveTime() {
  316 + return keepaliveTime;
  317 + }
  318 +
  319 + public void setKeepaliveTime(String keepaliveTime) {
  320 + this.keepaliveTime = keepaliveTime;
  321 + }
  322 +
  323 + public int getExpires() {
  324 + return expires;
  325 + }
  326 +
  327 + public void setExpires(int expires) {
  328 + this.expires = expires;
  329 + }
  330 +
  331 + public String getCreateTime() {
  332 + return createTime;
  333 + }
  334 +
  335 + public void setCreateTime(String createTime) {
  336 + this.createTime = createTime;
  337 + }
  338 +
  339 + public String getUpdateTime() {
  340 + return updateTime;
  341 + }
  342 +
  343 + public void setUpdateTime(String updateTime) {
  344 + this.updateTime = updateTime;
  345 + }
  346 +
  347 + public String getMediaServerId() {
  348 + return mediaServerId;
  349 + }
  350 +
  351 + public void setMediaServerId(String mediaServerId) {
  352 + this.mediaServerId = mediaServerId;
  353 + }
  354 +
  355 + public String getCharset() {
  356 + return charset;
  357 + }
  358 +
  359 + public void setCharset(String charset) {
  360 + this.charset = charset;
  361 + }
  362 +
  363 + public int getSubscribeCycleForCatalog() {
  364 + return subscribeCycleForCatalog;
  365 + }
  366 +
  367 + public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {
  368 + this.subscribeCycleForCatalog = subscribeCycleForCatalog;
  369 + }
  370 +
  371 + public int getSubscribeCycleForMobilePosition() {
  372 + return subscribeCycleForMobilePosition;
  373 + }
  374 +
  375 + public void setSubscribeCycleForMobilePosition(int subscribeCycleForMobilePosition) {
  376 + this.subscribeCycleForMobilePosition = subscribeCycleForMobilePosition;
  377 + }
  378 +
  379 + public int getMobilePositionSubmissionInterval() {
  380 + return mobilePositionSubmissionInterval;
  381 + }
  382 +
  383 + public void setMobilePositionSubmissionInterval(int mobilePositionSubmissionInterval) {
  384 + this.mobilePositionSubmissionInterval = mobilePositionSubmissionInterval;
  385 + }
  386 +
  387 + public int getSubscribeCycleForAlarm() {
  388 + return subscribeCycleForAlarm;
  389 + }
  390 +
  391 + public void setSubscribeCycleForAlarm(int subscribeCycleForAlarm) {
  392 + this.subscribeCycleForAlarm = subscribeCycleForAlarm;
  393 + }
  394 +
  395 + public boolean isSsrcCheck() {
  396 + return ssrcCheck;
  397 + }
  398 +
  399 + public void setSsrcCheck(boolean ssrcCheck) {
  400 + this.ssrcCheck = ssrcCheck;
  401 + }
  402 +
  403 + public String getGeoCoordSys() {
  404 + return geoCoordSys;
  405 + }
  406 +
  407 + public void setGeoCoordSys(String geoCoordSys) {
  408 + this.geoCoordSys = geoCoordSys;
  409 + }
  410 +
  411 + public String getPassword() {
  412 + return password;
  413 + }
  414 +
  415 + public void setPassword(String password) {
  416 + this.password = password;
  417 + }
  418 +
  419 + public String getSdpIp() {
  420 + return sdpIp;
  421 + }
  422 +
  423 + public void setSdpIp(String sdpIp) {
  424 + this.sdpIp = sdpIp;
  425 + }
  426 +
  427 + public String getLocalIp() {
  428 + return localIp;
  429 + }
  430 +
  431 + public void setLocalIp(String localIp) {
  432 + this.localIp = localIp;
  433 + }
  434 +
  435 + public int getKeepaliveIntervalTime() {
  436 + return keepaliveIntervalTime;
  437 + }
  438 +
  439 + public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
  440 + this.keepaliveIntervalTime = keepaliveIntervalTime;
  441 + }
  442 +
  443 + public boolean isAsMessageChannel() {
  444 + return asMessageChannel;
  445 + }
  446 +
  447 + public void setAsMessageChannel(boolean asMessageChannel) {
  448 + this.asMessageChannel = asMessageChannel;
  449 + }
  450 +
  451 + public SipTransactionInfo getSipTransactionInfo() {
  452 + return sipTransactionInfo;
  453 + }
  454 +
  455 + public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
  456 + this.sipTransactionInfo = sipTransactionInfo;
  457 + }
451 458
452 - public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {  
453 - this.sipTransactionInfo = sipTransactionInfo;  
454 - }  
455 public boolean isBroadcastPushAfterAck() { 459 public boolean isBroadcastPushAfterAck() {
456 return broadcastPushAfterAck; 460 return broadcastPushAfterAck;
457 } 461 }
@@ -459,4 +463,12 @@ public class Device { @@ -459,4 +463,12 @@ public class Device {
459 public void setBroadcastPushAfterAck(boolean broadcastPushAfterAck) { 463 public void setBroadcastPushAfterAck(boolean broadcastPushAfterAck) {
460 this.broadcastPushAfterAck = broadcastPushAfterAck; 464 this.broadcastPushAfterAck = broadcastPushAfterAck;
461 } 465 }
  466 +
  467 + public String getCarNo() {
  468 + return carNo;
  469 + }
  470 +
  471 + public void setCarNo(String carNo) {
  472 + this.carNo = carNo;
  473 + }
462 } 474 }
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
@@ -172,4 +172,6 @@ public interface IDeviceService { @@ -172,4 +172,6 @@ public interface IDeviceService {
172 172
173 boolean addAlarmDirectorySubscribe(Device device); 173 boolean addAlarmDirectorySubscribe(Device device);
174 boolean removeAlarmDirectorySubscription(Device device); 174 boolean removeAlarmDirectorySubscription(Device device);
  175 +
  176 + List<DeviceChannel> queryDeviceChannelByCarNo(String carNO);
175 } 177 }
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -28,6 +28,7 @@ import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper; @@ -28,6 +28,7 @@ import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper;
28 import com.genersoft.iot.vmp.utils.DateUtil; 28 import com.genersoft.iot.vmp.utils.DateUtil;
29 import com.genersoft.iot.vmp.vmanager.bean.BaseTree; 29 import com.genersoft.iot.vmp.vmanager.bean.BaseTree;
30 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; 30 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
  31 +import org.apache.commons.lang3.StringUtils;
31 import org.slf4j.Logger; 32 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory; 33 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired; 34 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,6 +36,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager; @@ -35,6 +36,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
35 import org.springframework.stereotype.Service; 36 import org.springframework.stereotype.Service;
36 import org.springframework.transaction.TransactionDefinition; 37 import org.springframework.transaction.TransactionDefinition;
37 import org.springframework.transaction.TransactionStatus; 38 import org.springframework.transaction.TransactionStatus;
  39 +import org.springframework.util.CollectionUtils;
38 import org.springframework.util.ObjectUtils; 40 import org.springframework.util.ObjectUtils;
39 41
40 import javax.sip.InvalidArgumentException; 42 import javax.sip.InvalidArgumentException;
@@ -43,6 +45,7 @@ import java.text.ParseException; @@ -43,6 +45,7 @@ import java.text.ParseException;
43 import java.time.Instant; 45 import java.time.Instant;
44 import java.util.*; 46 import java.util.*;
45 import java.util.concurrent.TimeUnit; 47 import java.util.concurrent.TimeUnit;
  48 +import java.util.stream.Collectors;
46 49
47 /** 50 /**
48 * 设备业务(目录订阅) 51 * 设备业务(目录订阅)
@@ -125,7 +128,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -125,7 +128,7 @@ public class DeviceServiceImpl implements IDeviceService {
125 } 128 }
126 if (sipTransactionInfo != null) { 129 if (sipTransactionInfo != null) {
127 device.setSipTransactionInfo(sipTransactionInfo); 130 device.setSipTransactionInfo(sipTransactionInfo);
128 - }else { 131 + } else {
129 if (deviceInRedis != null) { 132 if (deviceInRedis != null) {
130 device.setSipTransactionInfo(deviceInRedis.getSipTransactionInfo()); 133 device.setSipTransactionInfo(deviceInRedis.getSipTransactionInfo());
131 } 134 }
@@ -145,8 +148,8 @@ public class DeviceServiceImpl implements IDeviceService { @@ -145,8 +148,8 @@ public class DeviceServiceImpl implements IDeviceService {
145 logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage()); 148 logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
146 } 149 }
147 sync(device); 150 sync(device);
148 - }else {  
149 - if(!device.isOnLine()){ 151 + } else {
  152 + if (!device.isOnLine()) {
150 device.setOnLine(true); 153 device.setOnLine(true);
151 device.setCreateTime(now); 154 device.setCreateTime(now);
152 deviceMapper.update(device); 155 deviceMapper.update(device);
@@ -174,7 +177,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -174,7 +177,7 @@ public class DeviceServiceImpl implements IDeviceService {
174 redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true); 177 redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
175 } 178 }
176 179
177 - }else { 180 + } else {
178 if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).size() == 0) { 181 if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).size() == 0) {
179 logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId()); 182 logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
180 sync(device); 183 sync(device);
@@ -189,7 +192,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -189,7 +192,7 @@ public class DeviceServiceImpl implements IDeviceService {
189 // 刷新过期任务 192 // 刷新过期任务
190 String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId(); 193 String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
191 // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线 194 // 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
192 - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3); 195 + dynamicTask.startDelay(registerExpireTaskKey, () -> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3);
193 196
194 // 197 //
195 // try { 198 // try {
@@ -267,9 +270,9 @@ public class DeviceServiceImpl implements IDeviceService { @@ -267,9 +270,9 @@ public class DeviceServiceImpl implements IDeviceService {
267 // 添加目录订阅 270 // 添加目录订阅
268 CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander, dynamicTask); 271 CatalogSubscribeTask catalogSubscribeTask = new CatalogSubscribeTask(device, sipCommander, dynamicTask);
269 // 刷新订阅 272 // 刷新订阅
270 - int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(),30); 273 + int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForCatalog(), 30);
271 // 设置最小值为30 274 // 设置最小值为30
272 - dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, (subscribeCycleForCatalog -1) * 1000); 275 + dynamicTask.startCron(device.getDeviceId() + "catalog", catalogSubscribeTask, (subscribeCycleForCatalog - 1) * 1000);
273 276
274 catalogSubscribeTask.run(); 277 catalogSubscribeTask.run();
275 return true; 278 return true;
@@ -302,9 +305,9 @@ public class DeviceServiceImpl implements IDeviceService { @@ -302,9 +305,9 @@ public class DeviceServiceImpl implements IDeviceService {
302 // 添加目录订阅 305 // 添加目录订阅
303 MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander, dynamicTask); 306 MobilePositionSubscribeTask mobilePositionSubscribeTask = new MobilePositionSubscribeTask(device, sipCommander, dynamicTask);
304 // 设置最小值为30 307 // 设置最小值为30
305 - int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30); 308 + int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(), 30);
306 // 刷新订阅 309 // 刷新订阅
307 - dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog * 1000); 310 + dynamicTask.startCron(device.getDeviceId() + "mobile_position", mobilePositionSubscribeTask, subscribeCycleForCatalog * 1000);
308 mobilePositionSubscribeTask.run(); 311 mobilePositionSubscribeTask.run();
309 return true; 312 return true;
310 } 313 }
@@ -343,7 +346,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -343,7 +346,7 @@ public class DeviceServiceImpl implements IDeviceService {
343 logger.info("开启同步时发现同步已经存在"); 346 logger.info("开启同步时发现同步已经存在");
344 return; 347 return;
345 } 348 }
346 - int sn = (int)((Math.random()*9+1)*100000); 349 + int sn = (int) ((Math.random() * 9 + 1) * 100000);
347 catalogResponseMessageHandler.setChannelSyncReady(device, sn); 350 catalogResponseMessageHandler.setChannelSyncReady(device, sn);
348 try { 351 try {
349 sipCommander.catalogQuery(device, sn, event -> { 352 sipCommander.catalogQuery(device, sn, event -> {
@@ -351,7 +354,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -351,7 +354,7 @@ public class DeviceServiceImpl implements IDeviceService {
351 catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg); 354 catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
352 }); 355 });
353 } catch (SipException | InvalidArgumentException | ParseException e) { 356 } catch (SipException | InvalidArgumentException | ParseException e) {
354 - logger.error("[同步通道], 信令发送失败:{}", e.getMessage() ); 357 + logger.error("[同步通道], 信令发送失败:{}", e.getMessage());
355 String errorMsg = String.format("同步通道失败,信令发送失败: %s", e.getMessage()); 358 String errorMsg = String.format("同步通道失败,信令发送失败: %s", e.getMessage());
356 catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg); 359 catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), errorMsg);
357 } 360 }
@@ -415,14 +418,14 @@ public class DeviceServiceImpl implements IDeviceService { @@ -415,14 +418,14 @@ public class DeviceServiceImpl implements IDeviceService {
415 * 更新通道坐标系 418 * 更新通道坐标系
416 */ 419 */
417 private void updateDeviceChannelGeoCoordSys(Device device) { 420 private void updateDeviceChannelGeoCoordSys(Device device) {
418 - List<DeviceChannel> deviceChannels = deviceChannelMapper.getAllChannelWithCoordinate(device.getDeviceId());  
419 - if (deviceChannels.size() > 0) {  
420 - List<DeviceChannel> deviceChannelsForStore = new ArrayList<>();  
421 - for (DeviceChannel deviceChannel : deviceChannels) {  
422 - deviceChannelsForStore.add(deviceChannelService.updateGps(deviceChannel, device));  
423 - }  
424 - deviceChannelService.updateChannels(device.getDeviceId(), deviceChannelsForStore);  
425 - } 421 + List<DeviceChannel> deviceChannels = deviceChannelMapper.getAllChannelWithCoordinate(device.getDeviceId());
  422 + if (deviceChannels.size() > 0) {
  423 + List<DeviceChannel> deviceChannelsForStore = new ArrayList<>();
  424 + for (DeviceChannel deviceChannel : deviceChannels) {
  425 + deviceChannelsForStore.add(deviceChannelService.updateGps(deviceChannel, device));
  426 + }
  427 + deviceChannelService.updateChannels(device.getDeviceId(), deviceChannelsForStore);
  428 + }
426 } 429 }
427 430
428 431
@@ -432,7 +435,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -432,7 +435,7 @@ public class DeviceServiceImpl implements IDeviceService {
432 if (device == null) { 435 if (device == null) {
433 return null; 436 return null;
434 } 437 }
435 - if (ObjectUtils.isEmpty(parentId) ) { 438 + if (ObjectUtils.isEmpty(parentId)) {
436 parentId = deviceId; 439 parentId = deviceId;
437 } 440 }
438 List<DeviceChannel> rootNodes = deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, onlyCatalog); 441 List<DeviceChannel> rootNodes = deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, onlyCatalog);
@@ -447,7 +450,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -447,7 +450,7 @@ public class DeviceServiceImpl implements IDeviceService {
447 } 450 }
448 if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) { 451 if (ObjectUtils.isEmpty(parentId) || parentId.equals(deviceId)) {
449 return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, null, false); 452 return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, null, false);
450 - }else { 453 + } else {
451 return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, false); 454 return deviceChannelMapper.getSubChannelsByDeviceId(deviceId, parentId, false);
452 } 455 }
453 } 456 }
@@ -471,16 +474,16 @@ public class DeviceServiceImpl implements IDeviceService { @@ -471,16 +474,16 @@ public class DeviceServiceImpl implements IDeviceService {
471 node.setParent(false); 474 node.setParent(false);
472 if (channel.getChannelId().length() <= 8) { 475 if (channel.getChannelId().length() <= 8) {
473 node.setParent(true); 476 node.setParent(true);
474 - }else { 477 + } else {
475 if (channel.getChannelId().length() != 20) { 478 if (channel.getChannelId().length() != 20) {
476 node.setParent(channel.getParental() == 1); 479 node.setParent(channel.getParental() == 1);
477 - }else { 480 + } else {
478 try { 481 try {
479 int type = Integer.parseInt(channel.getChannelId().substring(10, 13)); 482 int type = Integer.parseInt(channel.getChannelId().substring(10, 13));
480 if (type == 215 || type == 216 || type == 200) { 483 if (type == 215 || type == 216 || type == 200) {
481 node.setParent(true); 484 node.setParent(true);
482 } 485 }
483 - }catch (NumberFormatException e) { 486 + } catch (NumberFormatException e) {
484 node.setParent(false); 487 node.setParent(false);
485 } 488 }
486 } 489 }
@@ -533,6 +536,10 @@ public class DeviceServiceImpl implements IDeviceService { @@ -533,6 +536,10 @@ public class DeviceServiceImpl implements IDeviceService {
533 if (!ObjectUtils.isEmpty(device.getStreamMode())) { 536 if (!ObjectUtils.isEmpty(device.getStreamMode())) {
534 deviceInStore.setStreamMode(device.getStreamMode()); 537 deviceInStore.setStreamMode(device.getStreamMode());
535 } 538 }
  539 +
  540 + if (!ObjectUtils.isEmpty(device.getCarNo())) {
  541 + deviceInStore.setCarNo(device.getCarNo());
  542 + }
536 // 事件订阅相关的信息 543 // 事件订阅相关的信息
537 if (deviceInStore.getSubscribeCycleForAlarm() != device.getSubscribeCycleForAlarm()) { 544 if (deviceInStore.getSubscribeCycleForAlarm() != device.getSubscribeCycleForAlarm()) {
538 if (device.getSubscribeCycleForAlarm() > 0) { 545 if (device.getSubscribeCycleForAlarm() > 0) {
@@ -555,7 +562,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -555,7 +562,7 @@ public class DeviceServiceImpl implements IDeviceService {
555 if (device.getSubscribeCycleForCatalog() > 0) { 562 if (device.getSubscribeCycleForCatalog() > 0) {
556 // 若已开启订阅,但订阅周期不同,则先取消 563 // 若已开启订阅,但订阅周期不同,则先取消
557 if (deviceInStore.getSubscribeCycleForCatalog() != 0) { 564 if (deviceInStore.getSubscribeCycleForCatalog() != 0) {
558 - removeCatalogSubscribe(deviceInStore, result->{ 565 + removeCatalogSubscribe(deviceInStore, result -> {
559 // 开启订阅 566 // 开启订阅
560 deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); 567 deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
561 addCatalogSubscribe(deviceInStore); 568 addCatalogSubscribe(deviceInStore);
@@ -563,13 +570,13 @@ public class DeviceServiceImpl implements IDeviceService { @@ -563,13 +570,13 @@ public class DeviceServiceImpl implements IDeviceService {
563 deviceMapper.updateCustom(deviceInStore); 570 deviceMapper.updateCustom(deviceInStore);
564 redisCatchStorage.updateDevice(deviceInStore); 571 redisCatchStorage.updateDevice(deviceInStore);
565 }); 572 });
566 - }else { 573 + } else {
567 // 开启订阅 574 // 开启订阅
568 deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog()); 575 deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
569 addCatalogSubscribe(deviceInStore); 576 addCatalogSubscribe(deviceInStore);
570 } 577 }
571 578
572 - }else if (device.getSubscribeCycleForCatalog() == 0) { 579 + } else if (device.getSubscribeCycleForCatalog() == 0) {
573 // 取消订阅 580 // 取消订阅
574 deviceInStore.setSubscribeCycleForCatalog(0); 581 deviceInStore.setSubscribeCycleForCatalog(0);
575 removeCatalogSubscribe(deviceInStore, null); 582 removeCatalogSubscribe(deviceInStore, null);
@@ -580,7 +587,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -580,7 +587,7 @@ public class DeviceServiceImpl implements IDeviceService {
580 if (device.getSubscribeCycleForMobilePosition() > 0) { 587 if (device.getSubscribeCycleForMobilePosition() > 0) {
581 // 若已开启订阅,但订阅周期不同,则先取消 588 // 若已开启订阅,但订阅周期不同,则先取消
582 if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) { 589 if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) {
583 - removeMobilePositionSubscribe(deviceInStore, result->{ 590 + removeMobilePositionSubscribe(deviceInStore, result -> {
584 // 开启订阅 591 // 开启订阅
585 deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); 592 deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
586 addMobilePositionSubscribe(deviceInStore); 593 addMobilePositionSubscribe(deviceInStore);
@@ -588,13 +595,13 @@ public class DeviceServiceImpl implements IDeviceService { @@ -588,13 +595,13 @@ public class DeviceServiceImpl implements IDeviceService {
588 deviceMapper.updateCustom(deviceInStore); 595 deviceMapper.updateCustom(deviceInStore);
589 redisCatchStorage.updateDevice(deviceInStore); 596 redisCatchStorage.updateDevice(deviceInStore);
590 }); 597 });
591 - }else { 598 + } else {
592 // 开启订阅 599 // 开启订阅
593 deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition()); 600 deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
594 addMobilePositionSubscribe(deviceInStore); 601 addMobilePositionSubscribe(deviceInStore);
595 } 602 }
596 603
597 - }else if (device.getSubscribeCycleForMobilePosition() == 0) { 604 + } else if (device.getSubscribeCycleForMobilePosition() == 0) {
598 // 取消订阅 605 // 取消订阅
599 deviceInStore.setSubscribeCycleForMobilePosition(0); 606 deviceInStore.setSubscribeCycleForMobilePosition(0);
600 removeMobilePositionSubscribe(deviceInStore, null); 607 removeMobilePositionSubscribe(deviceInStore, null);
@@ -606,7 +613,7 @@ public class DeviceServiceImpl implements IDeviceService { @@ -606,7 +613,7 @@ public class DeviceServiceImpl implements IDeviceService {
606 deviceInStore.setGeoCoordSys(device.getGeoCoordSys()); 613 deviceInStore.setGeoCoordSys(device.getGeoCoordSys());
607 updateDeviceChannelGeoCoordSys(deviceInStore); 614 updateDeviceChannelGeoCoordSys(deviceInStore);
608 } 615 }
609 - }else { 616 + } else {
610 deviceInStore.setGeoCoordSys("WGS84"); 617 deviceInStore.setGeoCoordSys("WGS84");
611 } 618 }
612 if (device.getCharset() == null) { 619 if (device.getCharset() == null) {
@@ -628,13 +635,13 @@ public class DeviceServiceImpl implements IDeviceService { @@ -628,13 +635,13 @@ public class DeviceServiceImpl implements IDeviceService {
628 try { 635 try {
629 platformChannelMapper.delChannelForDeviceId(deviceId); 636 platformChannelMapper.delChannelForDeviceId(deviceId);
630 deviceChannelMapper.cleanChannelsByDeviceId(deviceId); 637 deviceChannelMapper.cleanChannelsByDeviceId(deviceId);
631 - if ( deviceMapper.del(deviceId) < 0 ) { 638 + if (deviceMapper.del(deviceId) < 0) {
632 //事务回滚 639 //事务回滚
633 dataSourceTransactionManager.rollback(transactionStatus); 640 dataSourceTransactionManager.rollback(transactionStatus);
634 } 641 }
635 result = true; 642 result = true;
636 dataSourceTransactionManager.commit(transactionStatus); //手动提交 643 dataSourceTransactionManager.commit(transactionStatus); //手动提交
637 - }catch (Exception e) { 644 + } catch (Exception e) {
638 dataSourceTransactionManager.rollback(transactionStatus); 645 dataSourceTransactionManager.rollback(transactionStatus);
639 } 646 }
640 if (result) { 647 if (result) {
@@ -689,5 +696,19 @@ public class DeviceServiceImpl implements IDeviceService { @@ -689,5 +696,19 @@ public class DeviceServiceImpl implements IDeviceService {
689 return true; 696 return true;
690 } 697 }
691 698
  699 + @Override
  700 + public List<DeviceChannel> queryDeviceChannelByCarNo(String carNO) {
  701 + if (StringUtils.isEmpty(carNO)) {
  702 + return Collections.emptyList();
  703 + }
  704 + List<Device> devices = deviceMapper.queryDeviceByCarNo(carNO);
  705 + if (CollectionUtils.isEmpty(devices)) {
  706 + return Collections.emptyList();
  707 + }
  708 +
  709 + Set<String> deviceIds = devices.stream().map(Device::getDeviceId).collect(Collectors.toSet());
  710 + return deviceChannelMapper.querySubChannelsByDeviceIds(deviceIds);
  711 + }
  712 +
692 713
693 } 714 }
src/main/java/com/genersoft/iot/vmp/service/impl/UserServiceImpl.java
@@ -21,6 +21,7 @@ public class UserServiceImpl implements IUserService { @@ -21,6 +21,7 @@ public class UserServiceImpl implements IUserService {
21 21
22 @Override 22 @Override
23 public User getUser(String username, String password) { 23 public User getUser(String username, String password) {
  24 +
24 return userMapper.select(username, password); 25 return userMapper.select(username, password);
25 } 26 }
26 27
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
8 import org.apache.ibatis.annotations.*; 8 import org.apache.ibatis.annotations.*;
9 import org.springframework.stereotype.Repository; 9 import org.springframework.stereotype.Repository;
10 10
  11 +import java.util.Collection;
11 import java.util.List; 12 import java.util.List;
12 13
13 /** 14 /**
@@ -550,4 +551,50 @@ public interface DeviceChannelMapper { @@ -550,4 +551,50 @@ public interface DeviceChannelMapper {
550 " <if test='channelId != null'> and channel_id = #{channelId} </if>" + 551 " <if test='channelId != null'> and channel_id = #{channelId} </if>" +
551 "</script>") 552 "</script>")
552 void updateChannelStreamIdentification(DeviceChannel channel); 553 void updateChannelStreamIdentification(DeviceChannel channel);
  554 +
  555 +
  556 + @Select(value = {" <script>" +
  557 + "SELECT id,\n" +
  558 + " channel_id as channelId,\n" +
  559 + " COALESCE(custom_name, name) AS name,\n" +
  560 + " custom_name,\n" +
  561 + " manufacture,\n" +
  562 + " model,\n" +
  563 + " owner,\n" +
  564 + " civil_code,\n" +
  565 + " block,\n" +
  566 + " address,\n" +
  567 + " parent_id,\n" +
  568 + " safety_way,\n" +
  569 + " register_way,\n" +
  570 + " cert_num,\n" +
  571 + " certifiable,\n" +
  572 + " err_code,\n" +
  573 + " end_time,\n" +
  574 + " secrecy,\n" +
  575 + " ip_address,\n" +
  576 + " port,\n" +
  577 + " password,\n" +
  578 + " COALESCE(custom_ptz_type, ptz_type) AS ptz_type,\n" +
  579 + " status,\n" +
  580 + " COALESCE(custom_longitude, longitude) AS longitude,\n" +
  581 + " COALESCE(custom_latitude, latitude) AS latitude,\n" +
  582 + " stream_id,\n" +
  583 + " device_id,\n" +
  584 + " parental,\n" +
  585 + " has_audio,\n" +
  586 + " create_time,\n" +
  587 + " update_time,\n" +
  588 + " sub_count,\n" +
  589 + " longitude_gcj02,\n" +
  590 + " latitude_gcj02,\n" +
  591 + " longitude_wgs84,\n" +
  592 + " latitude_wgs84,\n" +
  593 + " business_group_id,\n" +
  594 + " gps_time\n" +
  595 + "from wvp_device_channel " +
  596 + "where device_id in " +
  597 + "<foreach collection='deviceIds' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
  598 + " </script>"})
  599 + List<DeviceChannel> querySubChannelsByDeviceIds(@Param("deviceIds") Collection<String> deviceIds);
553 } 600 }
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
@@ -255,6 +255,7 @@ public interface DeviceMapper { @@ -255,6 +255,7 @@ public interface DeviceMapper {
255 "<if test=\"broadcastPushAfterAck != null\">, broadcast_push_after_ack=#{broadcastPushAfterAck}</if>" + 255 "<if test=\"broadcastPushAfterAck != null\">, broadcast_push_after_ack=#{broadcastPushAfterAck}</if>" +
256 "<if test=\"geoCoordSys != null\">, geo_coord_sys=#{geoCoordSys}</if>" + 256 "<if test=\"geoCoordSys != null\">, geo_coord_sys=#{geoCoordSys}</if>" +
257 "<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" + 257 "<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" +
  258 + "<if test=\"carNo != null\">, car_No=#{carNo}</if>" +
258 "WHERE device_id=#{deviceId}"+ 259 "WHERE device_id=#{deviceId}"+
259 " </script>"}) 260 " </script>"})
260 void updateCustom(Device device); 261 void updateCustom(Device device);
@@ -272,7 +273,8 @@ public interface DeviceMapper { @@ -272,7 +273,8 @@ public interface DeviceMapper {
272 "broadcast_push_after_ack,"+ 273 "broadcast_push_after_ack,"+
273 "geo_coord_sys,"+ 274 "geo_coord_sys,"+
274 "on_line,"+ 275 "on_line,"+
275 - "media_server_id"+ 276 + "media_server_id,"+
  277 + "car_No"+
276 ") VALUES (" + 278 ") VALUES (" +
277 "#{deviceId}," + 279 "#{deviceId}," +
278 "#{name}," + 280 "#{name}," +
@@ -286,7 +288,8 @@ public interface DeviceMapper { @@ -286,7 +288,8 @@ public interface DeviceMapper {
286 "#{broadcastPushAfterAck}," + 288 "#{broadcastPushAfterAck}," +
287 "#{geoCoordSys}," + 289 "#{geoCoordSys}," +
288 "#{onLine}," + 290 "#{onLine}," +
289 - "#{mediaServerId}" + 291 + "#{mediaServerId}," +
  292 + "#{carNo}" +
290 ")") 293 ")")
291 void addCustomDevice(Device device); 294 void addCustomDevice(Device device);
292 295
@@ -295,4 +298,7 @@ public interface DeviceMapper { @@ -295,4 +298,7 @@ public interface DeviceMapper {
295 298
296 @Select("select * FROM wvp_device where as_message_channel = true") 299 @Select("select * FROM wvp_device where as_message_channel = true")
297 List<Device> queryDeviceWithAsMessageChannel(); 300 List<Device> queryDeviceWithAsMessageChannel();
  301 +
  302 + @Select("select * FROM wvp_device where car_No = #{carNo}")
  303 + List<Device> queryDeviceByCarNo(@Param("carNo") String carNo);
298 } 304 }
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -49,538 +49,562 @@ import java.nio.file.Files; @@ -49,538 +49,562 @@ import java.nio.file.Files;
49 import java.text.ParseException; 49 import java.text.ParseException;
50 import java.util.*; 50 import java.util.*;
51 51
52 -@Tag(name = "国标设备查询", description = "国标设备查询") 52 +@Tag(name = "国标设备查询", description = "国标设备查询")
53 @SuppressWarnings("rawtypes") 53 @SuppressWarnings("rawtypes")
54 54
55 @RestController 55 @RestController
56 @RequestMapping("/api/device/query") 56 @RequestMapping("/api/device/query")
57 public class DeviceQuery { 57 public class DeviceQuery {
58 -  
59 - private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class);  
60 -  
61 - @Autowired  
62 - private IVideoManagerStorage storager;  
63 -  
64 - @Autowired  
65 - private IDeviceChannelService deviceChannelService;  
66 -  
67 - @Autowired  
68 - private IRedisCatchStorage redisCatchStorage;  
69 -  
70 - @Autowired  
71 - private IInviteStreamService inviteStreamService;  
72 -  
73 - @Autowired  
74 - private SIPCommander cmder;  
75 -  
76 - @Autowired  
77 - private DeferredResultHolder resultHolder;  
78 -  
79 - @Autowired  
80 - private IDeviceService deviceService;  
81 -  
82 - @Autowired  
83 - private DynamicTask dynamicTask;  
84 -  
85 - /**  
86 - * 使用ID查询国标设备  
87 - * @param deviceId 国标ID  
88 - * @return 国标设备  
89 - */  
90 - @Operation(summary = "查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))  
91 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
92 - @GetMapping("/devices/{deviceId}")  
93 - public Device devices(@PathVariable String deviceId){  
94 -  
95 - return storager.queryVideoDevice(deviceId);  
96 - }  
97 -  
98 - /**  
99 - * 分页查询国标设备  
100 - * @param page 当前页  
101 - * @param count 每页查询数量  
102 - * @return 分页国标列表  
103 - */  
104 - @Operation(summary = "分页查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))  
105 - @Parameter(name = "page", description = "当前页", required = true)  
106 - @Parameter(name = "count", description = "每页查询数量", required = true)  
107 - @GetMapping("/devices")  
108 - @Options()  
109 - public PageInfo<Device> devices(int page, int count){ 58 +
  59 + private final static Logger logger = LoggerFactory.getLogger(DeviceQuery.class);
  60 +
  61 + @Autowired
  62 + private IVideoManagerStorage storager;
  63 +
  64 + @Autowired
  65 + private IDeviceChannelService deviceChannelService;
  66 +
  67 + @Autowired
  68 + private IRedisCatchStorage redisCatchStorage;
  69 +
  70 + @Autowired
  71 + private IInviteStreamService inviteStreamService;
  72 +
  73 + @Autowired
  74 + private SIPCommander cmder;
  75 +
  76 + @Autowired
  77 + private DeferredResultHolder resultHolder;
  78 +
  79 + @Autowired
  80 + private IDeviceService deviceService;
  81 +
  82 + @Autowired
  83 + private DynamicTask dynamicTask;
  84 +
  85 + /**
  86 + * 使用ID查询国标设备
  87 + *
  88 + * @param deviceId 国标ID
  89 + * @return 国标设备
  90 + */
  91 + @Operation(summary = "查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
  92 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  93 + @GetMapping("/devices/{deviceId}")
  94 + public Device devices(@PathVariable String deviceId) {
  95 +
  96 + return storager.queryVideoDevice(deviceId);
  97 + }
  98 +
  99 + /**
  100 + * 分页查询国标设备
  101 + *
  102 + * @param page 当前页
  103 + * @param count 每页查询数量
  104 + * @return 分页国标列表
  105 + */
  106 + @Operation(summary = "分页查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
  107 + @Parameter(name = "page", description = "当前页", required = true)
  108 + @Parameter(name = "count", description = "每页查询数量", required = true)
  109 + @GetMapping("/devices")
  110 + @Options()
  111 + public PageInfo<Device> devices(int page, int count) {
110 // if (page == null) page = 0; 112 // if (page == null) page = 0;
111 // if (count == null) count = 20; 113 // if (count == null) count = 20;
112 - return storager.queryVideoDeviceList(page, count,null);  
113 - }  
114 -  
115 - /**  
116 - * 分页查询通道数  
117 - *  
118 - * @param deviceId 设备id  
119 - * @param page 当前页  
120 - * @param count 每页条数  
121 - * @param query 查询内容  
122 - * @param online 是否在线 在线 true / 离线 false  
123 - * @param channelType 设备 false/子目录 true  
124 - * @param catalogUnderDevice 是否直属与设备的目录  
125 - * @return 通道列表  
126 - */  
127 - @GetMapping("/devices/{deviceId}/channels")  
128 - @Operation(summary = "分页查询通道", security = @SecurityRequirement(name = JwtUtils.HEADER))  
129 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
130 - @Parameter(name = "page", description = "当前页", required = true)  
131 - @Parameter(name = "count", description = "每页查询数量", required = true)  
132 - @Parameter(name = "query", description = "查询内容")  
133 - @Parameter(name = "online", description = "是否在线")  
134 - @Parameter(name = "channelType", description = "设备/子目录-> false/true")  
135 - @Parameter(name = "catalogUnderDevice", description = "是否直属与设备的目录")  
136 - public PageInfo<DeviceChannel> channels(@PathVariable String deviceId,  
137 - int page, int count,  
138 - @RequestParam(required = false) String query,  
139 - @RequestParam(required = false) Boolean online,  
140 - @RequestParam(required = false) Boolean channelType,  
141 - @RequestParam(required = false) Boolean catalogUnderDevice) {  
142 - if (ObjectUtils.isEmpty(query)) {  
143 - query = null;  
144 - }  
145 -  
146 - return storager.queryChannelsByDeviceId(deviceId, query, channelType, online, catalogUnderDevice, page, count);  
147 - }  
148 -  
149 - /**  
150 - * 同步设备通道  
151 - * @param deviceId 设备id  
152 - * @return  
153 - */  
154 - @Operation(summary = "同步设备通道", security = @SecurityRequirement(name = JwtUtils.HEADER))  
155 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
156 - @GetMapping("/devices/{deviceId}/sync")  
157 - public WVPResult<SyncStatus> devicesSync(@PathVariable String deviceId){  
158 -  
159 - if (logger.isDebugEnabled()) {  
160 - logger.debug("设备通道信息同步API调用,deviceId:" + deviceId);  
161 - }  
162 - Device device = storager.queryVideoDevice(deviceId);  
163 - boolean status = deviceService.isSyncRunning(deviceId);  
164 - // 已存在则返回进度  
165 - if (status) {  
166 - SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);  
167 - return WVPResult.success(channelSyncStatus);  
168 - }  
169 - deviceService.sync(device);  
170 -  
171 - WVPResult<SyncStatus> wvpResult = new WVPResult<>();  
172 - wvpResult.setCode(0);  
173 - wvpResult.setMsg("开始同步");  
174 - return wvpResult;  
175 - }  
176 -  
177 - /**  
178 - * 移除设备  
179 - * @param deviceId 设备id  
180 - * @return  
181 - */  
182 - @Operation(summary = "移除设备", security = @SecurityRequirement(name = JwtUtils.HEADER))  
183 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
184 - @DeleteMapping("/devices/{deviceId}/delete")  
185 - public String delete(@PathVariable String deviceId){  
186 -  
187 - if (logger.isDebugEnabled()) {  
188 - logger.debug("设备信息删除API调用,deviceId:" + deviceId);  
189 - }  
190 -  
191 - // 清除redis记录  
192 - boolean isSuccess = deviceService.delete(deviceId);  
193 - if (isSuccess) {  
194 - inviteStreamService.clearInviteInfo(deviceId);  
195 - // 停止此设备的订阅更新  
196 - Set<String> allKeys = dynamicTask.getAllKeys();  
197 - for (String key : allKeys) {  
198 - if (key.startsWith(deviceId)) {  
199 - Runnable runnable = dynamicTask.get(key);  
200 - if (runnable instanceof ISubscribeTask) {  
201 - ISubscribeTask subscribeTask = (ISubscribeTask) runnable;  
202 - subscribeTask.stop(null);  
203 - }  
204 - dynamicTask.stop(key);  
205 - }  
206 - }  
207 - JSONObject json = new JSONObject();  
208 - json.put("deviceId", deviceId);  
209 - return json.toString();  
210 - } else {  
211 - logger.warn("设备信息删除API调用失败!");  
212 - throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备信息删除API调用失败!");  
213 - }  
214 - }  
215 -  
216 - /**  
217 - * 分页查询子目录通道  
218 - * @param deviceId 通道id  
219 - * @param channelId 通道id  
220 - * @param page 当前页  
221 - * @param count 每页条数  
222 - * @param query 查询内容  
223 - * @param online 是否在线  
224 - * @param channelType 通道类型  
225 - * @return 子通道列表  
226 - */  
227 - @Operation(summary = "分页查询子目录通道", security = @SecurityRequirement(name = JwtUtils.HEADER))  
228 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
229 - @Parameter(name = "channelId", description = "通道国标编号", required = true)  
230 - @Parameter(name = "page", description = "当前页", required = true)  
231 - @Parameter(name = "count", description = "每页查询数量", required = true)  
232 - @Parameter(name = "query", description = "查询内容")  
233 - @Parameter(name = "online", description = "是否在线")  
234 - @Parameter(name = "channelType", description = "设备/子目录-> false/true")  
235 - @GetMapping("/sub_channels/{deviceId}/{channelId}/channels")  
236 - public PageInfo<DeviceChannel> subChannels(@PathVariable String deviceId,  
237 - @PathVariable String channelId,  
238 - int page,  
239 - int count,  
240 - @RequestParam(required = false) String query,  
241 - @RequestParam(required = false) Boolean online,  
242 - @RequestParam(required = false) Boolean channelType){  
243 -  
244 - DeviceChannel deviceChannel = storager.queryChannel(deviceId,channelId);  
245 - if (deviceChannel == null) {  
246 - PageInfo<DeviceChannel> deviceChannelPageResult = new PageInfo<>();  
247 - return deviceChannelPageResult;  
248 - }  
249 -  
250 - return storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);  
251 - }  
252 -  
253 - /**  
254 - * 更新通道信息  
255 - * @param deviceId 设备id  
256 - * @param channel 通道  
257 - * @return  
258 - */  
259 - @Operation(summary = "更新通道信息", security = @SecurityRequirement(name = JwtUtils.HEADER))  
260 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
261 - @Parameter(name = "channel", description = "通道信息", required = true)  
262 - @PostMapping("/channel/update/{deviceId}")  
263 - public void updateChannel(@PathVariable String deviceId,DeviceChannel channel){  
264 - deviceChannelService.updateChannel(deviceId, channel);  
265 - }  
266 -  
267 - @Operation(summary = "修改通道的码流类型", security = @SecurityRequirement(name = JwtUtils.HEADER))  
268 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
269 - @Parameter(name = "channel", description = "通道信息", required = true)  
270 - @PostMapping("/channel/stream/identification/update/")  
271 - public void updateChannelStreamIdentification(DeviceChannel channel){  
272 - deviceChannelService.updateChannelStreamIdentification(channel);  
273 - }  
274 -  
275 - /**  
276 - * 修改数据流传输模式  
277 - * @param deviceId 设备id  
278 - * @param streamMode 数据流传输模式  
279 - * @return  
280 - */  
281 - @Operation(summary = "修改数据流传输模式", security = @SecurityRequirement(name = JwtUtils.HEADER))  
282 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
283 - @Parameter(name = "streamMode", description = "数据流传输模式, 取值:" +  
284 - "UDP(udp传输),TCP-ACTIVE(tcp主动模式,暂不支持),TCP-PASSIVE(tcp被动模式)", required = true)  
285 - @PostMapping("/transport/{deviceId}/{streamMode}")  
286 - public void updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){  
287 - Device device = deviceService.getDevice(deviceId);  
288 - device.setStreamMode(streamMode);  
289 - deviceService.updateCustomDevice(device);  
290 - }  
291 -  
292 - /**  
293 - * 添加设备信息  
294 - * @param device 设备信息  
295 - * @return  
296 - */  
297 - @Operation(summary = "添加设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))  
298 - @Parameter(name = "device", description = "设备", required = true)  
299 - @PostMapping("/device/add/")  
300 - public void addDevice(Device device){  
301 -  
302 - if (device == null || device.getDeviceId() == null) {  
303 - throw new ControllerException(ErrorCode.ERROR400);  
304 - }  
305 -  
306 - // 查看deviceId是否存在  
307 - boolean exist = deviceService.isExist(device.getDeviceId());  
308 - if (exist) {  
309 - throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备编号已存在");  
310 - }  
311 - deviceService.addDevice(device);  
312 - }  
313 -  
314 - /**  
315 - * 更新设备信息  
316 - * @param device 设备信息  
317 - * @return  
318 - */  
319 - @Operation(summary = "更新设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))  
320 - @Parameter(name = "device", description = "设备", required = true)  
321 - @PostMapping("/device/update/")  
322 - public void updateDevice(Device device){  
323 -  
324 - if (device != null && device.getDeviceId() != null) {  
325 - deviceService.updateCustomDevice(device);  
326 - }  
327 - }  
328 -  
329 - /**  
330 - * 设备状态查询请求API接口  
331 - *  
332 - * @param deviceId 设备id  
333 - */  
334 - @Operation(summary = "设备状态查询", security = @SecurityRequirement(name = JwtUtils.HEADER))  
335 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
336 - @GetMapping("/devices/{deviceId}/status")  
337 - public DeferredResult<ResponseEntity<String>> deviceStatusApi(@PathVariable String deviceId) {  
338 - if (logger.isDebugEnabled()) {  
339 - logger.debug("设备状态查询API调用");  
340 - }  
341 - Device device = storager.queryVideoDevice(deviceId);  
342 - String uuid = UUID.randomUUID().toString();  
343 - String key = DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId;  
344 - DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(2*1000L);  
345 - if(device == null) {  
346 - result.setResult(new ResponseEntity(String.format("设备%s不存在", deviceId),HttpStatus.OK));  
347 - return result;  
348 - }  
349 - try {  
350 - cmder.deviceStatusQuery(device, event -> {  
351 - RequestMessage msg = new RequestMessage();  
352 - msg.setId(uuid);  
353 - msg.setKey(key);  
354 - msg.setData(String.format("获取设备状态失败,错误码: %s, %s", event.statusCode, event.msg));  
355 - resultHolder.invokeResult(msg);  
356 - });  
357 - } catch (InvalidArgumentException | SipException | ParseException e) {  
358 - logger.error("[命令发送失败] 获取设备状态: {}", e.getMessage());  
359 - throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());  
360 - }  
361 - result.onTimeout(()->{  
362 - logger.warn(String.format("获取设备状态超时"));  
363 - // 释放rtpserver  
364 - RequestMessage msg = new RequestMessage();  
365 - msg.setId(uuid);  
366 - msg.setKey(key);  
367 - msg.setData("Timeout. Device did not response to this command.");  
368 - resultHolder.invokeResult(msg);  
369 - });  
370 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, uuid, result);  
371 - return result;  
372 - }  
373 -  
374 - /**  
375 - * 设备报警查询请求API接口  
376 - * @param deviceId 设备id  
377 - * @param startPriority 报警起始级别(可选)  
378 - * @param endPriority 报警终止级别(可选)  
379 - * @param alarmMethod 报警方式条件(可选)  
380 - * @param alarmType 报警类型  
381 - * @param startTime 报警发生起始时间(可选)  
382 - * @param endTime 报警发生终止时间(可选)  
383 - * @return true = 命令发送成功  
384 - */  
385 - @Operation(summary = "设备报警查询", security = @SecurityRequirement(name = JwtUtils.HEADER))  
386 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
387 - @Parameter(name = "startPriority", description = "报警起始级别")  
388 - @Parameter(name = "endPriority", description = "报警终止级别")  
389 - @Parameter(name = "alarmMethod", description = "报警方式条件")  
390 - @Parameter(name = "alarmType", description = "报警类型")  
391 - @Parameter(name = "startTime", description = "报警发生起始时间")  
392 - @Parameter(name = "endTime", description = "报警发生终止时间")  
393 - @GetMapping("/alarm/{deviceId}")  
394 - public DeferredResult<ResponseEntity<String>> alarmApi(@PathVariable String deviceId,  
395 - @RequestParam(required = false) String startPriority,  
396 - @RequestParam(required = false) String endPriority,  
397 - @RequestParam(required = false) String alarmMethod,  
398 - @RequestParam(required = false) String alarmType,  
399 - @RequestParam(required = false) String startTime,  
400 - @RequestParam(required = false) String endTime) {  
401 - if (logger.isDebugEnabled()) {  
402 - logger.debug("设备报警查询API调用");  
403 - }  
404 - Device device = storager.queryVideoDevice(deviceId);  
405 - String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;  
406 - String uuid = UUID.randomUUID().toString();  
407 - try {  
408 - cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {  
409 - RequestMessage msg = new RequestMessage();  
410 - msg.setId(uuid);  
411 - msg.setKey(key);  
412 - msg.setData(String.format("设备报警查询失败,错误码: %s, %s",event.statusCode, event.msg));  
413 - resultHolder.invokeResult(msg);  
414 - });  
415 - } catch (InvalidArgumentException | SipException | ParseException e) {  
416 - logger.error("[命令发送失败] 设备报警查询: {}", e.getMessage());  
417 - throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());  
418 - }  
419 - DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);  
420 - result.onTimeout(()->{  
421 - logger.warn(String.format("设备报警查询超时"));  
422 - // 释放rtpserver  
423 - RequestMessage msg = new RequestMessage();  
424 - msg.setId(uuid);  
425 - msg.setKey(key);  
426 - msg.setData("设备报警查询超时");  
427 - resultHolder.invokeResult(msg);  
428 - });  
429 - resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, uuid, result);  
430 - return result;  
431 - }  
432 -  
433 -  
434 - @GetMapping("/{deviceId}/sync_status")  
435 - @Operation(summary = "获取通道同步进度", security = @SecurityRequirement(name = JwtUtils.HEADER))  
436 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
437 - public WVPResult<SyncStatus> getSyncStatus(@PathVariable String deviceId) {  
438 - SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);  
439 - WVPResult<SyncStatus> wvpResult = new WVPResult<>();  
440 - if (channelSyncStatus == null) {  
441 - wvpResult.setCode(-1);  
442 - wvpResult.setMsg("同步尚未开始");  
443 - }else {  
444 - wvpResult.setCode(ErrorCode.SUCCESS.getCode());  
445 - wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());  
446 - wvpResult.setData(channelSyncStatus);  
447 - if (channelSyncStatus.getErrorMsg() != null) {  
448 - wvpResult.setMsg(channelSyncStatus.getErrorMsg());  
449 - }  
450 - }  
451 - return wvpResult;  
452 - }  
453 -  
454 - @GetMapping("/{deviceId}/subscribe_info")  
455 - @Operation(summary = "获取设备的订阅状态", security = @SecurityRequirement(name = JwtUtils.HEADER))  
456 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
457 - public WVPResult<Map<String, Integer>> getSubscribeInfo(@PathVariable String deviceId) {  
458 - Set<String> allKeys = dynamicTask.getAllKeys();  
459 - Map<String, Integer> dialogStateMap = new HashMap<>();  
460 - for (String key : allKeys) {  
461 - if (key.startsWith(deviceId)) {  
462 - ISubscribeTask subscribeTask = (ISubscribeTask)dynamicTask.get(key);  
463 - if (subscribeTask instanceof CatalogSubscribeTask) {  
464 - dialogStateMap.put("catalog", 1);  
465 - }else if (subscribeTask instanceof MobilePositionSubscribeTask) {  
466 - dialogStateMap.put("mobilePosition", 1);  
467 - }  
468 - }  
469 - }  
470 - WVPResult<Map<String, Integer>> wvpResult = new WVPResult<>();  
471 - wvpResult.setCode(0);  
472 - wvpResult.setData(dialogStateMap);  
473 - return wvpResult;  
474 - }  
475 -  
476 - @GetMapping("/snap/{deviceId}/{channelId}")  
477 - @Operation(summary = "请求截图")  
478 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
479 - @Parameter(name = "channelId", description = "通道国标编号", required = true)  
480 - @Parameter(name = "mark", description = "标识", required = false)  
481 - public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId, @RequestParam(required = false) String mark) {  
482 -  
483 - try {  
484 - final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + (mark == null? ".jpg": ("_" + mark + ".jpg"))).toPath());  
485 - resp.setContentType(MediaType.IMAGE_PNG_VALUE);  
486 - ServletOutputStream outputStream = resp.getOutputStream();  
487 - IOUtils.copy(in, resp.getOutputStream());  
488 - in.close();  
489 - outputStream.close();  
490 - } catch (IOException e) {  
491 - resp.setStatus(HttpServletResponse.SC_NOT_FOUND);  
492 - }  
493 - }  
494 -  
495 - /**  
496 - * 查询国标树  
497 - * @param deviceId 设备ID  
498 - * @param parentId 父ID  
499 - * @param page 当前页  
500 - * @param count 每页条数  
501 - * @return 国标设备  
502 - */  
503 - @Operation(summary = "查询国标树")  
504 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
505 - @Parameter(name = "parentId", description = "父级国标编号")  
506 - @Parameter(name = "onlyCatalog", description = "只获取目录")  
507 - @Parameter(name = "page", description = "当前页", required = true)  
508 - @Parameter(name = "count", description = "每页条数", required = true)  
509 - @GetMapping("/tree/{deviceId}")  
510 - public ResponseEntity<PageInfo> getTree(@PathVariable String deviceId,  
511 - @RequestParam(required = false) String parentId,  
512 - @RequestParam(required = false) Boolean onlyCatalog,  
513 - int page, int count){  
514 -  
515 -  
516 - if (page <= 0) {  
517 - page = 1;  
518 - }  
519 - if (onlyCatalog == null) {  
520 - onlyCatalog = false;  
521 - }  
522 -  
523 - List<BaseTree<DeviceChannel>> treeData = deviceService.queryVideoDeviceTree(deviceId, parentId, onlyCatalog);  
524 - if (treeData == null || (page - 1) * count > treeData.size()) {  
525 - PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();  
526 - pageInfo.setPageNum(page);  
527 - pageInfo.setTotal(treeData == null? 0 : treeData.size());  
528 - pageInfo.setSize(0);  
529 - pageInfo.setList(new ArrayList<>());  
530 - return new ResponseEntity<>(pageInfo,HttpStatus.OK);  
531 - }  
532 -  
533 - int toIndex = Math.min(page * count, treeData.size());  
534 - // 处理分页  
535 - List<BaseTree<DeviceChannel>> trees = treeData.subList((page - 1) * count, toIndex);  
536 - PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();  
537 - pageInfo.setPageNum(page);  
538 - pageInfo.setTotal(treeData.size());  
539 - pageInfo.setSize(trees.size());  
540 - pageInfo.setList(trees);  
541 -  
542 - return new ResponseEntity<>(pageInfo,HttpStatus.OK);  
543 - }  
544 -  
545 - /**  
546 - * 查询国标树下的通道  
547 - * @param deviceId 设备ID  
548 - * @param parentId 父ID  
549 - * @param page 当前页  
550 - * @param count 每页条数  
551 - * @return 国标设备  
552 - */  
553 - @Operation(summary = "查询国标树下的通道")  
554 - @Parameter(name = "deviceId", description = "设备国标编号", required = true)  
555 - @Parameter(name = "parentId", description = "父级国标编号")  
556 - @Parameter(name = "page", description = "当前页", required = true)  
557 - @Parameter(name = "count", description = "每页条数", required = true)  
558 - @GetMapping("/tree/channel/{deviceId}")  
559 - public ResponseEntity<PageInfo> getChannelInTreeNode(@PathVariable String deviceId, @RequestParam(required = false) String parentId, int page, int count){  
560 -  
561 - if (page <= 0) {  
562 - page = 1;  
563 - }  
564 -  
565 - List<DeviceChannel> treeData = deviceService.queryVideoDeviceInTreeNode(deviceId, parentId);  
566 - if (treeData == null || (page - 1) * count > treeData.size()) {  
567 - PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();  
568 - pageInfo.setPageNum(page);  
569 - pageInfo.setTotal(treeData == null? 0 : treeData.size());  
570 - pageInfo.setSize(0);  
571 - pageInfo.setList(new ArrayList<>());  
572 - return new ResponseEntity<>(pageInfo,HttpStatus.OK);  
573 - }  
574 -  
575 - int toIndex = Math.min(page * count, treeData.size());  
576 - // 处理分页  
577 - List<DeviceChannel> trees = treeData.subList((page - 1) * count, toIndex);  
578 - PageInfo<DeviceChannel> pageInfo = new PageInfo<>();  
579 - pageInfo.setPageNum(page);  
580 - pageInfo.setTotal(treeData.size());  
581 - pageInfo.setSize(trees.size());  
582 - pageInfo.setList(trees);  
583 -  
584 - return new ResponseEntity<>(pageInfo,HttpStatus.OK);  
585 - } 114 + return storager.queryVideoDeviceList(page, count, null);
  115 + }
  116 +
  117 + /**
  118 + * 分页查询通道数
  119 + *
  120 + * @param deviceId 设备id
  121 + * @param page 当前页
  122 + * @param count 每页条数
  123 + * @param query 查询内容
  124 + * @param online 是否在线 在线 true / 离线 false
  125 + * @param channelType 设备 false/子目录 true
  126 + * @param catalogUnderDevice 是否直属与设备的目录
  127 + * @return 通道列表
  128 + */
  129 + @GetMapping("/devices/{deviceId}/channels")
  130 + @Operation(summary = "分页查询通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
  131 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  132 + @Parameter(name = "page", description = "当前页", required = true)
  133 + @Parameter(name = "count", description = "每页查询数量", required = true)
  134 + @Parameter(name = "query", description = "查询内容")
  135 + @Parameter(name = "online", description = "是否在线")
  136 + @Parameter(name = "channelType", description = "设备/子目录-> false/true")
  137 + @Parameter(name = "catalogUnderDevice", description = "是否直属与设备的目录")
  138 + public PageInfo<DeviceChannel> channels(@PathVariable String deviceId,
  139 + int page, int count,
  140 + @RequestParam(required = false) String query,
  141 + @RequestParam(required = false) Boolean online,
  142 + @RequestParam(required = false) Boolean channelType,
  143 + @RequestParam(required = false) Boolean catalogUnderDevice) {
  144 + if (ObjectUtils.isEmpty(query)) {
  145 + query = null;
  146 + }
  147 +
  148 + return storager.queryChannelsByDeviceId(deviceId, query, channelType, online, catalogUnderDevice, page, count);
  149 + }
  150 +
  151 + /**
  152 + * 同步设备通道
  153 + *
  154 + * @param deviceId 设备id
  155 + * @return
  156 + */
  157 + @Operation(summary = "同步设备通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
  158 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  159 + @GetMapping("/devices/{deviceId}/sync")
  160 + public WVPResult<SyncStatus> devicesSync(@PathVariable String deviceId) {
  161 +
  162 + if (logger.isDebugEnabled()) {
  163 + logger.debug("设备通道信息同步API调用,deviceId:" + deviceId);
  164 + }
  165 + Device device = storager.queryVideoDevice(deviceId);
  166 + boolean status = deviceService.isSyncRunning(deviceId);
  167 + // 已存在则返回进度
  168 + if (status) {
  169 + SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);
  170 + return WVPResult.success(channelSyncStatus);
  171 + }
  172 + deviceService.sync(device);
  173 +
  174 + WVPResult<SyncStatus> wvpResult = new WVPResult<>();
  175 + wvpResult.setCode(0);
  176 + wvpResult.setMsg("开始同步");
  177 + return wvpResult;
  178 + }
  179 +
  180 + /**
  181 + * 移除设备
  182 + *
  183 + * @param deviceId 设备id
  184 + * @return
  185 + */
  186 + @Operation(summary = "移除设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
  187 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  188 + @DeleteMapping("/devices/{deviceId}/delete")
  189 + public String delete(@PathVariable String deviceId) {
  190 +
  191 + if (logger.isDebugEnabled()) {
  192 + logger.debug("设备信息删除API调用,deviceId:" + deviceId);
  193 + }
  194 +
  195 + // 清除redis记录
  196 + boolean isSuccess = deviceService.delete(deviceId);
  197 + if (isSuccess) {
  198 + inviteStreamService.clearInviteInfo(deviceId);
  199 + // 停止此设备的订阅更新
  200 + Set<String> allKeys = dynamicTask.getAllKeys();
  201 + for (String key : allKeys) {
  202 + if (key.startsWith(deviceId)) {
  203 + Runnable runnable = dynamicTask.get(key);
  204 + if (runnable instanceof ISubscribeTask) {
  205 + ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
  206 + subscribeTask.stop(null);
  207 + }
  208 + dynamicTask.stop(key);
  209 + }
  210 + }
  211 + JSONObject json = new JSONObject();
  212 + json.put("deviceId", deviceId);
  213 + return json.toString();
  214 + } else {
  215 + logger.warn("设备信息删除API调用失败!");
  216 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备信息删除API调用失败!");
  217 + }
  218 + }
  219 +
  220 + /**
  221 + * 分页查询子目录通道
  222 + *
  223 + * @param deviceId 通道id
  224 + * @param channelId 通道id
  225 + * @param page 当前页
  226 + * @param count 每页条数
  227 + * @param query 查询内容
  228 + * @param online 是否在线
  229 + * @param channelType 通道类型
  230 + * @return 子通道列表
  231 + */
  232 + @Operation(summary = "分页查询子目录通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
  233 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  234 + @Parameter(name = "channelId", description = "通道国标编号", required = true)
  235 + @Parameter(name = "page", description = "当前页", required = true)
  236 + @Parameter(name = "count", description = "每页查询数量", required = true)
  237 + @Parameter(name = "query", description = "查询内容")
  238 + @Parameter(name = "online", description = "是否在线")
  239 + @Parameter(name = "channelType", description = "设备/子目录-> false/true")
  240 + @GetMapping("/sub_channels/{deviceId}/{channelId}/channels")
  241 + public PageInfo<DeviceChannel> subChannels(@PathVariable String deviceId,
  242 + @PathVariable String channelId,
  243 + int page,
  244 + int count,
  245 + @RequestParam(required = false) String query,
  246 + @RequestParam(required = false) Boolean online,
  247 + @RequestParam(required = false) Boolean channelType) {
  248 +
  249 + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
  250 + if (deviceChannel == null) {
  251 + PageInfo<DeviceChannel> deviceChannelPageResult = new PageInfo<>();
  252 + return deviceChannelPageResult;
  253 + }
  254 +
  255 + return storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);
  256 + }
  257 +
  258 + /**
  259 + * 更新通道信息
  260 + *
  261 + * @param deviceId 设备id
  262 + * @param channel 通道
  263 + * @return
  264 + */
  265 + @Operation(summary = "更新通道信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
  266 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  267 + @Parameter(name = "channel", description = "通道信息", required = true)
  268 + @PostMapping("/channel/update/{deviceId}")
  269 + public void updateChannel(@PathVariable String deviceId, DeviceChannel channel) {
  270 + deviceChannelService.updateChannel(deviceId, channel);
  271 + }
  272 +
  273 + @Operation(summary = "修改通道的码流类型", security = @SecurityRequirement(name = JwtUtils.HEADER))
  274 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  275 + @Parameter(name = "channel", description = "通道信息", required = true)
  276 + @PostMapping("/channel/stream/identification/update/")
  277 + public void updateChannelStreamIdentification(DeviceChannel channel) {
  278 + deviceChannelService.updateChannelStreamIdentification(channel);
  279 + }
  280 +
  281 + /**
  282 + * 修改数据流传输模式
  283 + *
  284 + * @param deviceId 设备id
  285 + * @param streamMode 数据流传输模式
  286 + * @return
  287 + */
  288 + @Operation(summary = "修改数据流传输模式", security = @SecurityRequirement(name = JwtUtils.HEADER))
  289 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  290 + @Parameter(name = "streamMode", description = "数据流传输模式, 取值:" +
  291 + "UDP(udp传输),TCP-ACTIVE(tcp主动模式,暂不支持),TCP-PASSIVE(tcp被动模式)", required = true)
  292 + @PostMapping("/transport/{deviceId}/{streamMode}")
  293 + public void updateTransport(@PathVariable String deviceId, @PathVariable String streamMode) {
  294 + Device device = deviceService.getDevice(deviceId);
  295 + device.setStreamMode(streamMode);
  296 + deviceService.updateCustomDevice(device);
  297 + }
  298 +
  299 + /**
  300 + * 添加设备信息
  301 + *
  302 + * @param device 设备信息
  303 + * @return
  304 + */
  305 + @Operation(summary = "添加设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
  306 + @Parameter(name = "device", description = "设备", required = true)
  307 + @PostMapping("/device/add/")
  308 + public void addDevice(Device device) {
  309 +
  310 + if (device == null || device.getDeviceId() == null) {
  311 + throw new ControllerException(ErrorCode.ERROR400);
  312 + }
  313 +
  314 + // 查看deviceId是否存在
  315 + boolean exist = deviceService.isExist(device.getDeviceId());
  316 + if (exist) {
  317 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备编号已存在");
  318 + }
  319 + deviceService.addDevice(device);
  320 + }
  321 +
  322 + /**
  323 + * 更新设备信息
  324 + *
  325 + * @param device 设备信息
  326 + * @return
  327 + */
  328 + @Operation(summary = "更新设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
  329 + @Parameter(name = "device", description = "设备", required = true)
  330 + @PostMapping("/device/update/")
  331 + public void updateDevice(Device device) {
  332 +
  333 + if (device != null && device.getDeviceId() != null) {
  334 + deviceService.updateCustomDevice(device);
  335 + }
  336 + }
  337 +
  338 + /**
  339 + * 设备状态查询请求API接口
  340 + *
  341 + * @param deviceId 设备id
  342 + */
  343 + @Operation(summary = "设备状态查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
  344 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  345 + @GetMapping("/devices/{deviceId}/status")
  346 + public DeferredResult<ResponseEntity<String>> deviceStatusApi(@PathVariable String deviceId) {
  347 + if (logger.isDebugEnabled()) {
  348 + logger.debug("设备状态查询API调用");
  349 + }
  350 + Device device = storager.queryVideoDevice(deviceId);
  351 + String uuid = UUID.randomUUID().toString();
  352 + String key = DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId;
  353 + DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(2 * 1000L);
  354 + if (device == null) {
  355 + result.setResult(new ResponseEntity(String.format("设备%s不存在", deviceId), HttpStatus.OK));
  356 + return result;
  357 + }
  358 + try {
  359 + cmder.deviceStatusQuery(device, event -> {
  360 + RequestMessage msg = new RequestMessage();
  361 + msg.setId(uuid);
  362 + msg.setKey(key);
  363 + msg.setData(String.format("获取设备状态失败,错误码: %s, %s", event.statusCode, event.msg));
  364 + resultHolder.invokeResult(msg);
  365 + });
  366 + } catch (InvalidArgumentException | SipException | ParseException e) {
  367 + logger.error("[命令发送失败] 获取设备状态: {}", e.getMessage());
  368 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
  369 + }
  370 + result.onTimeout(() -> {
  371 + logger.warn(String.format("获取设备状态超时"));
  372 + // 释放rtpserver
  373 + RequestMessage msg = new RequestMessage();
  374 + msg.setId(uuid);
  375 + msg.setKey(key);
  376 + msg.setData("Timeout. Device did not response to this command.");
  377 + resultHolder.invokeResult(msg);
  378 + });
  379 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, uuid, result);
  380 + return result;
  381 + }
  382 +
  383 + /**
  384 + * 设备报警查询请求API接口
  385 + *
  386 + * @param deviceId 设备id
  387 + * @param startPriority 报警起始级别(可选)
  388 + * @param endPriority 报警终止级别(可选)
  389 + * @param alarmMethod 报警方式条件(可选)
  390 + * @param alarmType 报警类型
  391 + * @param startTime 报警发生起始时间(可选)
  392 + * @param endTime 报警发生终止时间(可选)
  393 + * @return true = 命令发送成功
  394 + */
  395 + @Operation(summary = "设备报警查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
  396 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  397 + @Parameter(name = "startPriority", description = "报警起始级别")
  398 + @Parameter(name = "endPriority", description = "报警终止级别")
  399 + @Parameter(name = "alarmMethod", description = "报警方式条件")
  400 + @Parameter(name = "alarmType", description = "报警类型")
  401 + @Parameter(name = "startTime", description = "报警发生起始时间")
  402 + @Parameter(name = "endTime", description = "报警发生终止时间")
  403 + @GetMapping("/alarm/{deviceId}")
  404 + public DeferredResult<ResponseEntity<String>> alarmApi(@PathVariable String deviceId,
  405 + @RequestParam(required = false) String startPriority,
  406 + @RequestParam(required = false) String endPriority,
  407 + @RequestParam(required = false) String alarmMethod,
  408 + @RequestParam(required = false) String alarmType,
  409 + @RequestParam(required = false) String startTime,
  410 + @RequestParam(required = false) String endTime) {
  411 + if (logger.isDebugEnabled()) {
  412 + logger.debug("设备报警查询API调用");
  413 + }
  414 + Device device = storager.queryVideoDevice(deviceId);
  415 + String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;
  416 + String uuid = UUID.randomUUID().toString();
  417 + try {
  418 + cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {
  419 + RequestMessage msg = new RequestMessage();
  420 + msg.setId(uuid);
  421 + msg.setKey(key);
  422 + msg.setData(String.format("设备报警查询失败,错误码: %s, %s", event.statusCode, event.msg));
  423 + resultHolder.invokeResult(msg);
  424 + });
  425 + } catch (InvalidArgumentException | SipException | ParseException e) {
  426 + logger.error("[命令发送失败] 设备报警查询: {}", e.getMessage());
  427 + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
  428 + }
  429 + DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(3 * 1000L);
  430 + result.onTimeout(() -> {
  431 + logger.warn(String.format("设备报警查询超时"));
  432 + // 释放rtpserver
  433 + RequestMessage msg = new RequestMessage();
  434 + msg.setId(uuid);
  435 + msg.setKey(key);
  436 + msg.setData("设备报警查询超时");
  437 + resultHolder.invokeResult(msg);
  438 + });
  439 + resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, uuid, result);
  440 + return result;
  441 + }
  442 +
  443 +
  444 + @GetMapping("/{deviceId}/sync_status")
  445 + @Operation(summary = "获取通道同步进度", security = @SecurityRequirement(name = JwtUtils.HEADER))
  446 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  447 + public WVPResult<SyncStatus> getSyncStatus(@PathVariable String deviceId) {
  448 + SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);
  449 + WVPResult<SyncStatus> wvpResult = new WVPResult<>();
  450 + if (channelSyncStatus == null) {
  451 + wvpResult.setCode(-1);
  452 + wvpResult.setMsg("同步尚未开始");
  453 + } else {
  454 + wvpResult.setCode(ErrorCode.SUCCESS.getCode());
  455 + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
  456 + wvpResult.setData(channelSyncStatus);
  457 + if (channelSyncStatus.getErrorMsg() != null) {
  458 + wvpResult.setMsg(channelSyncStatus.getErrorMsg());
  459 + }
  460 + }
  461 + return wvpResult;
  462 + }
  463 +
  464 + @GetMapping("/{deviceId}/subscribe_info")
  465 + @Operation(summary = "获取设备的订阅状态", security = @SecurityRequirement(name = JwtUtils.HEADER))
  466 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  467 + public WVPResult<Map<String, Integer>> getSubscribeInfo(@PathVariable String deviceId) {
  468 + Set<String> allKeys = dynamicTask.getAllKeys();
  469 + Map<String, Integer> dialogStateMap = new HashMap<>();
  470 + for (String key : allKeys) {
  471 + if (key.startsWith(deviceId)) {
  472 + ISubscribeTask subscribeTask = (ISubscribeTask) dynamicTask.get(key);
  473 + if (subscribeTask instanceof CatalogSubscribeTask) {
  474 + dialogStateMap.put("catalog", 1);
  475 + } else if (subscribeTask instanceof MobilePositionSubscribeTask) {
  476 + dialogStateMap.put("mobilePosition", 1);
  477 + }
  478 + }
  479 + }
  480 + WVPResult<Map<String, Integer>> wvpResult = new WVPResult<>();
  481 + wvpResult.setCode(0);
  482 + wvpResult.setData(dialogStateMap);
  483 + return wvpResult;
  484 + }
  485 +
  486 + @GetMapping("/snap/{deviceId}/{channelId}")
  487 + @Operation(summary = "请求截图")
  488 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  489 + @Parameter(name = "channelId", description = "通道国标编号", required = true)
  490 + @Parameter(name = "mark", description = "标识", required = false)
  491 + public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId, @RequestParam(required = false) String mark) {
  492 +
  493 + try {
  494 + final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + (mark == null ? ".jpg" : ("_" + mark + ".jpg"))).toPath());
  495 + resp.setContentType(MediaType.IMAGE_PNG_VALUE);
  496 + ServletOutputStream outputStream = resp.getOutputStream();
  497 + IOUtils.copy(in, resp.getOutputStream());
  498 + in.close();
  499 + outputStream.close();
  500 + } catch (IOException e) {
  501 + resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
  502 + }
  503 + }
  504 +
  505 + /**
  506 + * 查询国标树
  507 + *
  508 + * @param deviceId 设备ID
  509 + * @param parentId 父ID
  510 + * @param page 当前页
  511 + * @param count 每页条数
  512 + * @return 国标设备
  513 + */
  514 + @Operation(summary = "查询国标树")
  515 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  516 + @Parameter(name = "parentId", description = "父级国标编号")
  517 + @Parameter(name = "onlyCatalog", description = "只获取目录")
  518 + @Parameter(name = "page", description = "当前页", required = true)
  519 + @Parameter(name = "count", description = "每页条数", required = true)
  520 + @GetMapping("/tree/{deviceId}")
  521 + public ResponseEntity<PageInfo> getTree(@PathVariable String deviceId,
  522 + @RequestParam(required = false) String parentId,
  523 + @RequestParam(required = false) Boolean onlyCatalog,
  524 + int page, int count) {
  525 +
  526 +
  527 + if (page <= 0) {
  528 + page = 1;
  529 + }
  530 + if (onlyCatalog == null) {
  531 + onlyCatalog = false;
  532 + }
  533 +
  534 + List<BaseTree<DeviceChannel>> treeData = deviceService.queryVideoDeviceTree(deviceId, parentId, onlyCatalog);
  535 + if (treeData == null || (page - 1) * count > treeData.size()) {
  536 + PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();
  537 + pageInfo.setPageNum(page);
  538 + pageInfo.setTotal(treeData == null ? 0 : treeData.size());
  539 + pageInfo.setSize(0);
  540 + pageInfo.setList(new ArrayList<>());
  541 + return new ResponseEntity<>(pageInfo, HttpStatus.OK);
  542 + }
  543 +
  544 + int toIndex = Math.min(page * count, treeData.size());
  545 + // 处理分页
  546 + List<BaseTree<DeviceChannel>> trees = treeData.subList((page - 1) * count, toIndex);
  547 + PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();
  548 + pageInfo.setPageNum(page);
  549 + pageInfo.setTotal(treeData.size());
  550 + pageInfo.setSize(trees.size());
  551 + pageInfo.setList(trees);
  552 +
  553 + return new ResponseEntity<>(pageInfo, HttpStatus.OK);
  554 + }
  555 +
  556 + /**
  557 + * 查询国标树下的通道
  558 + *
  559 + * @param deviceId 设备ID
  560 + * @param parentId 父ID
  561 + * @param page 当前页
  562 + * @param count 每页条数
  563 + * @return 国标设备
  564 + */
  565 + @Operation(summary = "查询国标树下的通道")
  566 + @Parameter(name = "deviceId", description = "设备国标编号", required = true)
  567 + @Parameter(name = "parentId", description = "父级国标编号")
  568 + @Parameter(name = "page", description = "当前页", required = true)
  569 + @Parameter(name = "count", description = "每页条数", required = true)
  570 + @GetMapping("/tree/channel/{deviceId}")
  571 + public ResponseEntity<PageInfo> getChannelInTreeNode(@PathVariable String deviceId, @RequestParam(required = false) String parentId, int page, int count) {
  572 +
  573 + if (page <= 0) {
  574 + page = 1;
  575 + }
  576 +
  577 + List<DeviceChannel> treeData = deviceService.queryVideoDeviceInTreeNode(deviceId, parentId);
  578 + if (treeData == null || (page - 1) * count > treeData.size()) {
  579 + PageInfo<BaseTree<DeviceChannel>> pageInfo = new PageInfo<>();
  580 + pageInfo.setPageNum(page);
  581 + pageInfo.setTotal(treeData == null ? 0 : treeData.size());
  582 + pageInfo.setSize(0);
  583 + pageInfo.setList(new ArrayList<>());
  584 + return new ResponseEntity<>(pageInfo, HttpStatus.OK);
  585 + }
  586 +
  587 + int toIndex = Math.min(page * count, treeData.size());
  588 + // 处理分页
  589 + List<DeviceChannel> trees = treeData.subList((page - 1) * count, toIndex);
  590 + PageInfo<DeviceChannel> pageInfo = new PageInfo<>();
  591 + pageInfo.setPageNum(page);
  592 + pageInfo.setTotal(treeData.size());
  593 + pageInfo.setSize(trees.size());
  594 + pageInfo.setList(trees);
  595 +
  596 + return new ResponseEntity<>(pageInfo, HttpStatus.OK);
  597 + }
  598 +
  599 + @Operation(summary = "根据车辆编号查询通道信息")
  600 + @Parameter(name = "carNo", description = "车辆编号", required = true)
  601 + @GetMapping("/query/channel/carNo/{carNo}")
  602 + public WVPResult<List<DeviceChannel>> queryDeviceChannelByCarNo(@PathVariable("carNo") String carNo) {
  603 + List<DeviceChannel> deviceChannels = deviceService.queryDeviceChannelByCarNo(carNo);
  604 + WVPResult<List<DeviceChannel>> wvpResult = new WVPResult<>();
  605 + wvpResult.setCode(0);
  606 + wvpResult.setData(deviceChannels);
  607 +
  608 + return wvpResult;
  609 + }
586 } 610 }
src/main/resources/application-local.yml
@@ -19,7 +19,7 @@ spring: @@ -19,7 +19,7 @@ spring:
19 # [可选] 数据库 DB 19 # [可选] 数据库 DB
20 database: 7 20 database: 7
21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 21 # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
22 -# password: guzijian 22 + # password: guzijian
23 # [可选] 超时时间 23 # [可选] 超时时间
24 timeout: 10000 24 timeout: 10000
25 # mysql数据源 25 # mysql数据源
@@ -30,7 +30,7 @@ spring: @@ -30,7 +30,7 @@ spring:
30 master: 30 master:
31 type: com.zaxxer.hikari.HikariDataSource 31 type: com.zaxxer.hikari.HikariDataSource
32 driver-class-name: com.mysql.cj.jdbc.Driver 32 driver-class-name: com.mysql.cj.jdbc.Driver
33 - url: jdbc:mysql://127.0.0.1:3306/latest_wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true 33 + url: jdbc:mysql://192.168.169.100:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
34 username: root 34 username: root
35 password: guzijian 35 password: guzijian
36 hikari: 36 hikari:
@@ -60,9 +60,10 @@ sip: @@ -60,9 +60,10 @@ sip:
60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 60 # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4
61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 61 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的
62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 62 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。
63 - ip: 192.169.1.31 63 + ip: 192.169.1.89
64 # [可选] 28181服务监听的端口 64 # [可选] 28181服务监听的端口
65 port: 5060 65 port: 5060
  66 +
66 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) 67 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
67 # 后两位为行业编码,定义参照附录D.3 68 # 后两位为行业编码,定义参照附录D.3
68 # 3701020049标识山东济南历下区 信息行业接入 69 # 3701020049标识山东济南历下区 信息行业接入
@@ -77,29 +78,29 @@ sip: @@ -77,29 +78,29 @@ sip:
77 78
78 #zlm 默认服务器配置 79 #zlm 默认服务器配置
79 media: 80 media:
80 - id: cQ5byeSBKP2INt6l 81 + id: guzijian1
81 # [必须修改] zlm服务器的内网IP 82 # [必须修改] zlm服务器的内网IP
82 - ip: 192.169.1.31 83 + ip: 192.168.169.100
83 # [必须修改] zlm服务器的http.port 84 # [必须修改] zlm服务器的http.port
84 - http-port: 80 85 + http-port: 1091
85 # [可选] 返回流地址时的ip,置空使用 media.ip 86 # [可选] 返回流地址时的ip,置空使用 media.ip
86 - stream-ip: 192.169.1.31 87 + stream-ip: 192.168.169.100
87 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip 88 # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
88 - sdp-ip: 192.169.1.31 89 + sdp-ip: 192.168.169.100
89 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip 90 # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
90 - hook-ip: 192.169.1.31 91 + hook-ip: 192.169.1.89
91 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 92 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置
92 http-ssl-port: 443 93 http-ssl-port: 443
93 # [可选] zlm服务器的hook.admin_params=secret 94 # [可选] zlm服务器的hook.admin_params=secret
94 - secret: ZLh24VioqaKqxiihBJ80ny60NuWpVe62 95 + secret: RPorcBlIw26uHGnEHYGesIYyFDXpgjkP
95 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 96 # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
96 rtp: 97 rtp:
97 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 98 # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
98 enable: true 99 enable: true
99 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 100 # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
100 - port-range: 50000,50300 # 端口范围 101 + port-range: 60000,60300 # 端口范围
101 # [可选] 国标级联在此范围内选择端口发送媒体流, 102 # [可选] 国标级联在此范围内选择端口发送媒体流,
102 - send-port-range: 50000,50300 # 端口范围 103 + send-port-range: 60000,60300 # 端口范围
103 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 104 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
104 record-assist-port: 18081 105 record-assist-port: 18081
105 # [根据业务需求配置] 106 # [根据业务需求配置]
@@ -111,11 +112,11 @@ user-settings: @@ -111,11 +112,11 @@ user-settings:
111 # 设备/通道状态变化时发送消息 112 # 设备/通道状态变化时发送消息
112 device-status-notify: true 113 device-status-notify: true
113 # 推流直播是否录制 114 # 推流直播是否录制
114 -# record-push-live: true 115 + # record-push-live: true
115 # 是否开启接口鉴权 116 # 是否开启接口鉴权
116 -# interface-authentication: false 117 + # interface-authentication: false
117 # 国标是否录制 118 # 国标是否录制
118 -# record-sip: true 119 + # record-sip: true
119 # 等待音视频编码信息再返回, true: 可以根据编码选择合适的播放器,false: 可以更快点播 120 # 等待音视频编码信息再返回, true: 可以根据编码选择合适的播放器,false: 可以更快点播
120 # wait-track: true 121 # wait-track: true
121 # [可选] 日志配置, 一般不需要改 122 # [可选] 日志配置, 一般不需要改
web_src/config/index.js
@@ -11,14 +11,14 @@ module.exports = { @@ -11,14 +11,14 @@ module.exports = {
11 assetsPublicPath: "/", 11 assetsPublicPath: "/",
12 proxyTable: { 12 proxyTable: {
13 "/debug": { 13 "/debug": {
14 - target: "http://61.169.120.202:18089", 14 + target: "http://192.169.1.89:18080",
15 changeOrigin: true, 15 changeOrigin: true,
16 pathRewrite: { 16 pathRewrite: {
17 "^/debug": "/", 17 "^/debug": "/",
18 }, 18 },
19 }, 19 },
20 "/static/snap": { 20 "/static/snap": {
21 - target: "http://61.169.120.202:18089", 21 + target: "http://192.169.1.89:18080",
22 changeOrigin: true, 22 changeOrigin: true,
23 // pathRewrite: { 23 // pathRewrite: {
24 // '^/static/snap': '/static/snap' 24 // '^/static/snap': '/static/snap'
web_src/src/components/dialog/deviceEdit.vue
@@ -59,6 +59,12 @@ @@ -59,6 +59,12 @@
59 <el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox> 59 <el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox>
60 <el-checkbox label="收到ACK后发流" v-model="form.broadcastPushAfterAck" style="float: left"></el-checkbox> 60 <el-checkbox label="收到ACK后发流" v-model="form.broadcastPushAfterAck" style="float: left"></el-checkbox>
61 </el-form-item> 61 </el-form-item>
  62 +
  63 + <el-form-item label="车辆编号" prop="carNo">
  64 + <el-input v-model="form.carNo" clearable></el-input>
  65 + </el-form-item>
  66 +
  67 +
62 <el-form-item> 68 <el-form-item>
63 <div style="float: right;"> 69 <div style="float: right;">
64 <el-button type="primary" @click="onSubmit">确认</el-button> 70 <el-button type="primary" @click="onSubmit">确认</el-button>
web_src/static/js/config.js
1 -window.baseUrl = "http://61.169.120.202:18089"; 1 +window.baseUrl = "http://192.169.1.89:18080";
2 2
3 // map组件全局参数, 注释此内容可以关闭地图功能 3 // map组件全局参数, 注释此内容可以关闭地图功能
4 window.mapParam = { 4 window.mapParam = {
数据库/ddl/DDL.sql 0 → 100644
  1 +ALTER TABLE wvp_device ADD car_No varchar(30) NULL COMMENT '车辆编号';
  2 +