Compare commits

...

5 Commits

Author SHA1 Message Date
阿斌
f96458f108
Pre Merge pull request !36 from 阿斌/N/A 2026-01-13 09:15:45 +00:00
lin
f396f5f29e 优化设备状态查询 2026-01-13 17:15:29 +08:00
lin
bca77f79cc 优化注销判定,主动注销不再确定状态 2026-01-13 16:25:36 +08:00
lin
8c54895c47 去除过期文件,修复接口文档分组 2026-01-13 13:06:22 +08:00
阿斌
da98101aac
update src/main/resources/civilCode.csv.
行政规划错误。江苏南通海门市,修改为海门区,浙江杭州删除下城区、江干区,新增钱塘区,临平区

Signed-off-by: 阿斌 <38912748@qq.com>
2024-12-15 08:58:42 +00:00
14 changed files with 41 additions and 162 deletions

View File

@ -1,91 +0,0 @@
#!/bin/bash
######################################################
# Copyright 2019 Pham Ngoc Hoai
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Repo: https://github.com/tyrion9/spring-boot-startup-script
#
######### PARAM ######################################
JAVA_OPT=-Xmx1024m
JARFILE=`ls -1r *.jar 2>/dev/null | head -n 1`
PID_FILE=pid.file
RUNNING=N
PWD=`pwd`
######### DO NOT MODIFY ########
if [ -f $PID_FILE ]; then
PID=`cat $PID_FILE`
if [ ! -z "$PID" ] && kill -0 $PID 2>/dev/null; then
RUNNING=Y
fi
fi
start()
{
if [ $RUNNING == "Y" ]; then
echo "Application already started"
else
if [ -z "$JARFILE" ]
then
echo "ERROR: jar file not found"
else
nohup java $JAVA_OPT -Djava.security.egd=file:/dev/./urandom -jar $PWD/$JARFILE > nohup.out 2>&1 &
echo $! > $PID_FILE
echo "Application $JARFILE starting..."
tail -f nohup.out
fi
fi
}
stop()
{
if [ $RUNNING == "Y" ]; then
kill -9 $PID
rm -f $PID_FILE
echo "Application stopped"
else
echo "Application not running"
fi
}
restart()
{
stop
start
}
case "$1" in
'start')
start
;;
'stop')
stop
;;
'restart')
restart
;;
*)
echo "Usage: $0 { start | stop | restart }"
exit 1
;;
esac
exit 0

View File

@ -1,20 +0,0 @@
#!/bin/bash
# 获取当前日期并格式化为 YYYY-MM-DD 的形式
current_date=$(date +"%Y-%m-%d")
mkdir -p "$current_date"/数据库
cp -r ./数据库/2.7.3 "$current_date"/数据库
cp src/main/resources/配置详情.yml "$current_date"
cp src/main/resources/application-dev.yml "$current_date"/application.yml
cp ./target/wvp-pro-*.jar "$current_date"
zip -r "$current_date".zip "$current_date"
rm -rf "$current_date"
exit 0

View File

@ -213,17 +213,12 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.6</version>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.8.0</version>
<version>2.8.5</version>
</dependency>
<dependency>

View File

@ -7,12 +7,12 @@ import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
/**
* @author lin
@ -39,7 +39,7 @@ public class SpringDocConfig {
.info(new Info().title("WVP-PRO 接口文档")
.contact(contact)
.description("开箱即用的28181协议视频平台。 <br/>" +
"1. 打开<a href='/doc.html#/1.%20全部/用户管理/login_1'>登录</a>接口" +
"1. 打开<a href='/doc.html#/1.%20全部/用户管理/login'>登录</a>接口" +
" 登录成功后返回AccessToken。 <br/>" +
"2. 填写到AccessToken到参数值 <a href='/doc.html#/Authorize/1.%20全部'>Token配置</a> <br/>" +
"后续接口就可以直接测试了")

View File

@ -26,7 +26,7 @@ public interface IDeviceService {
* 设备下线
* @param deviceId 设备编号
*/
void offline(String deviceId, String reason);
void offline(String deviceId, String reason, boolean check);
/**
* 添加目录订阅

View File

@ -274,7 +274,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
private void deviceStatusExpire(String deviceId, SipTransactionInfo transactionInfo) {
log.info("[设备状态] 到期, 编号: {}", deviceId);
offline(deviceId, "保活到期");
offline(deviceId, "保活到期", true);
}
@Override
@ -383,7 +383,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
@Override
@Transactional
public void offline(String deviceId, String reason) {
public void offline(String deviceId, String reason, boolean check) {
Device device = getDeviceByDeviceIdFromDb(deviceId);
if (device == null) {
log.warn("[设备不存在] device{}", deviceId);
@ -391,7 +391,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
}
// 主动查询设备状态, 没有HostAddress无法发送请求可能是手动添加的设备
if (device.getHostAddress() != null) {
if (check && device.getHostAddress() != null) {
Boolean deviceStatus = getDeviceStatus(device);
if (deviceStatus != null && deviceStatus) {
log.info("[设备离线] 主动探测发现设备在线,暂不处理 device{}", deviceId);
@ -471,7 +471,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
}
if (!deviceStatusTaskRunner.containsKey(device.getDeviceId())) {
log.debug("[状态丢失] 执行设备离线, 编号: {},", device.getDeviceId());
offline(device.getDeviceId(), "");
offline(device.getDeviceId(), "", true);
}
}
}
@ -1202,7 +1202,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
if ("ONLINE".equalsIgnoreCase(data.trim())) {
online(device, null);
}else {
offline(device.getDeviceId(), "设备状态查询结果:" + data.trim());
offline(device.getDeviceId(), "设备状态查询结果:" + data.trim(), true);
}
if (callback != null) {
callback.run(code, msg, data);

View File

@ -82,7 +82,7 @@ public interface ISIPCommanderForPlatform {
* @param fromTag
* @return
*/
void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, boolean status) throws SipException, InvalidArgumentException, ParseException;
void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, Boolean status) throws SipException, InvalidArgumentException, ParseException;
/**
* 向上级回复移动位置订阅消息

View File

@ -329,22 +329,29 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
* @return
*/
@Override
public void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, boolean status) throws SipException, InvalidArgumentException, ParseException {
public void deviceStatusResponse(Platform parentPlatform, String channelId, String sn, String fromTag, Boolean status) throws SipException, InvalidArgumentException, ParseException {
if (parentPlatform == null) {
return ;
}
String statusStr = (status)?"ONLINE":"OFFLINE";
String statusStr = null;
if (status != null) {
statusStr = (status)?"ONLINE":"OFFLINE";
}
String characterSet = parentPlatform.getCharacterSet();
StringBuffer deviceStatusXml = new StringBuffer(600);
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
.append("<Response>\r\n")
.append("<CmdType>DeviceStatus</CmdType>\r\n")
.append("<SN>" +sn + "</SN>\r\n")
.append("<DeviceID>" + channelId + "</DeviceID>\r\n")
.append("<Result>OK</Result>\r\n")
.append("<Online>"+statusStr+"</Online>\r\n")
.append("<Status>OK</Status>\r\n")
.append("</Response>\r\n");
.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
if (statusStr == null) {
deviceStatusXml.append("<Result>ERROR</Result>\r\n");
}else {
deviceStatusXml.append("<Result>OK</Result>\r\n")
.append("<Online>"+statusStr+"</Online>\r\n")
.append("<Status>OK</Status>\r\n");
}
deviceStatusXml.append("</Response>\r\n");
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());

View File

@ -117,7 +117,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
device.setRegisterTime(DateUtil.getNow());
deviceService.online(device, null);
} else {
deviceService.offline(deviceId, "主动注销");
deviceService.offline(deviceId, "主动注销", false);
}
return;
}else {
@ -228,7 +228,7 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
deviceService.online(device, sipTransactionInfo);
} else {
log.info("[注销成功] deviceId: {}->{}", deviceId, requestAddress);
deviceService.offline(deviceId, "主动注销");
deviceService.offline(deviceId, "主动注销", false);
}
} catch (SipException | NoSuchAlgorithmException | ParseException e) {
log.error("未处理的异常 ", e);

View File

@ -86,14 +86,14 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
} else if (CmdType.CATALOG.equals(cmd)) {
processNotifyCatalogList(request, rootElement);
} else {
log.info("接收到消息:" + cmd);
log.info("接收到消息:{}", cmd);
Response response = getMessageFactory().createResponse(200, request);
if (response != null) {
ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
response.setExpires(expireHeader);
}
log.info("response : " + response);
log.info("response : {}", response);
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
}
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
@ -126,9 +126,6 @@ public class SubscribeRequestProcessor extends SIPRequestProcessorParent impleme
.append("<DeviceID>").append(deviceId).append("</DeviceID>\r\n")
.append("<Result>OK</Result>\r\n")
.append("</Response>\r\n");
try {
int expires = request.getExpires().getExpires();
SIPResponse response = responseXmlAck(request, resultXml.toString(), platform, expires);

View File

@ -73,7 +73,13 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i
}
CommonGBChannel channel= channelService.queryOneWithPlatform(platform.getId(), channelId);
if (channel ==null){
log.error("[平台没有该通道的使用权限]:platformId"+platform.getServerGBId()+" deviceID:"+channelId);
log.error("[平台没有该通道的使用权限]:platformId: {} deviceID:{}", platform.getServerGBId(), channelId);
// 上级平台查询本平台状态
try {
cmderFroPlatform.deviceStatusResponse(platform, channelId, sn, fromHeader.getTag(), null);
} catch (SipException | InvalidArgumentException | ParseException e) {
log.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage());
}
return;
}
try {

View File

@ -861,7 +861,7 @@
320623,如东县,3206
320681,启东市,3206
320682,如皋市,3206
320684,海门,3206
320684,海门,3206
320685,海安市,3206
3207,连云港市,32
320703,连云区,3207
@ -918,8 +918,6 @@
33,浙江省,
3301,杭州市,33
330102,上城区,3301
330103,下城区,3301
330104,江干区,3301
330105,拱墅区,3301
330106,西湖区,3301
330108,滨江区,3301
@ -927,6 +925,8 @@
330110,余杭区,3301
330111,富阳区,3301
330112,临安区,3301
330113,临平区,3301
330114,钱塘区,3301
330122,桐庐县,3301
330127,淳安县,3301
330182,建德市,3301

1 编号 名称 上级
861 320623 如东县 3206
862 320681 启东市 3206
863 320682 如皋市 3206
864 320684 海门市 海门区 3206
865 320685 海安市 3206
866 3207 连云港市 32
867 320703 连云区 3207
918 33 浙江省
919 3301 杭州市 33
920 330102 上城区 3301
330103 下城区 3301
330104 江干区 3301
921 330105 拱墅区 3301
922 330106 西湖区 3301
923 330108 滨江区 3301
925 330110 余杭区 3301
926 330111 富阳区 3301
927 330112 临安区 3301
928 330113 临平区 3301
929 330114 钱塘区 3301
930 330122 桐庐县 3301
931 330127 淳安县 3301
932 330182 建德市 3301

15
zlm.md
View File

@ -1,15 +0,0 @@
1. 增加接口用来返回hook调用耗时。
参数: sn
返回值: hook耗时
功能: zlm收到调用后立即调用心跳hookhook中携带sn信息 zlm收到hook返回后计算此次hook的耗时然后返回耗时
用途: 1. 可以用来检测hook配置是否正常
2. 检测wvp与zlm连接的健康程度
2. 增加接口查询loadMP4File的录像播放位置
参数: app steam
返回: 当前播放的hook位置
功能: zlm收到请求后查询流的seek位置并返回
用途: 1. 获取当前播放位置,可以在页面同步显示时间
2. 用来时快进五秒 快退五秒类似的操作
3. loadMP4File扩展 增加默认seek值和默认倍速开始时直接从这个位置开始并使用指定的倍速
4. 支持下载指定取件的mp4文件这个区间可能包括多个文件和文件的一部分。
5. 希望seek接口和倍速接口可以去除schema的必选作为可选项不传则默认全部