diff --git a/pom.xml b/pom.xml index 26b9ad7..1f8d154 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,7 @@ 5.7.14 5.3.39 3.5.1 + 20.0 @@ -235,8 +236,8 @@ smartFishingPort-system smartFishingPort-common smartFishingPort-base - smartFishingPort-kechuang smartFishingPort-solr + smartFishingPort-kechuang pom diff --git a/smartFishingPort-admin/src/main/java/com/ltgk/smartFishingPort/SmartFishingPortApplication.java b/smartFishingPort-admin/src/main/java/com/ltgk/smartFishingPort/SmartFishingPortApplication.java index 59486b4..d76fd73 100644 --- a/smartFishingPort-admin/src/main/java/com/ltgk/smartFishingPort/SmartFishingPortApplication.java +++ b/smartFishingPort-admin/src/main/java/com/ltgk/smartFishingPort/SmartFishingPortApplication.java @@ -3,6 +3,8 @@ package com.ltgk.smartFishingPort; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; /** * 启动程序 @@ -10,6 +12,8 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; * @author ltgk */ @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +@EnableAspectJAutoProxy +@EnableScheduling public class SmartFishingPortApplication { public static void main(String[] args) diff --git a/smartFishingPort-admin/src/main/resources/application-druid.yml b/smartFishingPort-admin/src/main/resources/application-druid.yml index c66f155..81981ad 100644 --- a/smartFishingPort-admin/src/main/resources/application-druid.yml +++ b/smartFishingPort-admin/src/main/resources/application-druid.yml @@ -1,18 +1,21 @@ # 数据源配置 spring: + data: + solr: + host: http://198.16.74.212:8983/solr datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: # 主库数据源 -# master: -# url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 -# username: root -# password: password + # master: + # url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + # username: root + # password: password master: - url: jdbc:mysql://119.167.138.11:3306/smart_fishing_port?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: ltgk - password: litugaoke01! + url: jdbc:mysql://119.167.138.11:3306/smart_fishing_port?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: ltgk + password: litugaoke01! # 从库数据源 slave: # 从数据源开关/默认关闭 @@ -62,4 +65,47 @@ spring: merge-sql: true wall: config: - multi-statement-allow: true \ No newline at end of file + multi-statement-allow: true +url: + picFile: http://198.16.74.209:6060 +sdk: + loginDHUrl: http://192.168.1.18:6450/dhsdk/rest/sdk/init + attachTrafficDHUrl: http://192.168.1.18:6450/dhsdk/rest/sdk/attachTraffic + attachAlarmChanDHByAccountUrl: http://localhost:6450/dhsdk/rest/sdk/attachAlarmChanByAccount + attachAlarmChanHKByAccountUrl: http://localhost:6350/hksdk/rest/sdk/attachAlarmChanByAccount + hk: + getPtzCfgUrl: http://198.16.74.211:6350/hksdk/rest/sdk/getPtzCfg + setPtzCfgUrl: http://198.16.74.211:6350/hksdk/rest/sdk/setPtzCfg + setupAlarmChanUrl: http://198.16.74.211:6350/hksdk/rest/sdk/setupAlarmChan +file: + base: /file + image: /file/image + kml: /files/kml/ + +sysLog: + logFilePath: file/log/ # 系统操作日志备份文件夹 +path: + rootPath: file/ # 文件存储的跟路径,绝对路径-直接使用,相对路径-项目运行目录下 + filePattern: YYYY-MM/ # 存储目录的格式,日期格式YYYYMMddHHmmss,按照日期格式化来进行,为根目录下的一级 + mysqlhome: J://MYSQL5.7//bin// + sql: ${server.servlet.context-path}/file/sql + +#数据库备份时间间隔 +database: + backup: + interval: 3 # 单位天 +jwt: + tokenKey: Auth + duration: 18000 +drone: + url: http://198.16.74.210:30812/openapi/v0.1/ + key: eyJhbGciOiJIUzUxMiIsImNyaXQiOlsidHlwIiwiYWxnIiwia2lkIl0sImtpZCI6IjU3YmQyNmEwLTYyMDktNGE5My1hNjg4LWY4NzUyYmU1ZDE5MSIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50IjoiIiwiZXhwIjoyMDc1OTQ3NzIyLCJuYmYiOjE3NjA0MTQ5MjIsIm9yZ2FuaXphdGlvbl91dWlkIjoiOWRmMjlmYTgtNGI5OS00MThlLWJhMmQtMGY5ZWY5ZWVlMzkyIiwicHJvamVjdF91dWlkIjoiIiwic3ViIjoiZmgyIiwidXNlcl9pZCI6IjE3NjA0MTQxMDkzNTcwMDI0MjkifQ.DC_aS37W2fkqOjCtfvysDfhTn-4XVn3_IrXBnPD9rICGyrIBKBG3oPldeW_pqele5H_gCn1EgM0KXcbDgvq-dw + url2: http://198.16.74.210:30812/openapi/v0.9/ + url3: http://198.16.74.210:63302/ +rocketmq: + name-server: 198.16.74.211:9876 + producer: + group: collect + topic: point-topic +# 温州大致范围 +geoJson: 119.6203422546387,27.68292003880313;119.800415040,27.962869020;119.948730470,27.999251730;120.132751460,27.999251730;120.305786130,28.011376570;120.375137330,28.144659670;120.337371830,28.336417060;120.321578980,28.378110320;120.312652590,28.425825960;120.336685180,28.440921370;120.4183960,28.574271040;120.443801880,28.592962710;120.490493770,28.58874230;120.568771360,28.547132060;120.628509520,28.584521720;120.701293950,28.619487110;120.747299190,28.62069260;120.797424320,28.596580060;120.957412720,28.520589410;121.098175050,28.544719370;121.168212890,28.518779440;121.259536740,28.41072840;121.242657720,28.38772010;121.222457890,28.374787540;121.214561460,28.349410190;121.210098270,28.325840080;121.202459340,28.273166160;121.153106690,28.266287160;121.149673460,28.214869550;121.139373780,28.153741130;121.058349610,28.038652480;121.127700810,28.013195180;121.260223390,27.99682660;121.198425290,27.827842780;121.18194580,27.72486720;121.254730220,27.610538530;121.140747070,27.414442970;120.886688230,27.004078760;120.40191650,27.137368360;120.252227780,27.372986830;120.0503540,27.315654240;119.766082760,27.286366590;119.6733856201172,27.43455578758766;119.6150207519531,27.59350062636446;119.6126174926758,27.63396131658914;119.6151924133301,27.65935568886939;119.6203422546387,27.68292003880313 \ No newline at end of file diff --git a/smartFishingPort-admin/src/main/resources/application.yml b/smartFishingPort-admin/src/main/resources/application.yml index 93e4fb0..5ac242d 100644 --- a/smartFishingPort-admin/src/main/resources/application.yml +++ b/smartFishingPort-admin/src/main/resources/application.yml @@ -16,7 +16,7 @@ smartFishingPort: # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 - port: 8080 + port: 6061 servlet: # 应用的访问路径 context-path: / @@ -133,4 +133,4 @@ xss: # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 - urlPatterns: /system/*,/monitor/*,/tool/* + urlPatterns: /system/*,/monitor/*,/tool/* \ No newline at end of file diff --git a/smartFishingPort-common/pom.xml b/smartFishingPort-common/pom.xml index 83c4d82..1605c08 100644 --- a/smartFishingPort-common/pom.xml +++ b/smartFishingPort-common/pom.xml @@ -118,8 +118,38 @@ com.baomidou mybatis-plus-boot-starter ${mybatis.plus} + compile + + + org.projectlombok + lombok + + + + com.google.guava + guava + ${guava.version} + + + + + com.alibaba + fastjson + 2.0.53 + + + cn.hutool + hutool-all + 5.8.25 + + + + io.swagger + swagger-models + 1.6.3 + \ No newline at end of file diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/Constants.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/Constants.java index c6a801e..3dff052 100644 --- a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/Constants.java +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/Constants.java @@ -171,4 +171,12 @@ public class Constants */ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", "org.springframework", "org.apache", "com.ltgk.smartFishingPort.common.utils.file", "com.ltgk.smartFishingPort.common.config", "com.ltgk.smartFishingPort.generator" }; + + public static final String SUCCESS_CODE = "0"; + + public static final String CODE = "code"; + + // 默认boole类型 + public final static int FLAG_TRUE = 1; + public final static int FLAG_FALSE = 0; } diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/DroneConstruct.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/DroneConstruct.java new file mode 100644 index 0000000..e555959 --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/DroneConstruct.java @@ -0,0 +1,25 @@ +package com.ltgk.smartFishingPort.common.constant; + +/** + * 司空平台接口地址 + */ +public class DroneConstruct { + public final static String SYSTEM_STATUS = "system_status"; // 司空平台状态 + public final static String PROJECT = "project"; // 获取组织下的项目列表 + public final static String DEVICE = "device"; // 获取项目下的设备列表 + public final static String COMMAND = "device/$command/command";//实时控制指令下发 + public final static String AIRPORT_CAMERA_SWITCH = "device/change-camera"; // 机场相机切换 + public final static String DRONE_CAMERA_SWITCH = "device/change-lens"; // 飞行器相机切换 + public final static String DRONE_CONTROL_OBTAIN = "device/control"; // 获取飞行器控制权 + public final static String DRONE_CONTROL_RELEASE = "device/control"; // 释放飞行器控制权 + public final static String DRONE_WAY_LINE = "wayline"; // 获取航线列表 + public final static String DRONE_WAY_LINE_DETAIL = "wayline/$waylineId"; // 获取航线详情 + public final static String START_LIVE = "live-stream/start"; // 开始直播 + public final static String CREATE_FLIGHT_TASK = "flight-task"; + public final static String CREATE_FLIGHT_TASK_STATUS = "flight-task/$taskUuid/status"; + public final static String GET_FLIGHT_TASK_LIST = "flight-task/list"; + public final static String ONE_TOUCH_TAKEOFF = "task/api/v1/workspaces/$taskUuid/flight-tasks/drone-take-off"; + public final static String DRONE_CONTROL_OBTAIN_V2 = "drc/api/v1/projects/$projUuid/cloud_controls"; // 获取飞行器控制权 + public final static String ADD_STREAM_DETECT_TASK = "add_stream_detect_task"; + public final static String CONTROL_DETECTION = "control_detection"; +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/GlobalConstant.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/GlobalConstant.java new file mode 100644 index 0000000..f17d052 --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/constant/GlobalConstant.java @@ -0,0 +1,13 @@ +package com.ltgk.smartFishingPort.common.constant; + +/** + * @Author: zhouyaoyao + * @Date 2025/2/11 13:19 + * Description: 全局常量 + */ +public class GlobalConstant { + + public static final String SOURCE_TYPE_NAME_DH = "大华"; + public static final String SOURCE_TYPE_NAME_HK = "海康"; + +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/controller/BaseController.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/controller/BaseController.java index 4ac0416..a2c5805 100644 --- a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/controller/BaseController.java +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/controller/BaseController.java @@ -24,25 +24,21 @@ import java.util.List; /** * web层通用数据处理 - * + * * @author ltgk */ -public class BaseController -{ +public class BaseController { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 将前台传递过来的日期格式的字符串,自动转化为Date类型 */ @InitBinder - public void initBinder(WebDataBinder binder) - { + public void initBinder(WebDataBinder binder) { // Date 类型转换 - binder.registerCustomEditor(Date.class, new PropertyEditorSupport() - { + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { @Override - public void setAsText(String text) - { + public void setAsText(String text) { setValue(DateUtils.parseDate(text)); } }); @@ -51,19 +47,23 @@ public class BaseController /** * 设置请求分页数据 */ - protected void startPage() - { + protected void startPage() { PageUtils.startPage(); } + /** + * 设置请求分页数据 + */ + protected void startPage(Integer pageNum, Integer pageSize) { + PageUtils.startPage(pageNum, pageSize); + } + /** * 设置请求排序数据 */ - protected void startOrderBy() - { + protected void startOrderBy() { PageDomain pageDomain = TableSupport.buildPageRequest(); - if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) - { + if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) { String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); PageHelper.orderBy(orderBy); } @@ -72,17 +72,15 @@ public class BaseController /** * 清理分页的线程变量 */ - protected void clearPage() - { + protected void clearPage() { PageUtils.clearPage(); } /** * 响应请求分页数据 */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected TableDataInfo getDataTable(List list) - { + @SuppressWarnings({"rawtypes", "unchecked"}) + protected TableDataInfo getDataTable(List list) { TableDataInfo rspData = new TableDataInfo(); rspData.setCode(HttpStatus.SUCCESS); rspData.setMsg("查询成功"); @@ -94,110 +92,97 @@ public class BaseController /** * 返回成功 */ - public AjaxResult success() - { + public AjaxResult success() { return AjaxResult.success(); } /** * 返回失败消息 */ - public AjaxResult error() - { + public AjaxResult error() { return AjaxResult.error(); } /** * 返回成功消息 */ - public AjaxResult success(String message) - { + public AjaxResult success(String message) { return AjaxResult.success(message); } - + /** * 返回成功消息 */ - public AjaxResult success(Object data) - { + public AjaxResult success(Object data) { return AjaxResult.success(data); } /** * 返回失败消息 */ - public AjaxResult error(String message) - { + public AjaxResult error(String message) { return AjaxResult.error(message); } /** * 返回警告消息 */ - public AjaxResult warn(String message) - { + public AjaxResult warn(String message) { return AjaxResult.warn(message); } /** * 响应返回结果 - * + * * @param rows 影响行数 * @return 操作结果 */ - protected AjaxResult toAjax(int rows) - { + protected AjaxResult toAjax(int rows) { return rows > 0 ? AjaxResult.success() : AjaxResult.error(); } /** * 响应返回结果 - * + * * @param result 结果 * @return 操作结果 */ - protected AjaxResult toAjax(boolean result) - { + protected AjaxResult toAjax(boolean result) { return result ? success() : error(); } /** * 页面跳转 */ - public String redirect(String url) - { + public String redirect(String url) { return StringUtils.format("redirect:{}", url); } /** * 获取用户缓存信息 */ - public LoginUser getLoginUser() - { + public LoginUser getLoginUser() { return SecurityUtils.getLoginUser(); } /** * 获取登录用户id */ - public Long getUserId() - { + public Long getUserId() { return getLoginUser().getUserId(); } /** * 获取登录部门id */ - public Long getDeptId() - { + public Long getDeptId() { return getLoginUser().getDeptId(); } /** * 获取登录用户名 */ - public String getUsername() - { + public String getUsername() { return getLoginUser().getUsername(); } } diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Arguments.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Arguments.java new file mode 100644 index 0000000..3cd2135 --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Arguments.java @@ -0,0 +1,98 @@ +package com.ltgk.smartFishingPort.common.core.domain; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +import java.util.Collection; +import java.util.Objects; + +/** + * @author liutailin + * @date 2019-06-02 9:09. + */ +public final class Arguments { + private Arguments() { + } + + public static boolean isNullOrEmpty(T t) { + return Objects.isNull(t) || isEmpty(t); + } + + public static boolean isEmpty(String s) { + return Strings.isNullOrEmpty(s); + } + + public static boolean isEmpty(T t) { + return t.isEmpty(); + } + + public static boolean notEmpty(String s) { + return !isEmpty(s); + } + + public static boolean notEmpty(T l) { + return Objects.nonNull(l) && !l.isEmpty(); + } + + public static boolean positive(Number n) { + return n.doubleValue() > 0.0D; + } + + public static boolean isPositive(Number n) { + return n != null && n.doubleValue() > 0.0D; + } + + public static boolean negative(Number n) { + return n.doubleValue() < 0.0D; + } + + public static boolean isNegative(Number n) { + return n != null && n.doubleValue() < 0.0D; + } + + public static boolean equalWith(T source, T target) { + return com.google.common.base.Objects.equal(source, target); + } + + public static boolean not(Boolean t) { + Preconditions.checkArgument(Objects.nonNull(t)); + return !t.booleanValue(); + } + + public static boolean isDecimal(String str) { + char[] var1 = str.toCharArray(); + int var2 = var1.length; + + for(int var3 = 0; var3 < var2; ++var3) { + char c = var1[var3]; + if(c < 48 || c > 57) { + return false; + } + } + + return true; + } + + public static boolean isNumberic(String str) { + Boolean dot = false; + char[] var2 = str.toCharArray(); + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + char c = var2[var4]; + if(c == 46 && !dot) { + dot = true; + } else { + if(c == 46) { + return false; + } + + if(c < 48 || c > 57) { + return false; + } + } + } + + return true; + } +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Response.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Response.java new file mode 100644 index 0000000..ba624ae --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/domain/Response.java @@ -0,0 +1,72 @@ +package com.ltgk.smartFishingPort.common.core.domain; + +import com.google.common.base.MoreObjects; +import lombok.Data; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Objects; + +/** + * @author liutailin + * @date 2019-06-02 9:06. + */ +@Data +public class Response implements Serializable { + private static final long serialVersionUID = 1L; + private boolean success; + private T result; + private String msg; + private String code; + + public Response(String code, String msg, boolean success, T result) { + this.code = code; + this.msg = msg; + this.success = success; + this.result = result; + } + + public Response() { + } + + public static Response build(String code, String msg, boolean success, T result) { + return new Response(code,msg,success,result); + } + + public static Response ok(T data) { + return new Response("200","操作成功.",true,data); + } + + public static Response ok() { + return ok((T) null); + } + + public static Response fail(String msg) { + return new Response("500",msg,false,null); + } + + public static Response fail(String code, String msg) { + return new Response(code,msg,false,null); + } + + public static Response or(Boolean flag) { + return flag.booleanValue() ? new Response("200",null,true,"操作成功.") + : new Response("500","操作失败.",false,null); + } + + public static Response or(T t) { + return Objects.nonNull(t) ? new Response("200",null,true,t) + : new Response("200",null,true,null); + } + + public static Response or(T t) { + return Arguments.notEmpty(t) ? new Response("200",null,true,t) + : new Response("200",null,true,null); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("success", this.success).add("result", this.result).add("msg", this.msg).omitNullValues().toString(); + } + +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/redis/RedisCache.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/redis/RedisCache.java index b7367ba..ee43c62 100644 --- a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/redis/RedisCache.java +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/core/redis/RedisCache.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * spring redis 工具类 @@ -262,4 +263,15 @@ public class RedisCache { return redisTemplate.keys(pattern); } + + public List getMByScript(String patternKey) { + Set tempPatternKey = redisTemplate.keys(patternKey); + List valueList = tempPatternKey.stream() + .map(m -> { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.get(m); + }) + .collect(Collectors.toList()); + return valueList; + } } diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/ClassCodes.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/ClassCodes.java new file mode 100644 index 0000000..21c3ebd --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/ClassCodes.java @@ -0,0 +1,59 @@ +package com.ltgk.smartFishingPort.common.enums; + +import java.util.ArrayList; +import java.util.List; + +/** + * 识别类型 + */ +public enum ClassCodes { + SAND_MINING_SHIP("采砂矿石船",140000), + PASSENGER_SHIP("客轮",140001), + CONTAINER_SHIP("集装箱船",140002), + BULK_CARRIER("bulkCargoCarrier",140003), + GENERAL_CARGO_SHIP("普通货船",140004), + FISHING_SHIP("渔船",140005), + //国旗 + FLAG_SHIP("国旗船",140006), + //清洁船 + CLEAN_SHIP("清洁船",140007), + //未封仓 + UNDRESSED_SHIP("未封仓",140008), + // 未挂国旗 + UNDRESSED_FLAG_SHIP("未挂国旗",140009), + NOT_DRESSED_SAVESHIP("未穿救生衣",139000), + DRESSED_SAVESHIP("穿救生衣",139001), + DISCARDED_SHIP("废弃船",111002), + FISHING_FARMING_SHIP("捕鱼养殖",111003); +// SHIP("船",141000), +// FLAG("插旗旗",141001), +// SHIP_NO_FLAG("未插旗船",141002); + private String name; + private int code; + ClassCodes(String name, int code) { + this.name = name; + this.code = code; + } + public String getName() { + return name; + } + public int getCode() { + return code; + } + public static ClassCodes getClassCodesByCode(int code) { + for (ClassCodes classCodes : ClassCodes.values()) { + if (classCodes.getCode() == code) { + return classCodes; + } + } + return null; + } + // 获取所有code 并转为字符串 用逗号隔开 + public static String getAllCode() { + List codes = new ArrayList<>(); + for (ClassCodes value : ClassCodes.values()){ + codes.add(String.valueOf(value.getCode())); + } + return String.join(",", codes); + } +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/DroneToRtmp.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/DroneToRtmp.java new file mode 100644 index 0000000..1ba41af --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/enums/DroneToRtmp.java @@ -0,0 +1,48 @@ +package com.ltgk.smartFishingPort.common.enums; + +public enum DroneToRtmp { + YJM("1581F8HGX254M00A09YQ", "rtmp://198.16.74.210:1936/live/yjm", "rtmp://198.16.74.211/live/livestream/uav01","http://198.16.74.211:18080/live/livestream/uav01.flv"), + + LCSF("1581F8HGX256700A0HNV", "rtmp://198.16.74.210:1936/live/lcsf", "rtmp://198.16.74.211/live/livestream/uav02","http://198.16.74.211:18080/live/livestream/uav02.flv"), + OBMT("1581F8HGX257Q00A0PJT", "rtmp://198.16.74.210:1936/live/obmt", "rtmp://198.16.74.211/live/livestream/uav03","http://198.16.74.211:18080/live/livestream/uav03.flv"); + private String name; + private String srcUrl; + private String dstUrl; + private String httpUrl; + private DroneToRtmp(String name, String srcUrl, String dstUrl, String httpUrl) { + this.name = name; + this.srcUrl = srcUrl; + this.dstUrl = dstUrl; + this.httpUrl = httpUrl; + } + public String getName() { + return name; + } + public String getSrcUrl() { + return srcUrl; + } + public String getDstUrl() { + return dstUrl; + } + public String getHttpUrl() { + return httpUrl; + } + public static DroneToRtmp getRtmpByName(String name) { + for (DroneToRtmp item : DroneToRtmp.values()) { + if (item.getName().equals(name)) { + return item; + } + } + return null; + } + // 查看那么在不在 + public static boolean isExist(String name) { + for (DroneToRtmp item : DroneToRtmp.values()) { + if (item.getName().equals(name)) { + return true; + } + } + return false; + } + +} diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/DateUtils.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/DateUtils.java index 976e765..b1ff24f 100644 --- a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/DateUtils.java +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/DateUtils.java @@ -6,6 +6,7 @@ import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; +import java.time.format.DateTimeFormatter; import java.util.Date; /** @@ -185,4 +186,17 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } + + public static String toDate(String str) { + try { + DateTimeFormatter parsePatterns = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime localDateTime = LocalDateTime.parse(str, parsePatterns); + // 将 LocalDateTime 转换为 ZonedDateTime 并指定时区为 UTC + ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.systemDefault()).withZoneSameInstant(ZoneOffset.UTC); + // 格式化输出为 ISO 8601 格式 + return zonedDateTime.format(DateTimeFormatter.ISO_INSTANT); + } catch (Exception e) { + return null; + } + } } diff --git a/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/MybatisUtil.java b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/MybatisUtil.java new file mode 100644 index 0000000..e38c41a --- /dev/null +++ b/smartFishingPort-common/src/main/java/com/ltgk/smartFishingPort/common/utils/MybatisUtil.java @@ -0,0 +1,68 @@ +package com.ltgk.smartFishingPort.common.utils; + +import com.baomidou.mybatisplus.annotation.SqlCondition; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.springframework.util.StringUtils; + +import java.lang.reflect.Field; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MybatisUtil { + private static Pattern humpPattern = Pattern.compile("[A-Z]"); + + public static QueryWrapper notNullField(T T){ + QueryWrapper wrapper = new QueryWrapper<>(); + for (Field field : T.getClass().getDeclaredFields()) { + field.setAccessible(true); + try { + //序列化 字段不需要查询 + if("serialVersionUID".equals(field.getName())){ + continue; + } + //属性为空,不用查询 + if(field.get(T) == null || StringUtils.isEmpty(field.get(T).toString())){ + continue; + } + //主键 注解TableId + TableId tableId = field.getAnnotation(TableId.class); + if (tableId != null){ + //主键 + wrapper.eq(tableId.value(),field.get(T)); + continue; + } + //数据库中字段名和实体类属性不一致 注解TableField + TableField tableField = field.getAnnotation(TableField.class); + if(tableField != null){ + if(tableField.exist()){ + if (SqlCondition.LIKE.equals(tableField.condition())) { + wrapper.like(tableField.value(),field.get(T)); + } else { + wrapper.eq(tableField.value(),field.get(T)); + } + }// @TableField(exist = false) 不是表中内容 不形成查询条件 + continue; + } + //数据库中字段名和实体类属性一致 + wrapper.eq(humpToLine(field.getName()),field.get(T)); + return wrapper; + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + return wrapper; + } + + public static String humpToLine(String str) { + Matcher matcher = humpPattern.matcher(str); + StringBuffer sb = new StringBuffer(); + while (matcher.find()) { + matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase()); + } + matcher.appendTail(sb); + return sb.toString(); + } + +} diff --git a/smartFishingPort-framework/src/main/java/com/ltgk/smartFishingPort/framework/web/service/SysLoginService.java b/smartFishingPort-framework/src/main/java/com/ltgk/smartFishingPort/framework/web/service/SysLoginService.java index 2433f18..c8e6637 100644 --- a/smartFishingPort-framework/src/main/java/com/ltgk/smartFishingPort/framework/web/service/SysLoginService.java +++ b/smartFishingPort-framework/src/main/java/com/ltgk/smartFishingPort/framework/web/service/SysLoginService.java @@ -6,6 +6,7 @@ import com.ltgk.smartFishingPort.common.constant.UserConstants; import com.ltgk.smartFishingPort.common.core.domain.model.LoginUser; import com.ltgk.smartFishingPort.common.core.redis.RedisCache; import com.ltgk.smartFishingPort.common.exception.ServiceException; +import com.ltgk.smartFishingPort.common.exception.user.*; import com.ltgk.smartFishingPort.common.utils.DateUtils; import com.ltgk.smartFishingPort.common.utils.MessageUtils; import com.ltgk.smartFishingPort.common.utils.StringUtils; diff --git a/smartFishingPort-kechuang/pom.xml b/smartFishingPort-kechuang/pom.xml index 44aee4e..34d179a 100644 --- a/smartFishingPort-kechuang/pom.xml +++ b/smartFishingPort-kechuang/pom.xml @@ -26,6 +26,94 @@ com.ltgk.smartFishingPort smartFishingPort-system + + + + org.springframework.boot + spring-boot-starter-websocket + + + + com.auth0 + java-jwt + 3.4.0 + + + + org.springframework.boot + spring-boot-starter-security + + + org.apache.velocity + velocity + 1.7 + + + org.apache.rocketmq + rocketmq-spring-boot-starter + 2.2.1 + + + org.slf4j + slf4j-log4j12 + + + log4j + log4j + + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + + com.squareup.okhttp3 + okhttp + 3.2.0 + + + org.apache.commons + commons-lang3 + 3.14.0 + + + org.bytedeco + javacv + 1.4.1 + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + com.alibaba + easyexcel + 2.2.10 + + + io.netty + netty-all + + + + com.github.xiaoymin + knife4j-spring-boot-starter + 3.0.3 + + + org.springframework.boot + spring-boot-devtools + runtime + true + + \ No newline at end of file diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneClientCommon.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneClientCommon.java new file mode 100644 index 0000000..8013e18 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneClientCommon.java @@ -0,0 +1,196 @@ +package com.ltgk.smartFishingPort.common; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.TypeReference; +import com.ltgk.smartFishingPort.common.constant.DroneConstruct; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Map; +import java.util.UUID; + +/** + * 无人机客户端连接demo + */ +@Slf4j +@Component +public class DroneClientCommon { + @Value("${drone.key}") + private String droneKey; // 无人机密钥 + @Value("${drone.url}") + private String droneUrl; // 无人机地址 + @Value("${drone.url2}") + private String droneOneTouchTakeoffUrl; // 无人机地址 + @Value("${drone.url3}") + private String startUrl; // 开启算法url + /** + * 获取无人机的uuid + * @return + */ + public static String getDroneUuid(){ + return null; + } + /** + * 获取司空平台状态 + * @return + */ + public DroneResponseBase getDroneSystemStatus(){ + String resp = sendDroneGetRequest(DroneConstruct.SYSTEM_STATUS, null,null); + DroneResponseBase droneResponseBase = JSON.parseObject(resp, new TypeReference() { + }); + return droneResponseBase; + } + /** + * 获取无人机通讯Token + * @return + */ + public static String getDroneToken(){ + return null; + } + /** + * 无人机POST请求 + */ + public String sendDronePostRequest(String url, String param, String uuid){ + HttpRequest post = HttpUtil.createPost(droneUrl + url); + post.header("Content-Type", "application/json"); + post.header("X-User-Token", droneKey);// token + post.header("X-Project-Uuid", uuid);//项目编号 + post.header("X-Language", "zh");// 语言 + post.header("X-Request-Id", UUID.randomUUID().toString());//请求唯一标识 + post.body(param); + try (HttpResponse response = post.execute()) { + if (response.isOk()) { + log.info("sendDronePostRequest -- 发送无人机请求成功,url:{}", url); + String body = response.body(); + return body; + } else { + log.error("sendDronePostRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,response.getStatus()); + } + } catch (Exception e) { + log.error("sendDronePostRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,e.getMessage()); + } + return null; + } + /** + * 无人机GET请求 + */ + public String sendDroneGetRequest(String url, Map param, String uuid){ + HttpRequest get = HttpUtil.createGet(droneUrl + url); + get.header("X-User-Token", droneKey);// token + get.header("X-Project-Uuid", uuid);//项目编号 + get.header("X-Language", "zh");// 语言 + get.header("X-Request-Id", UUID.randomUUID().toString());//请求唯一标识 + if (ObjectUtils.isNotEmpty( param)){ + param.forEach((k,v)->{ + get.form(k,v); + }); + } + try (HttpResponse response = get.execute()) { + if (response.isOk()) { + log.info("sendDroneGetRequest -- 发送无人机请求成功,url:{}", url); + String body = response.body(); + return body; + } else { + log.error("sendDroneGetRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,response.getStatus()); + } + } catch (Exception e) { + log.error("sendDroneGetRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,e.getMessage()); + } + return null; + } + /** + * 无人机一键起降POST请求 + */ + public String sendDroneOneTouchTakeoffPostRequest(String url, String param, String uuid){ + HttpRequest post = HttpUtil.createPost(droneOneTouchTakeoffUrl + url); + post.header("Content-Type", "application/json"); + post.header("X-User-Token", droneKey);// token + post.header("X-Project-Uuid", uuid);//项目编号 + post.header("X-Language", "zh");// 语言 + post.header("X-Request-Id", UUID.randomUUID().toString());//请求唯一标识 + post.body(param); + try (HttpResponse response = post.execute()) { + if (response.isOk()) { + log.info("sendDroneOneTouchTakeoffPostRequest -- 发送无人机请求成功,url:{}", url); + String body = response.body(); + return body; + } else { + log.error("sendDroneOneTouchTakeoffPostRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,response.getStatus()); + } + } catch (Exception e) { + log.error("sendDroneOneTouchTakeoffPostRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,e.getMessage()); + } + return null; + } + public String sendDroneOneTouchTakeoffGetRequest(String url, Map param, String uuid){ + HttpRequest get = HttpUtil.createGet(droneOneTouchTakeoffUrl + url); + get.header("Content-Type", "application/json"); + get.header("X-User-Token", droneKey);// token + get.header("X-Project-Uuid", uuid);//项目编号 + get.header("X-Language", "zh");// 语言 + get.header("X-Request-Id", UUID.randomUUID().toString());//请求唯一标识 + if (ObjectUtils.isNotEmpty( param)){ + param.forEach((k,v)->{ + get.form(k,v); + }); + } + try (HttpResponse response = get.execute()) { + if (response.isOk()) { + log.info("sendDroneOneTouchTakeoffGetRequest -- 发送无人机请求成功,url:{}", url); + String body = response.body(); + return body; + } else { + log.error("sendDroneOneTouchTakeoffGetRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,response.getStatus()); + } + } catch (Exception e) { + log.error("sendDroneOneTouchTakeoffGetRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,e.getMessage()); + } + return null; + } + public String sendDroneOneTouchTakeoffDeleteRequest(String url, String param, String uuid){ + HttpRequest delete = HttpRequest.delete(droneOneTouchTakeoffUrl + url); + delete.header("Content-Type", "application/json"); + delete.header("X-User-Token", droneKey);// token + delete.header("X-Project-Uuid", uuid);//项目编号 + delete.header("X-Language", "zh");// 语言 + delete.header("X-Request-Id", UUID.randomUUID().toString());//请求唯一标识 + delete.body(param); + try (HttpResponse response = delete.execute()) { + if (response.isOk()) { + log.info("sendDroneOneTouchTakeoffDeleteRequest -- 发送无人机请求成功,url:{}", url); + String body = response.body(); + return body; + } else { + log.error("sendDroneOneTouchTakeoffDeleteRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,response.getStatus()); + } + } catch (Exception e) { + log.error("sendDroneOneTouchTakeoffDeleteRequest -- 发送无人机请求失败,url:{},失败原因:{}" , url,e.getMessage()); + } + return null; + } + + public String sendVideoStreamDetectSwitch(String url, String param){ + HttpRequest post = HttpUtil.createPost(startUrl + url); + post.header("Content-Type", "application/json"); + post.body(param); + try (HttpResponse response = post.execute()) { + if (response.isOk()) { + log.info("sendVideoStreamDetectSwitch -- 发送开启算法请求成功,url:{},param:{}", url, param); + String body = response.body(); + return body; + } else { + log.error("sendVideoStreamDetectSwitch -- 发送开启算法请求失败,url:{},失败原因:{},param:{}" , url,response.getStatus(),param); + } + } catch (Exception e) { + log.error("sendVideoStreamDetectSwitch -- 发送开启算法请求失败,url:{},失败原因:{},param:{}" , url,e.getMessage(),param); + } + return null; + } + + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneResponseBase.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneResponseBase.java new file mode 100644 index 0000000..4e56fc8 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/DroneResponseBase.java @@ -0,0 +1,18 @@ +package com.ltgk.smartFishingPort.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class DroneResponseBase { + @JsonProperty("code") + @ApiModelProperty(value = "响应码") + private Integer code; + @JsonProperty("message") + @ApiModelProperty(value = "响应信息") + private String message; + @JsonProperty("data") + @ApiModelProperty(value = "响应数据") + private T data; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/RocketMQConsumer.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/RocketMQConsumer.java new file mode 100644 index 0000000..b860adc --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/common/RocketMQConsumer.java @@ -0,0 +1,146 @@ +package com.ltgk.smartFishingPort.common; + +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.domain.dto.BoatDynamicDto; +import com.ltgk.smartFishingPort.utils.GeoUtils; +import com.ltgk.smartFishingPort.websocket.work.SowWs; +import lombok.extern.slf4j.Slf4j; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.awt.geom.Point2D; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.stream.Collectors; + +/** + * @Author: zhouyaoyao + * @Date 2025/8/6 14:40 + * Description: + */ +@Slf4j +@Component +@RocketMQMessageListener(topic = "point-topic", consumerGroup = "boat-point-get") +public class RocketMQConsumer implements RocketMQListener { + + @Resource + @Qualifier("taskExecutor") + private TaskExecutor taskExecutor; + @Value("${geoJson}") + private String geoJson; + + @Override + public void onMessage(String message) { + try { +// log.info("received message: {}",message); + // 2. 队列提交并行化 + CompletableFuture.allOf( + CompletableFuture.runAsync(() -> this.addListToSaveQue(this.copyDynamicJsonToBoatDynamicDTO(message)), taskExecutor) + ).exceptionally(ex -> { + log.error("队列提交失败", ex); + return null; + }); + } catch (Exception e) { + log.info("消息异常:{}", e.getMessage()); + } + } + + private ConcurrentLinkedDeque saveDataDeque = new ConcurrentLinkedDeque<>(); + + public synchronized boolean addListToSaveQue(BoatDynamicDto entity) { + try { + this.saveDataDeque.offer(entity); + if (this.saveDataDeque.size() > 200) { + this.submitJqQueueDataIfNeeded(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + @Scheduled(fixedRate = 30 * 1000) + public void submitJqQueueDataIfNeeded() { + // 1. 加锁防止并发提交 + synchronized (this) { + sendDynamic(saveDataDeque); + saveDataDeque.clear(); + } + } + + Map globalMap; + + public Map getGlobalMap() { + if (Objects.isNull(globalMap)) { + return Maps.newHashMap(); + } else { + return globalMap; + } + } + + public List getBoatDynamicList() { + if (CollectionUtils.isEmpty(globalMap)) { + return Lists.newArrayList(); + } else { + return globalMap.values().stream().collect(Collectors.toList()); + } + } + + public void setGlobalMap(Map globalMap) { + this.globalMap = globalMap; + } + + public void sendDynamic(ConcurrentLinkedDeque list) { + Map map = list.stream() + .filter(f -> !Objects.isNull(f) && StringUtils.isNotBlank(f.getBoatName())).collect( + Collectors.groupingBy(BoatDynamicDto::getBoatName, Collectors.collectingAndThen( + Collectors.reducing((t1, t2) -> t1.getGpsTime().after(t2.getGpsTime()) ? t1 : t2), Optional::get)) + ); + Map mapTmp = list.stream() + .filter(f -> !Objects.isNull(f) && StringUtils.isNotBlank(f.getBoatName())).collect( + Collectors.groupingBy(BoatDynamicDto::getTerminalCode, Collectors.collectingAndThen( + Collectors.reducing((t1, t2) -> t1.getGpsTime().after(t2.getGpsTime()) ? t1 : t2), Optional::get)) + ); + Map globalMapTmp = getGlobalMap(); + globalMapTmp.putAll(mapTmp); + setGlobalMap(globalMapTmp); + sowWs.sendMessage(new ArrayList<>(map.values())); + } + + @Resource + SowWs sowWs; + + public BoatDynamicDto copyDynamicJsonToBoatDynamicDTO(String dynamicJson) { + if (StringUtils.isBlank(dynamicJson)) { + return null; + } + BoatDynamicDto boatDynamic = JSONObject.parseObject(dynamicJson, BoatDynamicDto.class); + + return boatDynamic; + } + + public boolean pointInPolygon(Double lon, Double lat) { + List points = new ArrayList<>(); + Arrays.asList(geoJson.split(";")).forEach(point -> { + if (StringUtils.isNotBlank(point)) { + Point2D.Double point2D = new Point2D.Double(Double.parseDouble(point.split(",")[0]), Double.parseDouble(point.split(",")[1])); + points.add(point2D); + } + }); + + Point2D.Double point = new Point2D.Double(lon, lat); + return GeoUtils.isInPolygon(point, points); + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/config/TaskExecutorConfig.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/config/TaskExecutorConfig.java new file mode 100644 index 0000000..4fb9763 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/config/TaskExecutorConfig.java @@ -0,0 +1,21 @@ +package com.ltgk.smartFishingPort.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +public class TaskExecutorConfig { + + @Bean("taskExecutor") + public TaskExecutor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(10); + executor.setMaxPoolSize(20); + executor.setQueueCapacity(100); + executor.setThreadNamePrefix("rocketmq-consumer-"); + executor.initialize(); + return executor; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDataController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDataController.java new file mode 100644 index 0000000..6fb59e9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDataController.java @@ -0,0 +1,162 @@ +package com.ltgk.smartFishingPort.controller; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.ltgk.smartFishingPort.common.constant.Constants; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.common.core.redis.RedisCache; +import com.ltgk.smartFishingPort.domain.dto.BoatDynamicDto; +import com.ltgk.smartFishingPort.domain.entity.BoatData; +import com.ltgk.smartFishingPort.domain.vo.CurrentAisDynamicVO; +import com.ltgk.smartFishingPort.service.IBoatDataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Api(tags = {"渔船档案模块"}) +@RestController +@RequestMapping("/boatData") +public class BoatDataController { + + @Resource + IBoatDataService boatDataService; + @Resource + RedisCache redisUtils; +// @Resource +// private ISolrService solrService; + + @ApiOperation("根据识别船牌号查询船只信息") + @GetMapping("/getBaseInfoByShipPlate") + public Response getBaseInfoByShipPlate(@ApiParam("识别船牌") @RequestParam(value = "shipPlate") String shipPlate) { + Object obj = redisUtils.getCacheObject("ais-collect-name:" + shipPlate); + CurrentAisDynamicVO currentAisDynamicVO = new CurrentAisDynamicVO(); + currentAisDynamicVO.setShipPlate(shipPlate); + if (Objects.isNull(obj)) { + currentAisDynamicVO.setAisStatus("未知"); + return Response.ok(currentAisDynamicVO); + } + BoatDynamicDto boatDynamicDto = JSONObject.parseObject(obj.toString(), BoatDynamicDto.class); +// Map map = new HashMap<>(); +// map.put("boatName",boatDynamicDto.getBoatNameEn()); +// map.put("mmsi",boatDynamicDto.getTerminalCode()); +// map.put("aisStatus","已开启"); +// map.put("sog",boatDynamicDto.getSog()); +// map.put("cog",boatDynamicDto.getSog()); + currentAisDynamicVO.setBoatName(boatDynamicDto.getBoatNameEn()); + currentAisDynamicVO.setMmsi(boatDynamicDto.getTerminalCode()); + currentAisDynamicVO.setAisStatus("已开启"); + currentAisDynamicVO.setSog(boatDynamicDto.getSog()); + currentAisDynamicVO.setCog(boatDynamicDto.getCog()); + currentAisDynamicVO.setLatitude(boatDynamicDto.getLatitude()); + currentAisDynamicVO.setLongitude(boatDynamicDto.getLongitude()); + currentAisDynamicVO.setDataSource(boatDynamicDto.getDataSource()); + return Response.ok(currentAisDynamicVO); + } + + @ApiOperation("根据全部AIS船只信息") + @GetMapping("/getAllAisDynamic") + public Response getAllAisDynamic() { + List objList = redisUtils.getMByScript("ais-collect-name:*"); + if (Objects.isNull(objList) || CollectionUtils.isEmpty(objList)) { + return Response.ok(); + } + List list = objList.stream().map(m -> { + BoatDynamicDto boatDynamicDto = JSONObject.parseObject(m.toString(), BoatDynamicDto.class); + CurrentAisDynamicVO currentAisDynamicVO = new CurrentAisDynamicVO(); + currentAisDynamicVO.setShipPlate(boatDynamicDto.getBoatName()); + currentAisDynamicVO.setBoatName(boatDynamicDto.getBoatNameEn()); + currentAisDynamicVO.setMmsi(boatDynamicDto.getTerminalCode()); + currentAisDynamicVO.setAisStatus("已开启"); + currentAisDynamicVO.setSog(boatDynamicDto.getSog()); + currentAisDynamicVO.setCog(boatDynamicDto.getCog()); + currentAisDynamicVO.setLatitude(boatDynamicDto.getLatitude()); + currentAisDynamicVO.setLongitude(boatDynamicDto.getLongitude()); + currentAisDynamicVO.setDataSource(boatDynamicDto.getDataSource()); + return currentAisDynamicVO; + }).filter(f -> "YingJue".equals(f.getDataSource())).collect(Collectors.toList()); + return Response.ok(list); + } + + /** + * 分页查询渔船档案信息 + * + * @param boatData 渔船档案信息 + * @return 查询结果 + */ + @ApiOperation(value = "分页查询渔船档案信息") + @PostMapping("/page") + public Response page(BoatData boatData) { + IPage result = boatDataService.selectByPage(boatData); + return Response.ok(result); + } + + @ApiOperation(value = "添加渔船档案信息") + @PostMapping("/save") +// @JwtUser + public Response save(BoatData boatData +// , @JwtUser UserInfo user + ) { +// boatData.setCreateBy(user.getUserName()); +// boatData.setUpdateBy(user.getUserName()); + boatData.setDelFlag(Constants.FLAG_FALSE); + return Response.or(boatDataService.save(boatData)); + } + + @ApiOperation(value = "编辑渔船档案信息") + @PostMapping("/update") +// @JwtUser + public Response update(BoatData boatData +// , @JwtUser UserInfo user + ) { +// boatData.setUpdateBy(user.getUserName()); + return Response.or(boatDataService.updateById(boatData)); + } + + @ApiOperation(value = "删除渔船档案信息") + @PostMapping("/delete") + public Response delete(@ApiParam("ID 逗号隔开") @RequestParam("ids") String ids) { + List idList = Arrays.asList(ids.split(",")); + if (CollUtil.isEmpty(idList)) { + return Response.fail("请输入要删除的渔船档案ID"); + } + return Response.or(boatDataService.removeByIds(idList)); + } + + /** + * 根据经纬度获取AIS数据中距离最近的点位且更新时间为±1分钟之内的数据 + * + * @param longitude:经度 + * @param latitude:维度 + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/2 + */ + @ApiOperation(value = "根据经纬度来获取AIS数据中距离最近且不大于10米并且更新时间为5分钟之内的船的数据") + @PostMapping("/getNearestAisData") + public Response getNearestAisData(@ApiParam("经度") @RequestParam("longitude") String longitude, @ApiParam("纬度") @RequestParam("latitude") String latitude) { + return Response.ok(boatDataService.getNearestAisData(longitude, latitude)); + } + +// /** +// * 根据 mmsi 获取 24H 内 AIS 船舶轨迹信息 +// * +// * @param mmsi: AIS 编号 +// * @return ltgk.pm.video.base.Response +// * @author Qi ChengBin +// * @date 2025/12/23 +// */ +// @ApiOperation(value = "根据mmsi获取 24H 轨迹信息") +// @PostMapping("/findAISPointPositionByMmsi") +// public Response findAISPointPositionByMmsi(@ApiParam("mmsi") @RequestParam("mmsi") String mmsi) { +// return Response.ok(solrService.findAISPointPositionByMmsi(mmsi)); +// } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDynamicController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDynamicController.java new file mode 100644 index 0000000..3740af6 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/BoatDynamicController.java @@ -0,0 +1,39 @@ +package com.ltgk.smartFishingPort.controller; + +import com.ltgk.smartFishingPort.common.RocketMQConsumer; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.domain.dto.BoatDynamicDto; +import com.ltgk.smartFishingPort.service.IBoatDynamicService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 17:25 + * Description: + */ +@RestController +@RequestMapping("/boatDynamic") +@Api(tags = {"船舶实时动态信息模块"}) +public class BoatDynamicController { + @Resource + IBoatDynamicService boatDynamicService; + @Resource + RocketMQConsumer rocketMQConsumer; + + @ApiOperation("查询当前渔船动态定位") + @PostMapping("/findByCurrent") + public Response findByCurrent() { +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.ge(BoatDynamic::getGpsTime, DateUtils.formatDateTime(DateUtils.addDays(new Date(),-1),DateUtils.formatDefaultTimestamp)); +// List list = boatDynamicService.list(); + List boatDynamicDtos = rocketMQConsumer.getBoatDynamicList(); + return Response.ok(boatDynamicDtos); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DroneController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DroneController.java new file mode 100644 index 0000000..7c074a5 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DroneController.java @@ -0,0 +1,257 @@ +package com.ltgk.smartFishingPort.controller; + +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.domain.drone.*; +import com.ltgk.smartFishingPort.domain.vo.*; +import com.ltgk.smartFishingPort.service.DroneService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +@Slf4j +@Api(tags = "无人机模块") +@RestController +@RequestMapping("/rest/drone") +@Valid +public class DroneController { + @Autowired + private DroneService droneService; + + /** + * 获取司空平台状态 + * + * @return {@link DroneSystemStatusVO} + */ + @PostMapping("/getDroneSystemStatus") + @ApiOperation(value = "获取司空平台状态") + public Response getDroneSystemStatus() { + return droneService.getDroneSystemStatus(); + } + + /** + * 获取项目列表 + * + * @return {@link List} + */ + @PostMapping("/getDroneProject") + @ApiOperation(value = "获取项目列表") + public Response> getDroneProject() { + return droneService.getDroneProject(); + } + + /** + * 获取组织下的设备列表[机场场景] 飞行器开机后, 才能获得 camera_list 信息。 + * + * @param + * @return {@link List} + */ + @PostMapping("/getDroneDevice") + @ApiOperation(value = "获取组织下的设备列表[机场场景] 飞行器开机后, 才能获得 camera_list 信息。") + public Response> getDroneDevice(@RequestBody @Validated DroneDeviceReq req) { + return droneService.getDroneDevice(req); + } + + /** + * 实时控制指令下发 + * + * @param req + * @return + */ + @PostMapping("/droneCommand") + @ApiOperation(value = "实时控制指令下发") + public Response droneCommand(@RequestBody @Validated DroneCommandReq req) { + return droneService.droneCommand(req); + } + + /** + * 机场相机切换 + * + * @param req + * @return + */ + @PostMapping("/airportCameraSwitch") + @ApiOperation(value = "机场相机切换") + public Response airportCameraSwitch(@RequestBody @Validated AirportCameraSwitchReq req) { + return droneService.airportCameraSwitch(req); + } + + /** + * 飞行器镜头切换 + * + * @param req + * @return + */ + @PostMapping("/droneCameraSwitch") + @ApiOperation(value = "飞行器镜头切换") + public Response droneCameraSwitch(@RequestBody @Validated DroneCameraSwitchReq req) { + return droneService.droneCameraSwitch(req); + } + + /** + * 飞行器控制权获取 + * + * @param req + * @return + */ + @PostMapping("/droneControlObtain") + @ApiOperation(value = "飞行器控制权获取") + public Response droneControlObtain(@RequestBody @Validated DroneControlObtainReq req) { + return droneService.droneControlObtain(req); + } + + /** + * 飞行器控制权释放 + * + * @param req + * @return + */ + @PostMapping("/droneControlRelease") + @ApiOperation(value = "飞行器控制权释放") + public Response droneControlRelease(@RequestBody @Validated DroneControlObtainReq req) { + return droneService.droneControlRelease(req); + } + + /** + * 飞行器控制权获取 + * + * @param req + * @return + */ + @PostMapping("/droneControlObtainV2") + @ApiOperation(value = "飞行器控制权获取V2") + public Response droneControlObtainV2(@RequestBody @Validated DroneControlObtainReqV2 req) { + return droneService.droneControlObtainV2(req); + } + + /** + * 飞行器控制权状态 + * + * @param req + * @return + */ + @PostMapping("/droneControlStatus") + @ApiOperation(value = "飞行器控制权状态") + public Response> droneControlStatus(@RequestBody @Validated DroneControlStatusReq req) { + return droneService.droneControlStatus(req); + } + + /** + * 获取航线详情 + */ + @PostMapping("/getDroneWayLine") + @ApiOperation(value = "获取航线列表") + public Response> getDroneWayLine(@RequestBody @Validated DroneDeviceReq req) { + return droneService.getDroneWayLine(req); + } + + /** + * 获取航线详情 + */ + @PostMapping("/getDroneWayLineDetail") + @ApiOperation(value = "获取航线详情") + public Response getDroneWayLineDetail(@RequestBody @Validated GetDroneWayLineDetailReq req) { + return droneService.getDroneWayLineDetail(req); + } + + /** + * 创建飞行任务 + * + * @param req + * @return + */ + @PostMapping("/createDroneTask") + @ApiOperation(value = "创建飞行任务") + public Response createDroneTask(@RequestBody @Validated CreateDroneTaskReq req) { + return droneService.createDroneTask(req); + } + + /** + * 更新飞行任务状态 + * + * @param req + * @return + */ + @PostMapping("/updateDroneTaskStatus") + @ApiOperation(value = "更新飞行任务状态") + public Response updateDroneTaskStatus(@RequestBody @Validated UpdateDroneTaskStatusReq req) { + return droneService.updateDroneTaskStatus(req); + } + + /** + * 开启直播 + * + * @param req + * @return {@link StartLiveReqRespDto} + */ + @PostMapping("/startLive") + @ApiOperation(value = "开启直播") + public Response startLive(@RequestBody @Validated StartLiveReq req) { + return droneService.startLive(req); + } + + @PostMapping("/getDroneTaskList") + @ApiOperation(value = "获取飞行任务列表") + public Response> getDroneTaskList(@RequestBody @Validated GetDroneTaskListReq req) { + return droneService.getDroneTaskList(req); + } + + /** + * 无人机一键起飞 + * + * @param req + * @return + */ + @PostMapping("/droneOneTouchTakeoff") + @ApiOperation(value = "无人机一键起飞") + public Response droneOneTouchTakeoff(@RequestBody @Validated DroneOneTouchTakeoffReq req) { + return droneService.droneOneTouchTakeoff(req); + } + + /** + * 获取视频流检测算法开关 + * + * @return + */ + @PostMapping("/videoStreamDetectSwitch") + @ApiOperation(value = "获取视频流检测算法开关") + public Response videoStreamDetectSwitch(@RequestBody @Validated VideoStreamDetectSwitchReq req) { + return droneService.videoStreamDetectSwitch(req); + } + + /** + * 获取无人机视频流地址 + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/11/27 + */ + @PostMapping("/getVideoStream") + @ApiOperation(value = "获取视频流地址") + public Response getVideoStream(@RequestBody @Validated GetVideoStreamReq req) { + return droneService.getVideoStream(req); + } + + /** + * 开启关闭无人机算法 + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/11/27 + */ + @PostMapping("/doStartOrStopUavAlgorithm") + @ApiOperation(value = "开启/关闭无人机算法") + public Response doStartOrStopUavAlgorithm(@RequestBody @Validated GetVideoStreamReq req) { + return droneService.doStartOrStopUavAlgorithm(req); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DsVideoController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DsVideoController.java new file mode 100644 index 0000000..4e434f9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/DsVideoController.java @@ -0,0 +1,527 @@ +package com.ltgk.smartFishingPort.controller; + + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.collect.Lists; +import com.ltgk.smartFishingPort.common.core.controller.BaseController; +import com.ltgk.smartFishingPort.common.core.domain.AjaxResult; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.domain.dto.DsArtemisDTO; +import com.ltgk.smartFishingPort.domain.dto.VideoServoDTO; +import com.ltgk.smartFishingPort.domain.entity.DsVideo; +import com.ltgk.smartFishingPort.domain.vo.DsDynamicLkdVO; +import com.ltgk.smartFishingPort.service.IDsVideoService; +import com.ltgk.smartFishingPort.service.impl.ArtemisPostService; +import com.ltgk.smartFishingPort.service.impl.DsCameraService; +import com.ltgk.smartFishingPort.utils.CameraDegreesUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + *

+ * 视频监控管理表 前端控制器 + *

+ * + * @author zhouyaoyao + * @since 2025-01-19 + */ +@Api(tags = "视频监控设备信息") +@RestController +@RequestMapping("/fishingPort/dsVideo") +public class DsVideoController extends BaseController { + + @Resource + IDsVideoService dsVideoService; + @Resource + RedisTemplate redisTemplate; + @Resource + DsCameraService dsCameraService; + + @ApiOperation(value = "查询列表数据") + @PostMapping("/getList") + public Object getList(@RequestBody DsVideo dsVideo) { + QueryWrapper queryWrapper = MybatisUtil.notNullField(dsVideo); + List list = dsVideoService.list(queryWrapper); + return success(list); + } + + /** + * 视频监控层级列表 + * + * @param dsVideo: + * @return com.yuhuan.common.core.domain.AjaxResult + * @author Qi ChengBin + * @date 2025/3/11 + */ + @ApiOperation(value = "视频监控层级列表") + @PostMapping("/findVideoLevelList") + public AjaxResult findVideoLevelList(@RequestBody DsVideo dsVideo) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(dsVideo); + List dsVideoList = dsVideoService.list(wrapper); + return success(dsVideoList.stream() + .collect(Collectors.groupingBy(DsVideo::getBelongUnit))); + } + + + @ApiOperation(value = "分页查询") + @PostMapping("/page") + public Object page(@RequestBody DsVideo dsVideo) { + QueryWrapper queryWrapper = MybatisUtil.notNullField(dsVideo); + startPage(dsVideo.getPageNum(), dsVideo.getPageSize()); + List list = dsVideoService.list(queryWrapper); + return getDataTable(list); + } + + @ApiOperation(value = "详情查询") + @PostMapping("/detail") + public Object page(@RequestParam("id") Long id) { + if (Objects.isNull(id)) { + return AjaxResult.error("id不能为空"); + } + DsVideo dsVideo = dsVideoService.getById(id); + return success(dsVideo); + } + + @ApiOperation(value = "添加") + @PostMapping("/save") + public Object save(@RequestBody DsVideo dsVideo) { + dsVideo.setCreateBy("SYS") + .setCreateAt(new Date()) + .setUpdateBy("SYS") + .setUpdateAt(new Date()); + AjaxResult result = toAjax(dsVideoService.save(dsVideo)); + updateYunVideoList(); + return result; + } + + @ApiOperation(value = "编辑") + @PostMapping("/update") + public Object update(@RequestBody DsVideo dsVideo) { + dsVideo.setUpdateBy("SYS") + .setUpdateAt(new Date()); + AjaxResult result = toAjax(dsVideoService.updateById(dsVideo)); + updateYunVideoList(); + return result; + } + + @ApiOperation(value = "删除") + @PostMapping("/delete") + public Object delete(@RequestBody DsVideo dsVideo) { + AjaxResult result = toAjax(dsVideoService.removeById(dsVideo.getId())); + updateYunVideoList(); + return result; + } + + @ApiOperation("通过海康综合安防平台查询视频监控设备的预览视频流链接") + @PostMapping("/getPreviewUrlByArtemis") + public AjaxResult getPreviewUrlByArtemis(@RequestBody DsArtemisDTO dsArtemisDTO) { + String previewProtocol = dsArtemisDTO.getPreviewProtocol(); + if (StringUtils.isEmpty(previewProtocol)) { + previewProtocol = "hls"; + } + return AjaxResult.success(ArtemisPostService.getPreviewUrl(dsArtemisDTO.getVideoCode(), previewProtocol)); + } + + /** + * 光电联动反向定位,判断监控设备和将要联动的定位目标是否超出可视范围、是否处于视角遮挡区 + * + * @return + */ + @ApiOperation("光电联动反向定位判断") + @PostMapping("/judgeMoveByGps") + public AjaxResult judgeMoveByGps(@RequestBody VideoServoDTO videoServoDTO) { + String deviceCode = videoServoDTO.getDeviceCode(); + String gpsX = videoServoDTO.getGpsX(); + String gpsY = videoServoDTO.getGpsY(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(DsVideo::getVideoCode, deviceCode); + queryWrapper.last("limit 1"); + DsVideo videos = dsVideoService.getOne(queryWrapper); + if (Objects.isNull(videos)) { + return error("未查到该摄像头"); + } + // 默认可视距离 5KM + Double visibleDistance = 5d; + if (!Objects.isNull(videos.getVisionDistance())) { + visibleDistance = videos.getVisionDistance().doubleValue(); + } + try { + double latitudeVal = videos.getLatitude().doubleValue(); + double longitudeVal = videos.getLongitude().doubleValue(); + double gpsXVal = Double.parseDouble(gpsX); + double gpsYVal = Double.parseDouble(gpsY); + double distance = CameraDegreesUtil.getDistance(longitudeVal, latitudeVal, gpsXVal, gpsYVal).setScale(5, RoundingMode.HALF_UP).doubleValue(); + if (org.apache.commons.lang.StringUtils.isNotBlank(videos.getXRotateVal())) { + BigDecimal degreeX = CameraDegreesUtil.rotateForNorthByLR(longitudeVal, latitudeVal, gpsXVal, gpsYVal, videos.getRotateT()); + double degreeXVal = degreeX.doubleValue(); + degreeXVal = degreeXVal < 0 ? 360 + degreeXVal : degreeXVal; + double dxVal = degreeXVal; + String xRotateVal = videos.getXRotateVal(); + List flags = Arrays.asList(xRotateVal.split(";")).stream().map(item -> { + String itemStr1 = item.split("-")[0]; + String itemStr2 = item.split("-")[1]; + double itemVal1 = Double.parseDouble(itemStr1); + double itemVal2 = Double.parseDouble(itemStr2); + return itemVal1 < dxVal && itemVal2 > dxVal; + }).collect(Collectors.toList()); + if (!flags.contains(true)) { + return error("超出监控摄像头可视角度,此监控角度有遮挡"); + } + } + if (distance > visibleDistance) { + return error("超出监控摄像头可视范围"); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + return success(); + } + + /** + * 云台类型监控设备列表,用于光电联动时获取联动目标附近的视频监控设备 + */ + List yunVideoCodeList = Lists.newArrayList(); + + /** + * 定时(4个小时)更新一次云台类型监控设备列表 + */ + @Scheduled(cron = "0 0 0/4 * * ?") + public List updateYunVideoList() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.eq(DsVideo::getVideoType, "云台") + .eq(DsVideo::getRunStatus, "正常") + // 获取没有锁定的摄像头 + .eq(DsVideo::getBeLock, 0) + ; + queryWrapper.orderByAsc(DsVideo::getVideoName); + List list = dsVideoService.list(queryWrapper); + if (!CollectionUtils.isEmpty(list)) { + yunVideoCodeList = list.stream() + .filter(f -> "云台".equals(f.getVideoType()) && StringUtils.isNotBlank(f.getVideoCode())) + .collect(Collectors.toList()); + return yunVideoCodeList; + } else { + return Lists.newArrayList(); + } + } + + /** + * 光电联动反向定位联动控制,根据监控设备和将要联动的定位目标经纬度控制视频监控设备转动对焦 + * + * @return + */ + @ApiOperation("光电联动反向定位联动控制") + @PostMapping("/sitMoveByGps") + public AjaxResult sitMoveByGps(@RequestBody VideoServoDTO videoServoDTO) { + String deviceCode = videoServoDTO.getDeviceCode(); + String gpsX = videoServoDTO.getGpsX(); + String gpsY = videoServoDTO.getGpsY(); + String mmsi = videoServoDTO.getTerminalCode(); + Object dynamicObj = redisTemplate.opsForValue().get("ais:" + mmsi); + Object radarDynamicObj = redisTemplate.opsForValue().get("radar-mmsi:" + mmsi); + DsDynamicLkdVO dynamicRadarVO = null; + if (!Objects.isNull(dynamicObj)) { + try { + dynamicRadarVO = JSONObject.parseObject(dynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 AIS 信息[" + dynamicObj.toString() + "]报错:" + e.getMessage()); + } + } + if (!Objects.isNull(radarDynamicObj)) { + DsDynamicLkdVO dynamicRadarTmp = null; + try { + dynamicRadarTmp = JSONObject.parseObject(radarDynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 Radar 信息[" + radarDynamicObj.toString() + "]报错:" + e.getMessage()); + } + if (!Objects.isNull(dynamicRadarVO)) { + Date gpsTime = dynamicRadarVO.getLocationTime(); + if (gpsTime.before(dynamicRadarTmp.getLocationTime())) { + dynamicRadarVO = dynamicRadarTmp; + } + } else { + dynamicRadarVO = dynamicRadarTmp; + } + } + if (!Objects.isNull(dynamicRadarVO)) { + gpsX = dynamicRadarVO.getLongitude().toString(); + gpsY = dynamicRadarVO.getLatitude().toString(); + } + return dsVideoService.sitMoveByGps(deviceCode, gpsX, gpsY); + } + + @ApiOperation("校准光电联动功能参数") + @PostMapping("/correctLinkageParam") + public AjaxResult correctLinkageParam(@RequestBody VideoServoDTO videoServoDTO) { + String mmsi = videoServoDTO.getTerminalCode(); + String deviceCode = videoServoDTO.getDeviceCode(); + Object dynamicObj = redisTemplate.opsForValue().get("ais:" + mmsi); + Object radarDynamicObj = redisTemplate.opsForValue().get("radar-mmsi:" + mmsi); + DsDynamicLkdVO dynamicRadarVO = null; + if (!Objects.isNull(dynamicObj)) { + try { + dynamicRadarVO = JSONObject.parseObject(dynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 AIS 信息[" + dynamicObj.toString() + "]报错:" + e.getMessage()); + } + } + if (!Objects.isNull(radarDynamicObj)) { + DsDynamicLkdVO dynamicRadarTmp = null; + try { + dynamicRadarTmp = JSONObject.parseObject(radarDynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 Radar 信息[" + radarDynamicObj.toString() + "]报错:" + e.getMessage()); + } + if (!Objects.isNull(dynamicRadarVO)) { + Date gpsTime = dynamicRadarVO.getLocationTime(); + if (gpsTime.before(dynamicRadarTmp.getLocationTime())) { + dynamicRadarVO = dynamicRadarTmp; + } + } else { + dynamicRadarVO = dynamicRadarTmp; + } + } + if (Objects.isNull(dynamicRadarVO)) { + return AjaxResult.error(); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(DsVideo::getVideoCode, deviceCode); + queryWrapper.last(" limit 1"); + DsVideo dsVideo = dsVideoService.getOne(queryWrapper); + if (Objects.isNull(dsVideo)) { + return AjaxResult.error(); + } + Object ptzObj = dsCameraService.hkGetPtzCfg(dsVideo.getVideoIp(), dsVideo.getVideoPort(), dsVideo.getVideoAccount(), dsVideo.getVideoPassword()); + if (Objects.isNull(ptzObj)) { + return AjaxResult.error(); + } + JSONObject ptzJSONObj = JSONObject.parseObject(JSONObject.toJSONString(ptzObj)); + System.out.println(JSONObject.toJSONString(ptzObj)); + float pVal = ptzJSONObj.getFloat("pValue"); + float tVal = ptzJSONObj.getFloat("tValue"); + float zVal = ptzJSONObj.getFloat("zValue"); + int rotateT = dsVideo.getRotateT(); + Double height = dsVideo.getHeight().doubleValue(); + double lon1 = dynamicRadarVO.getLongitude(); + double lat1 = dynamicRadarVO.getLatitude(); + double lon2 = dsVideo.getLongitude().doubleValue(); + double lat2 = dsVideo.getLatitude().doubleValue(); + String xValArr = dsVideo.getXValArr(); + String yValArr = dsVideo.getYValArr(); + String zNumValArr = dsVideo.getZNumValArr(); + + BigDecimal degreeX = CameraDegreesUtil.rotateForNorthByLR(lon2, lat2, lon1, lat1, rotateT); + double degreeXVal = degreeX.doubleValue() < 0 ? 360 + degreeX.doubleValue() : degreeX.doubleValue(); + degreeX = new BigDecimal(degreeXVal); + BigDecimal degreeY = CameraDegreesUtil.rotateByUD(Objects.isNull(height) ? 0.2 : (height / 1000), lon2, lat2, lon1, lat1); + BigDecimal distance = CameraDegreesUtil.getDistance(lon1, lat1, lon2, lat2).setScale(5, RoundingMode.HALF_UP); + System.out.println("degreeX:" + degreeX + ",degreeY:" + degreeY + ",distance:" + distance); + double xVal = new BigDecimal(pVal).subtract(degreeX).setScale(8, BigDecimal.ROUND_UP).doubleValue(); + double yVal = new BigDecimal(tVal).subtract(degreeY).setScale(8, BigDecimal.ROUND_UP).doubleValue(); + double zNumVal = new BigDecimal(zVal).divide(distance, 8, BigDecimal.ROUND_UP).doubleValue(); + JSONArray xValArray = null; + if (StringUtils.isNotBlank(xValArr)) { + xValArray = JSONArray.parseArray(xValArr); + } else { + xValArray = new JSONArray(); + } + JSONObject xValArrItem = new JSONObject(); + xValArrItem.put("distance", degreeX.setScale(8, BigDecimal.ROUND_UP).doubleValue()); + xValArrItem.put("number", xVal); + xValArray.add(xValArrItem); + xValArr = JSONObject.toJSONString(xValArray); + JSONArray yValArray = null; + if (StringUtils.isNotBlank(yValArr)) { + yValArray = JSONArray.parseArray(yValArr); + } else { + yValArray = new JSONArray(); + } + JSONObject yValArrItem = new JSONObject(); + yValArrItem.put("distance", distance.setScale(8, BigDecimal.ROUND_UP).doubleValue()); + yValArrItem.put("number", yVal); + yValArray.add(yValArrItem); + yValArr = JSONObject.toJSONString(yValArray); + JSONArray zNumValArray = null; + if (StringUtils.isNotBlank(zNumValArr)) { + zNumValArray = JSONArray.parseArray(zNumValArr); + } else { + zNumValArray = new JSONArray(); + } + JSONObject zNumValItem = new JSONObject(); + zNumValItem.put("distance", distance.setScale(8, BigDecimal.ROUND_UP).doubleValue()); + zNumValItem.put("number", zNumVal); + zNumValArray.add(zNumValItem); + zNumValArr = JSONObject.toJSONString(zNumValArray); + boolean result = dsVideoService.lambdaUpdate() + .eq(DsVideo::getVideoIp, dsVideo.getVideoIp()) + .set(DsVideo::getXValArr, xValArr) + .set(DsVideo::getYValArr, yValArr) + .set(DsVideo::getZNumValArr, zNumValArr) + .update(); + return AjaxResult.success(result); + } + + /** + * 光电联动查看监控设备列表 + * + * @return 光电联动查看监控设备列表 + */ + @ApiOperation("光电联动查看监控设备列表") + @PostMapping("/getDevicesForServo") + public AjaxResult getDevicesForServo(@RequestBody VideoServoDTO videoServoDTO) { + String gpsX = videoServoDTO.getGpsX(); + String gpsY = videoServoDTO.getGpsY(); + Double gpsXVal = Double.parseDouble(gpsX); + Double gpsYVal = Double.parseDouble(gpsY); + yunVideoCodeList = updateYunVideoList(); + List list = yunVideoCodeList.stream().map(v -> { + double latitudeVal = v.getLatitude().doubleValue(); + double longitudeVal = v.getLongitude().doubleValue(); + BigDecimal distance = CameraDegreesUtil.getDistance(longitudeVal, latitudeVal, gpsXVal, gpsYVal).setScale(5, RoundingMode.HALF_UP); + v.setDistance(distance); + v.setDistance1(distance); +// v.setDistanceVal(Objects.isNull(v.getVisionDistance()) ? 0 : distance.doubleValue() - v.getVisionDistance().doubleValue()); + if (StringUtils.isNotBlank(v.getXRotateVal())) { + BigDecimal degreeX = CameraDegreesUtil.rotateForNorthByLR(longitudeVal, latitudeVal, gpsXVal, gpsYVal, v.getRotateT()); + double degreeXVal = degreeX.doubleValue(); + degreeXVal = degreeXVal < 0 ? 360 + degreeXVal : degreeXVal; + double dxVal = degreeXVal; + String xRotateVal = v.getXRotateVal(); + List flags = Arrays.asList(xRotateVal.split(";")).stream().map(item -> { + String itemStr1 = item.split("-")[0]; + String itemStr2 = item.split("-")[1]; + double itemVal1 = Double.parseDouble(itemStr1); + double itemVal2 = Double.parseDouble(itemStr2); + return itemVal1 < dxVal && itemVal2 > dxVal; + }).collect(Collectors.toList()); + if (!flags.contains(true)) { +// return Response.fail("超出监控摄像头可视范围"); + v.setDistance1(Objects.isNull(v.getDistance()) ? v.getDistance() : v.getDistance().add(new BigDecimal(999))); + } + } + return v; + }).sorted(Comparator.comparing(DsVideo::getDistance1)).collect(Collectors.toList()); + List resultList = Lists.newArrayList(); + if (CollectionUtils.isEmpty(yunVideoCodeList)) { + return AjaxResult.success(list); + } + for (int i = 0; i < list.size(); i++) { + if (i < 5) { + resultList.add(list.get(i)); + } + } + return success(resultList); + } + + /** + * 光电随动控制 + * + * @return + */ + @ApiOperation("光电随动控制") + @PostMapping("/servoByRadar") + public AjaxResult servoByRadar(@RequestBody VideoServoDTO videoServoDTO) { + Set tempPatternKey = redisTemplate.keys("servo:*"); + String deviceCode = videoServoDTO.getDeviceCode(); + String terminalCode = videoServoDTO.getTerminalCode(); + if (!CollectionUtils.isEmpty(tempPatternKey)) { + tempPatternKey.stream() + .forEach(m -> { + String deviceCodeTmp = redisTemplate.opsForValue().get(m).toString(); + if (deviceCode.trim().equals(deviceCodeTmp)) { + redisTemplate.delete("servo:" + m); + } + }); + } + String gpsX = videoServoDTO.getGpsX(); + String gpsY = videoServoDTO.getGpsY(); + Object dynamicObj = redisTemplate.opsForValue().get("ais:" + terminalCode); + Object radarDynamicObj = redisTemplate.opsForValue().get("radar-mmsi:" + terminalCode); + DsDynamicLkdVO dynamicRadarVO = null; + if (!Objects.isNull(dynamicObj)) { + try { + dynamicRadarVO = JSONObject.parseObject(dynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 AIS 信息[" + dynamicObj.toString() + "]报错:" + e.getMessage()); + } + } + if (!Objects.isNull(radarDynamicObj)) { + DsDynamicLkdVO dynamicRadarTmp = null; + try { + dynamicRadarTmp = JSONObject.parseObject(radarDynamicObj.toString(), DsDynamicLkdVO.class); + } catch (Exception e) { + System.out.println("解析 redis 中的 Radar 信息[" + radarDynamicObj.toString() + "]报错:" + e.getMessage()); + } + if (!Objects.isNull(dynamicRadarVO)) { + Date gpsTime = dynamicRadarVO.getLocationTime(); + if (gpsTime.before(dynamicRadarTmp.getLocationTime())) { + dynamicRadarVO = dynamicRadarTmp; + } + } else { + dynamicRadarVO = dynamicRadarTmp; + } + } + if (!Objects.isNull(dynamicRadarVO)) { + gpsX = dynamicRadarVO.getLongitude().toString(); + gpsY = dynamicRadarVO.getLatitude().toString(); + } + dsVideoService.sitMoveByGps(deviceCode, gpsX, gpsY); + redisTemplate.opsForValue().set("servo:" + terminalCode, deviceCode, 30, TimeUnit.MINUTES); + return success(); + } + + /** + * 光电随动控制退出 + * + * @return + */ + @ApiOperation("光电随动控制退出") + @PostMapping("/servoByRadarExit") + public AjaxResult servoByRadarExit(@RequestBody VideoServoDTO videoServoDTO) { + String terminalCode = videoServoDTO.getTerminalCode(); + redisTemplate.delete("servo:" + terminalCode); + return success(); + } + + /** + * 获取摄像头详细信息,并且获取摄像头相关的 PTZ + * + * @param dsVideo: + * @return com.yuhuan.common.core.domain.AjaxResult + * @author Qi ChengBin + * @date 2025/8/4 + */ + @PostMapping("/getVideoInfo") + public AjaxResult getVideoInfo(@RequestBody DsVideo dsVideo) { + return success(dsVideoService.getVideoInfo(dsVideo)); + } + + /** + * 更新摄像头可视范围字段状态,并获取所有的开启了可视摄像头范围的相关数据 + * + * @param dsVideo:需开启摄像头可视范围的相关摄像头数据 + * @return com.yuhuan.common.core.domain.AjaxResult + * @author Qi ChengBin + * @date 2025/9/15 + */ + @PostMapping("/updateOneAndFindVideoInfoList") + public AjaxResult updateOneAndFindVideoInfoList(@RequestBody DsVideo dsVideo) { + return success(dsVideoService.updateOneAndFindVideoInfoList(dsVideo)); + } +} + diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/EmergencyRescueController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/EmergencyRescueController.java new file mode 100644 index 0000000..edb02b3 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/EmergencyRescueController.java @@ -0,0 +1,77 @@ +package com.ltgk.smartFishingPort.controller; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.domain.entity.EmergencyRescue; +import com.ltgk.smartFishingPort.service.IEmergencyRescueService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:11 + * Description: + */ +@RestController +@RequestMapping("/emergencyRescue") +@Api(tags = "应急救援事故模块") +public class EmergencyRescueController { + + @Resource + IEmergencyRescueService emergencyRescueService; + + /** + * 分页查询应急救援事故 + * + * @param entity 应急救援事故 + * @return 查询结果 + */ + @ApiOperation(value = "分页查询应急救援事故") + @PostMapping("/page") + public Response page(EmergencyRescue entity) { + IPage result = emergencyRescueService.selectByPage(entity); + return Response.ok(result); + } + + @ApiOperation(value = "添加应急救援事故") + @PostMapping("/save") +// @JwtUser + public Response save(EmergencyRescue entity +// , @JwtUser UserInfo user + ) { +// entity.setCreateBy(user.getUserName()); +// entity.setUpdateBy(user.getUserName()); +// entity.setDelFlag(Constants.FLAG_FALSE); + return Response.or(emergencyRescueService.save(entity)); + } + + @ApiOperation(value = "编辑应急救援事故") + @PostMapping("/update") +// @JwtUser + public Response update(EmergencyRescue entity +// , @JwtUser UserInfo user + ) { +// entity.setUpdateBy(user.getUserName()); + return Response.or(emergencyRescueService.updateById(entity)); + } + + @ApiOperation(value = "删除应急救援事故") + @PostMapping("/delete") + public Response delete(@ApiParam("ID 逗号隔开") @RequestParam("ids") String ids) { + List idList = Arrays.asList(ids.split(",")); + if (CollUtil.isEmpty(idList)) { + return Response.fail("请输入要删除的应急救援事故ID"); + } + return Response.or(emergencyRescueService.removeByIds(idList)); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoCameraController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoCameraController.java new file mode 100644 index 0000000..dc221a7 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoCameraController.java @@ -0,0 +1,341 @@ +package com.ltgk.smartFishingPort.controller; + + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ltgk.smartFishingPort.common.constant.Constants; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.common.core.redis.RedisCache; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.domain.entity.EnvEquipment; +import com.ltgk.smartFishingPort.domain.entity.UavEquipment; +import com.ltgk.smartFishingPort.domain.entity.VideoCamera; +import com.ltgk.smartFishingPort.mapper.EnvEquipmentMapper; +import com.ltgk.smartFishingPort.mapper.UavEquipmentMapper; +import com.ltgk.smartFishingPort.service.IVideoCameraService; +import com.ltgk.smartFishingPort.utils.ArtemisPostUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + *

+ * 监控设备表 前端控制器 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +@Api(tags = {"监控设备模块"}) +@RestController +@RequestMapping("/videoCamera") +public class VideoCameraController { + + @Autowired + RedisCache redisUtils; + + @Autowired + IVideoCameraService videoCameraService; + @Resource + UavEquipmentMapper uavEquipmentMapper; + @Resource + EnvEquipmentMapper envEquipmentMapper; + + @ApiOperation("分页查询监控设备列表") + @PostMapping("/findPage") + public Response findPage(VideoCamera videoCamera + , @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo + , @RequestParam(value = "pageSize", defaultValue = "15") Integer pageSize) { + IPage page = videoCameraService.findPage(videoCamera, pageNo, pageSize); + return Response.ok(page); + } + + @ApiOperation("分页查询无人机设备列表") + @PostMapping("/findUavPage") + public Response findUavPage(UavEquipment uavEquipment + , @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo + , @RequestParam(value = "pageSize", defaultValue = "15") Integer pageSize) { + IPage page = new Page<>(pageNo, pageSize); + QueryWrapper wrapper = MybatisUtil.notNullField(uavEquipment); + IPage pageList = uavEquipmentMapper.selectPage(page, wrapper); + return Response.ok(pageList); + } + + @ApiOperation("分页查询环境检测设备列表") + @PostMapping("/findEnvPage") + public Response findEnvPage(EnvEquipment envEquipment + , @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo + , @RequestParam(value = "pageSize", defaultValue = "15") Integer pageSize) { + IPage page = new Page<>(pageNo, pageSize); + String videoType = envEquipment.getVideoType(); + envEquipment.setVideoType(null); + LambdaQueryWrapper wrapper = MybatisUtil.notNullField(envEquipment).lambda(); + if (StringUtils.isNotBlank(videoType)) { + wrapper.in(EnvEquipment::getVideoType, Arrays.asList(videoType.split(","))); + } + IPage pageList = envEquipmentMapper.selectPage(page, wrapper); + return Response.ok(pageList); + } + + /** + * SDK摄像头登录 + */ + @ApiOperation("SDK摄像头登录DH") +// @ApiImplicitParams({ +// @ApiImplicitParam(name = "m_strIp", value = "摄像头ip", required = true), +// @ApiImplicitParam(name = "m_nPort", value = "摄像头端口", required = true), +// @ApiImplicitParam(name = "m_strUser", value = "摄像头用户名", required = true), +// @ApiImplicitParam(name = "m_strPassword", value = "摄像头密码", required = true) +// }) + @PostMapping("/sdkLoginDH") + public Object sdkLogin(String m_strIp, String m_nPort, String m_strUser, String m_strPassword) { + String key = m_strIp + m_nPort + m_strUser + m_strPassword; + Object result = redisUtils.getCacheObject("DHLoginIp:" + m_strIp); + String lHandler = ""; + if (result == null) { + Object loginResult = videoCameraService.loginDH(m_strIp, m_nPort, m_strUser, m_strPassword); + + if (loginResult.toString().contains("true")) { + lHandler = String.valueOf(JSONObject.parseObject(loginResult.toString()).get("result")); + //有效期1h + redisUtils.setCacheObject("DHLoginIp:" + m_strIp, lHandler, 60 * 60 * 1, TimeUnit.SECONDS); + redisUtils.setCacheObject("DHLoginHandler:" + lHandler, m_strIp, 60 * 60 * 1, TimeUnit.SECONDS); + } + } else { + lHandler = result.toString(); + } + return lHandler; + } + + @ApiOperation("订阅车辆交通抓拍信息") + @PostMapping("/attachTrafficByAccount") + public Response attachTraffic(String m_strIp, String m_nPort, String m_strUser, String m_strPassword, Integer channelId) { + boolean result = videoCameraService.attachAlarmChanDHByAccount(m_strIp, m_nPort, m_strUser, m_strPassword, channelId.toString()); + if (result) { + return Response.ok(); + } else { + return Response.fail("操作失败"); + } + } + + @ApiOperation("订阅车辆交通抓拍信息") + @PostMapping("/attachTrafficByHandler") + public Response attachTraffic(Long loginHandler, Integer channelId) { + boolean result = videoCameraService.attachTraffic(loginHandler, channelId); + if (result) { + Object m_strIp = redisUtils.getCacheObject("DHLoginHandler:" + loginHandler); + if (!Objects.isNull(m_strIp)) { + redisUtils.setCacheObject("DHTrafficHandler:" + loginHandler, m_strIp, 60 * 60 * 6, TimeUnit.SECONDS); + } + } + return Response.or(result); + } + + @ApiOperation("通过综合安防平台获取监控信息") + @PostMapping("/getHKMonitorPoint") + public Response getHKMonitorPoint() { + return Response.ok(ArtemisPostUtil.callPostStringApi()); + } + + + /** + * 获取监控点预览取流URLv2 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ + @PostMapping("/getPreviewUrl") + public Response getPreviewUrl(@RequestParam("cameraIndexCode") String cameraIndexCode) { + return Response.ok(ArtemisPostUtil.getPreviewUrl(cameraIndexCode)); + } + + /** + * 云台操作 + * 根据监控点编号进行云台操作接口 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param action 0-开始 ,1-停止 注:GOTO_PRESET命令下填任意值均可转到预置点,建议填0即可 + * @param command 不区分大小写,说明: + * LEFT 左转 + * RIGHT右转 + * UP 上转 + * DOWN 下转 + * ZOOM_IN 焦距变大 + * ZOOM_OUT 焦距变小 + * LEFT_UP 左上 + * LEFT_DOWN 左下 + * RIGHT_UP 右上 + * RIGHT_DOWN 右下 + * FOCUS_NEAR 焦点前移 + * FOCUS_FAR 焦点后移 + * IRIS_ENLARGE 光圈扩大 + * IRIS_REDUCE 光圈缩小 + * WIPER_SWITCH 接通雨刷开关 + * START_RECORD_TRACK 开始记录轨迹 + * STOP_RECORD_TRACK 停止记录轨迹 + * START_TRACK 开始轨迹 + * STOP_TRACK 停止轨迹; + * 以下命令presetIndex不可为空: + * GOTO_PRESET到预置点 + * @param speed 云台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 查询结果 + */ + @PostMapping("/controlByPtz") + public Response controlByPtz(@RequestParam("cameraIndexCode") String cameraIndexCode, @RequestParam("action") Integer action + , @RequestParam("command") String command, @RequestParam("speed") Integer speed, @RequestParam("presetIndex") Integer presetIndex) { + JSONObject obj = ArtemisPostUtil.controlling(cameraIndexCode, action, command, speed, presetIndex); + if (!Objects.isNull(obj)) { + boolean success = obj.getBoolean("success"); + return Response.or(success); + } else { + return Response.or(false); + } + } + + /** + * 云台跳转到指定预置点 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param speed 台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 调用结果 + */ + @PostMapping("/goToPreset") + public Response goToPreset(@RequestParam("cameraIndexCode") String cameraIndexCode, @RequestParam("speed") Integer speed + , @RequestParam("presetIndex") String presetIndex) { + JSONObject obj = ArtemisPostUtil.goToPreset(cameraIndexCode, speed, presetIndex); + if (!Objects.isNull(obj)) { + boolean success = obj.getBoolean("success"); + return Response.or(success); + } else { + return Response.or(false); + } + } + + /** + * 设置预置点信息 + * 该接口用于设置监控点的预置点信息,若参数传已经存在的预置点编号,则可修改预置点信息 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param presetName 预置点名称 + * @param presetIndex 预置点编号(1 - 300) + * @return 调用结果 + * @throws Exception 抛出异常 + */ + @PostMapping("/presetsAddition") + public Response presetsAddition(@RequestParam("cameraIndexCode") String cameraIndexCode, @RequestParam("presetName") String presetName + , @RequestParam("presetIndex") Integer presetIndex) { + return Response.ok(ArtemisPostUtil.presetsAddition(cameraIndexCode, presetName, presetIndex)); + } + + /** + * 查询预置点信息 + * 该接口用于查询监控点的预置点信息。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ + @PostMapping("/presetsSearches") + public Response presetsSearches(@RequestParam("cameraIndexCode") String cameraIndexCode) { + return Response.ok(ArtemisPostUtil.presetsSearches(cameraIndexCode)); + } + + /** + * 删除预置点信息 + * 该接口用于删除监控点的预置点信息。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param presetIndex 预置点编号 + * @return 调用结果 + */ + @PostMapping("/presetsDeletion") + public Response presetsDeletion(@RequestParam("cameraIndexCode") String cameraIndexCode, @RequestParam("presetIndex") Integer presetIndex) { + return Response.ok(ArtemisPostUtil.presetsDeletion(cameraIndexCode, presetIndex)); + } + + /** + * 3D放大 + * 该接口用于控制监控点进行3D电子放大。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param startX 开始放大的X坐标,范围:0-255。由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕X坐标/屏幕宽 * 255,即该坐标位X坐标占总屏幕宽的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param startY 开始放大的Y坐标,范围:0-255,由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕Y坐标/屏幕高 * 255,即该坐标位Y坐标占总屏幕高的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param endX 结束放大的X坐标,范围以及计算方式同startX + * @param endY 结束放大的Y坐标,范围以及计算方式同startY + * @return 查询结果 + */ + @PostMapping("/selZoom") + public Response selZoom(@RequestParam("cameraIndexCode") String cameraIndexCode, @RequestParam("startX") Integer startX + , @RequestParam("startY") Integer startY, @RequestParam("endX") Integer endX, @RequestParam("endY") Integer endY) { + return Response.ok(ArtemisPostUtil.selZoom(cameraIndexCode, startX, startY, endX, endY)); + } + + /** + * 分页查询视频监控信息 + * + * @param videoCamera 视频监控信息 + * @return 查询结果 + */ + @ApiOperation(value = "分页查询视频监控信息") + @PostMapping("/page") + public Response page(VideoCamera videoCamera) { + IPage result = videoCameraService.selectByPage(videoCamera); + return Response.ok(result); + } + + @ApiOperation(value = "添加视频监控信息") + @PostMapping("/save") +// @JwtUser + public Response save(VideoCamera videoCamera +// , @JwtUser UserInfo user + ) { +// videoCamera.setCreateBy(user.getUserName()); +// videoCamera.setUpdateBy(user.getUserName()); + videoCamera.setDelFlag(Constants.FLAG_FALSE); + return Response.or(videoCameraService.save(videoCamera)); + } + + @ApiOperation(value = "编辑视频监控信息") + @PostMapping("/update") +// @JwtUser + public Response update(VideoCamera videoCamera +// , @JwtUser UserInfo user + ) { +// videoCamera.setUpdateBy(user.getUserName()); + return Response.or(videoCameraService.updateById(videoCamera)); + } + + @ApiOperation(value = "删除视频监控信息") + @PostMapping("/delete") + public Response delete(@ApiParam("ID 逗号隔开") @RequestParam("ids") String ids) { + List idList = Arrays.asList(ids.split(",")); + if (CollUtil.isEmpty(idList)) { + return Response.fail("请输入要删除的视频监控ID"); + } + return Response.or(videoCameraService.removeByIds(idList)); + } +} + diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoIdentificationController.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoIdentificationController.java new file mode 100644 index 0000000..f2a9ccc --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/controller/VideoIdentificationController.java @@ -0,0 +1,324 @@ +package com.ltgk.smartFishingPort.controller; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.google.common.collect.Lists; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.common.utils.DateUtils; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.domain.dto.UpdateVideoIdentificationDto; +import com.ltgk.smartFishingPort.domain.dto.VideoIdentificationDto; +import com.ltgk.smartFishingPort.domain.entity.VideoIdentification; +import com.ltgk.smartFishingPort.domain.vo.*; +import com.ltgk.smartFishingPort.service.IVideoIdentificationService; +import com.ltgk.smartFishingPort.utils.ExcelUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + *

+ * 监控识别记录表 前端控制器 + *

+ * + * @author zhou + * @since 2024-12-10 + */ +@Api(tags = {"视频识别信息模块"}) +@RestController +@RequestMapping("/videoIdentification") +@Slf4j +public class VideoIdentificationController { + + @Autowired + IVideoIdentificationService videoIdentificationService; + + @Value("${url.picFile}") + private String picUrl; + + @ApiOperation("添加视频检测预警信息") + @PostMapping(value = "/add") + public Response add(@ModelAttribute VideoIdentification videoIdentification) { +// String videoReplace = videoIdentification.getVideoUrl().replace("http://120.238.185.186:2001", "https://pyzhyg.panyu.gd.cn:7673"); +// String pictureReplace = videoIdentification.getPictureUrl().replace("http://120.238.185.186:2001", "https://pyzhyg.panyu.gd.cn:7673"); +// videoIdentification.setVideoUrl(videoReplace.replace("http://120.238.185.186:2002", "https://pyzhyg.panyu.gd.cn:7673")); +// videoIdentification.setPictureUrl(pictureReplace.replace("http://120.238.185.186:2002", "https://pyzhyg.panyu.gd.cn:7673")); + + if ("卡口".equals(videoIdentification.getTakeType())) { + // 接收卡口数据 + if (!"船牌识别".equals(videoIdentification.getIdentificationType())) { + return Response.ok(); + } + // TODO: 接收数据时将图片的数据进行转换 + videoIdentification.setCreateAt(new Date()) + .setCreateBy("SYS-卡口") + .setUpdateAt(new Date()) + .setUpdateBy("SYS-卡口"); + } else { + // 接收无人机数据 + videoIdentification.setCreateAt(new Date()) + .setCreateBy("SYS-无人机") + .setUpdateAt(new Date()) + .setUpdateBy("SYS-无人机"); + } + return Response.or(videoIdentificationService.saveOrUpdate(videoIdentification)); + } + + @ApiOperation("添加视频检测预警信息") + @PostMapping(value = "/addByJson") + public Response addByJson(@RequestBody VideoIdentification videoIdentification) { +// String videoReplace = videoIdentification.getVideoUrl().replace("http://120.238.185.186:2001", "https://pyzhyg.panyu.gd.cn:7673"); +// String pictureReplace = videoIdentification.getPictureUrl().replace("http://120.238.185.186:2001", "https://pyzhyg.panyu.gd.cn:7673"); +// videoIdentification.setVideoUrl(videoReplace.replace("http://120.238.185.186:2002", "https://pyzhyg.panyu.gd.cn:7673")); +// videoIdentification.setPictureUrl(pictureReplace.replace("http://120.238.185.186:2002", "https://pyzhyg.panyu.gd.cn:7673")); + return Response.or(videoIdentificationService.saveOrUpdate(videoIdentification)); + } + + @ApiOperation("添加视频检测预警信息") + @PostMapping(value = "/addByTracker") + public Response addByTracker(@RequestBody VideoIdentificationDto videoIdentificationDto) { + VideoIdentification videoIdentification = new VideoIdentification(); + BeanUtils.copyProperties(videoIdentificationDto, videoIdentification); + return Response.or(videoIdentificationService.saveOrUpdate(videoIdentification)); + } + + @ApiOperation("分页查询渔船识别记录") + @PostMapping("/findByPage") + public Response findByPage(VideoIdentificationDto videoIdentificationDto) { + IPage pageResult = videoIdentificationService.findByPage(videoIdentificationDto); + return Response.ok(pageResult); + } + + @ApiOperation("导出渔船识别记录EXCEL") + @GetMapping("/exportByCondition") + public void exportByCondition(VideoIdentificationDto videoIdentificationDto, HttpServletResponse response) throws Exception { + VideoIdentification param = new VideoIdentification(); + BeanUtils.copyProperties(videoIdentificationDto, param); + QueryWrapper queryWrapper = MybatisUtil.notNullField(param); + List list = videoIdentificationService.list(queryWrapper); + List dtoList = list + .stream() + .map(m -> { + VideoIdentificationVo dto = new VideoIdentificationVo(); + BeanUtils.copyProperties(m, dto); + return dto; + }).collect(Collectors.toList()); + ExcelUtil util = new ExcelUtil<>(VideoIdentificationVo.class); + util.exportExcel(response, "渔船识别记录", "VideoIdentification", dtoList); + } + + @ApiOperation("卡口流量趋势") + @GetMapping("/getPortTrend") + public Response getPortTrend() { + List list = Lists.newArrayList(); + Date now = DateUtils.addDays(new Date(), 1); + Date beforeDate = DateUtils.addDays(new Date(), -7); + Date dateTmp = beforeDate; + while (dateTmp.before(now)) { + PortTrendVO item = new PortTrendVO(); + item.setTimeStr(DateUtils.parseDateToStr("yyyy-MM-dd", dateTmp)); + item.setCount(Long.parseLong(new Random().nextInt(30) + 50 + "")); + list.add(item); + dateTmp = DateUtils.addDays(dateTmp, 1); + } + return Response.ok(list); + } + + @ApiOperation("识别率") + @GetMapping("/getIdentityRate") + public Response getIdentityRate(@RequestParam("type") String type) { + + int totalCount = new Random().nextInt(10) + 150; + int identityCount = new Random().nextInt(20) + 130; + if ("all".equals(type) || "year".equals(type)) { + totalCount = totalCount * 12; + identityCount = identityCount * 12; + } + String rate = (new BigDecimal(identityCount)).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP) + "%"; +// Map map = Maps.newHashMap(); +// map.put("totalCount",totalCount); +// map.put("identityCount",identityCount); +// map.put("rate",rate); + IdentityRateVO identityRateVO = new IdentityRateVO(); + identityRateVO.setTotalCount(totalCount); + identityRateVO.setIdentityCount(identityCount); + identityRateVO.setRate(rate); + return Response.ok(identityRateVO); + } + + @ApiOperation("无人机执行次数") + @GetMapping("/getVAVOperateCount") + public Response getUAVOperateCount() { + int operateCount = new Random().nextInt(5) + 10; + int autoCount = new Random().nextInt(10) + 20; +// Map map = Maps.newHashMap(); +// map.put("operateCount",operateCount); +// map.put("autoCount",autoCount); + UAVOperateCountVO uavOperateCountVO = new UAVOperateCountVO(); + uavOperateCountVO.setOperateCount(operateCount); + uavOperateCountVO.setAutoCount(autoCount); + return Response.ok(uavOperateCountVO); + } + + @ApiOperation("卡口识别累计") + @GetMapping("/getPortIdentityTotal") + public Response getPortIdentityTotal() { + int boatNameIdentityCount = new Random().nextInt(10) + 30; + int boatTypeIdentityCount = new Random().nextInt(15) + 50; + int notCloseDoorCount = new Random().nextInt(10) + 10; + int notWearSafeCount = new Random().nextInt(10) + 10; + int crossLineCount = new Random().nextInt(10) + 10; + int draftCount = new Random().nextInt(10) + 10; +// Map map = Maps.newHashMap(); +// map.put("boatNameIdentityCount",boatNameIdentityCount); +// map.put("boatTypeIdentityCount",boatTypeIdentityCount); +// map.put("notCloseDoorCount",notCloseDoorCount); +// map.put("notWearSafeCount",notWearSafeCount); +// map.put("crossLineCount",crossLineCount); +// map.put("draftCount",draftCount); + PortIdentityTotalVO portIdentityTotalVO = new PortIdentityTotalVO(boatNameIdentityCount, boatTypeIdentityCount, notCloseDoorCount, notWearSafeCount, crossLineCount, draftCount); + return Response.ok(portIdentityTotalVO); + } + + @ApiOperation("无人机识别累计") + @GetMapping("/getUAVIdentityTotal") + public Response getUAVIdentityTotal() { + int boatNameIdentityCount = new Random().nextInt(10) + 30; + int boatTypeIdentityCount = new Random().nextInt(15) + 50; + int dangerSignCount = new Random().nextInt(10) + 10; + int notCountrySignCount = new Random().nextInt(10) + 10; + int crossLineCount = new Random().nextInt(10) + 10; + int outSpeedCount = new Random().nextInt(10) + 10; + int notNormalBerthCount = new Random().nextInt(10) + 10; + int dropCount = new Random().nextInt(2); + int fireCount = new Random().nextInt(3); + int oilCount = new Random().nextInt(5) + 3; +// Map map = Maps.newHashMap(); +// map.put("boatNameIdentityCount",boatNameIdentityCount); +// map.put("boatTypeIdentityCount",boatTypeIdentityCount); +// map.put("dangerSignCount",dangerSignCount); +// map.put("notCountrySignCount",notCountrySignCount); +// map.put("crossLineCount",crossLineCount); +// map.put("outSpeedCount",outSpeedCount); +// map.put("notNormalBerthCount",notNormalBerthCount); +// map.put("dropCount",dropCount); +// map.put("fireCount", fireCount); +// map.put("oilCount", oilCount); + UAVIdentityTotalVO uavIdentityTotalVO = new UAVIdentityTotalVO(); + uavIdentityTotalVO.setBoatNameIdentityCount(boatNameIdentityCount); + uavIdentityTotalVO.setBoatTypeIdentityCount(boatTypeIdentityCount); + uavIdentityTotalVO.setDangerSignCount(dangerSignCount); + uavIdentityTotalVO.setNotCountrySignCount(notCountrySignCount); + uavIdentityTotalVO.setNotNormalBerthCount(notNormalBerthCount); + uavIdentityTotalVO.setCrossLineCount(crossLineCount); + uavIdentityTotalVO.setOutSpeedCount(outSpeedCount); + uavIdentityTotalVO.setDropCount(dropCount); + uavIdentityTotalVO.setOilCount(oilCount); + uavIdentityTotalVO.setFireCount(fireCount); + return Response.ok(uavIdentityTotalVO); + } + + @ApiOperation("航道流速信息") + @GetMapping("/getWaterwayVelocity") + public Response getWaterwayVelocity(@RequestParam("waterwayVelocity") String waterwayVelocity) { + int deepSiteCode = new Random().nextInt(10); + int radarVelocity = new Random().nextInt(15) + 50; + int radarLevel = new Random().nextInt(10) + 10; + int pressureLevel = new Random().nextInt(10) + 10; + int temperature = new Random().nextInt(10) + 10; + int angle = new Random().nextInt(10) + 10; +// Map map = Maps.newHashMap(); +// map.put("deepSiteCode",deepSiteCode); +// map.put("radarVelocity",radarVelocity); +// map.put("radarLevel",radarLevel); +// map.put("pressureLevel",pressureLevel); +// map.put("temperature",temperature); +// map.put("angle",angle); + WaterwayVelocityVO waterwayVelocityVO = new WaterwayVelocityVO(); + waterwayVelocityVO.setDeepSiteCode(deepSiteCode); + ; + waterwayVelocityVO.setRadarVelocity(radarVelocity); + waterwayVelocityVO.setRadarLevel(radarLevel); + waterwayVelocityVO.setPressureLevel(pressureLevel); + waterwayVelocityVO.setTemperature(temperature); + waterwayVelocityVO.setAngle(angle); + return Response.ok(waterwayVelocityVO); + } + + @ApiOperation("航道气象信息") + @GetMapping("/getWaterwayWeather") + public Response getWaterwayWeather(@RequestParam("waterwayVelocity") String waterwayVelocity) { + int deepSiteCode = new Random().nextInt(10); + int temperature = new Random().nextInt(15) + 50; + int humidity = new Random().nextInt(10) + 10; + int windSpeed = new Random().nextInt(10) + 10; + int windDirect = new Random().nextInt(10) + 10; + int pressure = new Random().nextInt(10) + 10; + int rainFall = new Random().nextInt(10) + 10; + int illuminance = new Random().nextInt(10) + 10; +// Map map = Maps.newHashMap(); +// map.put("deepSiteCode",deepSiteCode); +// map.put("temperature",temperature); +// map.put("humidity",humidity); +// map.put("windSpeed",windSpeed); +// map.put("windDirect",windDirect); +// map.put("pressure",pressure); +// map.put("rainFall",rainFall); +// map.put("illuminance",illuminance); + WaterwayWeatherVO waterwayWeatherVO = new WaterwayWeatherVO(); + waterwayWeatherVO.setDeepSiteCode(deepSiteCode); + waterwayWeatherVO.setTemperature(temperature); + waterwayWeatherVO.setHumidity(humidity); + waterwayWeatherVO.setWindSpeed(windSpeed); + waterwayWeatherVO.setWindDirect(windDirect); + waterwayWeatherVO.setPressure(pressure); + waterwayWeatherVO.setRainFall(rainFall); + waterwayWeatherVO.setIlluminance(illuminance); + return Response.ok(waterwayWeatherVO); + } + + /** + * 删除告警信息 + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/1 + */ + @ApiOperation("删除视频检测预警信息") + @PostMapping(value = "/removeVideoIdentification") + public Response removeVideoIdentification(@RequestBody UpdateVideoIdentificationDto req) { + return Response.or(videoIdentificationService.removeById(Long.parseLong(req.getId()))); + } + + /** + * 修改告警信息 + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/1 + */ + @ApiOperation("修改视频检测预警信息") + @PostMapping(value = "/updateVideoIdentification") + public Response updateVideoIdentification(@RequestBody UpdateVideoIdentificationDto req) { + VideoIdentification videoIdentification = new VideoIdentification(); + BeanUtils.copyProperties(req, videoIdentification); + videoIdentification.setId(Long.parseLong(req.getId())); + return Response.or(videoIdentificationService.updateById(videoIdentification)); + } +} + diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/AddStreamDetectTaskReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/AddStreamDetectTaskReq.java new file mode 100644 index 0000000..9dd6139 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/AddStreamDetectTaskReq.java @@ -0,0 +1,30 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class AddStreamDetectTaskReq { + @JsonProperty("task_id") + @ApiModelProperty("任务ID") + private String task_id; + + @JsonProperty("src_url") + @ApiModelProperty("源视频地址") + private String src_url; + + @JsonProperty("dst_url") + @ApiModelProperty("目标视频地址") + private String dst_url; + + @JsonProperty("class_codes") + @ApiModelProperty(value = "算法类别识别码,支持多个,以逗号分隔,参见识别编码统一说明") + private String class_codes; + + @JsonProperty("device_sn") + @ApiModelProperty("设备SN") + private String device_sn; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DeviceRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DeviceRespDto.java new file mode 100644 index 0000000..795dc55 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DeviceRespDto.java @@ -0,0 +1,111 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DeviceRespDto { + @JsonProperty("gateway") + @ApiModelProperty(value = "机舱") + private Gateway gateway; + @JsonProperty("drone") + @ApiModelProperty(value = "飞行器") + private Drone drone; + @Data + public static class Gateway{ + @JsonProperty("sn") + @ApiModelProperty(value = "设备sn") + private String sn; + @JsonProperty("callsign") + @ApiModelProperty(value = "设备别名") + private String callsign; + @JsonProperty("device_model") + @ApiModelProperty(value = "设备模型") + private DeviceModel deviceModel; + @JsonProperty("device_online_status") + @ApiModelProperty(value = "设备在线状态") + private boolean deviceOnlineStatus; + @JsonProperty("mode_code") + @ApiModelProperty(value = "设备模式 0:空闲中,1:现场调试,2:远程调试,3:固件升级中,4:作业中") + private Integer modeCode; + @JsonProperty("camera_list") + @ApiModelProperty(value = "相机列表") + private List cameraList; + } + @Data + public static class DeviceModel{ + @JsonProperty("key") + @ApiModelProperty(value = "Key,设备唯一标识,由domain-type-sub_type组成,详细设备类型请参考:https://developer.dji.com/doc/cloud-api-tutorial/cn/overview/product-support.html") + private String key; + @JsonProperty("domain") + @ApiModelProperty(value = "域") + private String domain; + @JsonProperty("type") + @ApiModelProperty(value = "类型") + private String type; + @JsonProperty("sub_type") + @ApiModelProperty(value = "子类型") + private String sub_type; + @JsonProperty("name") + @ApiModelProperty(value = "设备型号") + private String name; + @JsonProperty("class") + @ApiModelProperty(value = "设备分类:机场,遥控器等") + private String classs; + + } + @Data + public static class GatewayCameraList{ + @JsonProperty("camera_index") + @ApiModelProperty(value = "相机索引") + private String cameraIndex; + @JsonProperty("available_camera_positions") + @ApiModelProperty(value = "可用的相机位置 indoor:舱内摄像头 outdoor:舱外摄像头") + private List availableCameraPositions; + @JsonProperty("camera_position") + @ApiModelProperty(value = "当前相机位置") + private String cameraPosition; + + } + @Data + public static class Drone{ + @JsonProperty("sn") + @ApiModelProperty(value = "飞行器SN") + private String sn; + @JsonProperty("callsign") + @ApiModelProperty(value = "设备别名") + private String callsign; + @JsonProperty("device_model") + @ApiModelProperty(value = "设备模型") + private DeviceModel deviceModel; + @JsonProperty("device_online_status") + @ApiModelProperty(value = "设备在线状态") + private boolean deviceOnlineStatus; + @JsonProperty("mode_code") + @ApiModelProperty(value = "飞行器状态:0:待机,1:起飞准备,2:起飞准备完毕,3:手动飞行,4:自动起飞,5:航线飞行,6:全景拍照,7:智能跟随,8:ADS-B 躲避,9:自动返航,10:自动降落,11:强制降落,12:三桨叶降落,13:升级中,14:未连接,15:APAS,16:虚拟摇杆状态,17:指令飞行,18:空中 RTK 收敛模式,19:机场选址中") + private Integer modeCode; + @JsonProperty("camera_list") + @ApiModelProperty(value = "相机列表") + private List cameraList; + } + @Data + public static class DroneCameraList{ + @JsonProperty("camera_index") + @ApiModelProperty(value = "相机索引") + private String cameraIndex; + @JsonProperty("lens_list") + @ApiModelProperty(value = "镜头列表") + private List lens_list; + } + public static class LensList{ + @JsonProperty("available_lens_types") + @ApiModelProperty(value = "可用镜头类型 normal:默认镜头 wide:广角镜头 zoom:变焦镜头 ir:红外镜头") + private List availableLensTypes; + @JsonProperty("lens_type") + @ApiModelProperty(value = "当前镜头类型 normal:默认镜头 wide:广角镜头 zoom:变焦镜头 ir:红外镜头") + private String lensType; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespDto.java new file mode 100644 index 0000000..d246383 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespDto.java @@ -0,0 +1,51 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneControlObtainRespDto { + @JsonProperty("drone_sn") + @ApiModelProperty("飞行器SN") + private String drone_sn; + @JsonProperty("controls") + @ApiModelProperty("控制信息") + private List controls; + @Data + public static class Controls { + @JsonProperty("type") + @ApiModelProperty("控制权类型:flight 表示飞行控制权,payload表示 负载控制权。") + private String type; + @JsonProperty("payload_index") + @ApiModelProperty("负载索引") + private String payload_index; + @JsonProperty("gateway") + @ApiModelProperty("网关信息") + private Gateway gateway; + @JsonProperty("user") + @ApiModelProperty("用户信息") + private User user; + + } + @Data + public static class Gateway { + @JsonProperty("sn") + @ApiModelProperty("网关SN,比如机场SN") + private String sn; + } + @Data + public static class User { + @JsonProperty("call_sign") + @ApiModelProperty("用户别名") + private String call_sign; + @JsonProperty("user_id") + @ApiModelProperty("用户ID") + private String user_id; + @JsonProperty("type") + @ApiModelProperty("控制权类型,Cloud表示云端控制。") + private String type; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespV2Dto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespV2Dto.java new file mode 100644 index 0000000..7929743 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneControlObtainRespV2Dto.java @@ -0,0 +1,85 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneControlObtainRespV2Dto { + @JsonProperty("drone_sn") + @ApiModelProperty("飞行器SN") + private String drone_sn; + @JsonProperty("controls") + @ApiModelProperty("控制信息") + private List controls; + + @Data + public static class Controls { + @JsonProperty("type") + @ApiModelProperty("控制权类型:flight 表示飞行控制权,payload表示 负载控制权。") + private String type; + @JsonProperty("version") + @ApiModelProperty("控制权版本 (用于并发控制)") + private String version; + @JsonProperty("gateway") + @ApiModelProperty("网关信息") + private Gateway gateway; + @JsonProperty("user") + @ApiModelProperty("用户信息") + private User user; + @JsonProperty("key") + @ApiModelProperty("控制权限Key") + private String key; + @JsonProperty("spec") + @ApiModelProperty("控制权限的特定属性") + private Spec spec; + + } + + @Data + public static class Gateway { + @JsonProperty("sn") + @ApiModelProperty("网关SN,比如机场SN") + private String sn; + @JsonProperty("id") + @ApiModelProperty("网关ID") + private String id; + @JsonProperty("device_model_class") + @ApiModelProperty("网关设备类型") + private String device_model_class; + @JsonProperty("auth_control_keys") + @ApiModelProperty("网关正在代理的云控控制权") + private String auth_control_keys; + } + + @Data + public static class User { + @JsonProperty("call_sign") + @ApiModelProperty("用户别名") + private String call_sign; + @JsonProperty("user_id") + @ApiModelProperty("用户ID") + private String user_id; + @JsonProperty("type") + @ApiModelProperty("控制权类型,Cloud表示云端控制。") + private String type; + } + + @Data + public static class Spec { + @JsonProperty("is_cloud_control_auth") + @ApiModelProperty("是否正在等待授权") + private Boolean is_cloud_control_auth; + @JsonProperty("is_locked") + @ApiModelProperty("是否被锁定 (例如,被遥控器抢夺)") + private Boolean is_locked; + @JsonProperty("payload_index") + @ApiModelProperty("负载索引 (仅当类型为 payload 时有效)") + private String payload_index; + @JsonProperty("waiting_for_auth_user") + @ApiModelProperty("正在等待谁授权 (如果 IsCloudControlAuth 为 true)") + private String waiting_for_auth_user; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneOneTouchTakeoffRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneOneTouchTakeoffRespDto.java new file mode 100644 index 0000000..ed77da7 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneOneTouchTakeoffRespDto.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class DroneOneTouchTakeoffRespDto { + @ApiModelProperty("从起飞到降落的整体id") + @JsonProperty("flight_id") + private String flight_id; + @ApiModelProperty("单次操作的id") + @JsonProperty("fly_to_id") + private String fly_to_id; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneResponseListBase.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneResponseListBase.java new file mode 100644 index 0000000..0bbf824 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneResponseListBase.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneResponseListBase { + @JsonProperty("list") + @ApiModelProperty(value = "响应数据列表") + private List list; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneTaskRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneTaskRespDto.java new file mode 100644 index 0000000..830d51c --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneTaskRespDto.java @@ -0,0 +1,82 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class DroneTaskRespDto { + @JsonProperty("name") + @ApiModelProperty("任务名称") + private String name; + @JsonProperty("task_type") + @ApiModelProperty("任务类型:immediate:立即任务,timed:单次定时任务,recurring:重复任务,continuous:连续任务,非必填,不填写则为全部类型") + private String task_type; + @JsonProperty("status") + @ApiModelProperty("任务状态数组:waiting:待开始,starting_failure:启动失败,executing:执行中,paused: 暂停,terminated:终止,success:成功,suspended:挂起,timeout:超时,非必填,不填写则为全部状态") + private String status; + @JsonProperty("sn") + @ApiModelProperty("执行任务的设备SN") + private String sn; + @JsonProperty("landing_dock_sn") + @ApiModelProperty("任务降落的设备SN,若为空则表示仅使用一个设备") + private String landing_dock_sn; + @JsonProperty("begin_at") + @ApiModelProperty("任务设定的开始时间") + private String begin_at; + @JsonProperty("end_at") + @ApiModelProperty("任务设定的结束时间") + private String end_at; + @JsonProperty("run_at") + @ApiModelProperty("任务实际执行的时间") + private String run_at; + @JsonProperty("completed_at") + @ApiModelProperty("任务实际完成的时间") + private String completed_at; + @JsonProperty("wayline_uuid") + @ApiModelProperty("任务执行航线ID") + private String wayline_uuid; + @JsonProperty("folder_id") + @ApiModelProperty("任务关联的媒体文件夹ID") + private Integer folder_id; + @JsonProperty("current_waypoint_index") + @ApiModelProperty("任务已经飞完的航点数量") + private Integer current_waypoint_index; + @JsonProperty("total_waypoints") + @ApiModelProperty("任务的总航点数量") + private Integer total_waypoints; + @JsonProperty("media_upload_status") + @ApiModelProperty("媒体上传状态:to_upload,uploading,upload_finished") + private String media_upload_status; + @JsonProperty("resumable_status") + @ApiModelProperty("断点续飞状态:‘’-不可续飞,auto-自动续飞,manual-手动续飞") + private Boolean resumable_status; + @JsonProperty("operations") + @ApiModelProperty("任务操作记录") + private Operations operations; + @JsonProperty("exceptions") + @ApiModelProperty("异常信息") + private Exceptions exceptions; + @Data + public static class Exceptions { + @JsonProperty("code") + @ApiModelProperty("任务执行错误码") + private String code; + @JsonProperty("message") + @ApiModelProperty("错误信息") + private String message; + @JsonProperty("happen_at") + @ApiModelProperty("错误发生的时间") + private String happen_at; + @JsonProperty("sn") + @ApiModelProperty("错误发生的设备") + private String sn; + + } + @Data + public static class Operations { + @JsonProperty("operator_account") + @ApiModelProperty("任务操作者账号") + private String operator_account; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineDetailRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineDetailRespDto.java new file mode 100644 index 0000000..497e1fb --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineDetailRespDto.java @@ -0,0 +1,51 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneWayLineDetailRespDto { + @ApiModelProperty("航线唯一标识,wayline_id") + @JsonProperty("id") + private String id; + @ApiModelProperty("航线名称") + @JsonProperty("name") + private String name; + @ApiModelProperty("航线文件下载链接") + @JsonProperty("download_url") + private String downloadUrl; + @JsonProperty("payload_information") + @ApiModelProperty("负载信息列表,详细设备类型请参考:https://developer.dji.com/doc") + private List payloadInformation; + @ApiModelProperty("设备唯一标识,由domain-type-sub_type组成,详细设备类型请参考:https://developer.dji.com/doc/cloud-api-tutorial/cn/overview/product-support.html") + @JsonProperty("device_model_key") + private String deviceModelKey; + @ApiModelProperty("航线类型waypoint:航点航线 mapping_2d:建图航拍,对应司空2 中的面状航线下的正射采集 mapping_3d:倾斜摄影,对应司空2 中的面状航线下的倾斜采集 mapping_strip:带状航线 facade:斜面航线 solid:几何体航线 mapping_gobject:贴近摄影") + @JsonProperty("template_type") + private List templateType; + @ApiModelProperty("更新时间") + @JsonProperty("update_time") + private String updateTime; + @ApiModelProperty("航线长度") + @JsonProperty("distance") + private String distance; + @ApiModelProperty("航线航点个数") + @JsonProperty("wayline_point_nums") + private Integer waylinePointNums; + + @Data + public static class PayloadInformation { + @ApiModelProperty("域") + @JsonProperty("domain") + private String domain; + @ApiModelProperty("负载类型") + @JsonProperty("type") + private String type; + @ApiModelProperty("镜头类型 wide:广角,zoom:变焦,ir:红外") + @JsonProperty("lens_type") + private String lensType; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineRespDto.java new file mode 100644 index 0000000..4985058 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/DroneWayLineRespDto.java @@ -0,0 +1,41 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneWayLineRespDto { + @ApiModelProperty("航线唯一标识,wayline_id") + @JsonProperty("id") + private String id; + @ApiModelProperty("航线名称") + @JsonProperty("name") + private String name; + @JsonProperty("payload_information") + @ApiModelProperty("负载信息列表,详细设备类型请参考:https://developer.dji.com/doc") + private List payloadInformation; + @ApiModelProperty("设备唯一标识,由domain-type-sub_type组成,详细设备类型请参考:https://developer.dji.com/doc/cloud-api-tutorial/cn/overview/product-support.html") + @JsonProperty("device_model_key") + private String deviceModelKey; + @ApiModelProperty("航线类型waypoint:航点航线 mapping_2d:建图航拍,对应司空2 中的面状航线下的正射采集 mapping_3d:倾斜摄影,对应司空2 中的面状航线下的倾斜采集 mapping_strip:带状航线 facade:斜面航线 solid:几何体航线 mapping_gobject:贴近摄影") + @JsonProperty("template_type") + private List templateType; + @ApiModelProperty("更新时间") + @JsonProperty("update_time") + private String updateTime; + @Data + public static class PayloadInformation { + @ApiModelProperty("域") + @JsonProperty("domain") + private String domain; + @ApiModelProperty("负载类型") + @JsonProperty("type") + private String type; + @ApiModelProperty("镜头类型 wide:广角,zoom:变焦,ir:红外") + @JsonProperty("lens_type") + private String lensType; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/ProjectRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/ProjectRespDto.java new file mode 100644 index 0000000..ff10dde --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/ProjectRespDto.java @@ -0,0 +1,40 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ProjectRespDto { + @JsonProperty("name") + @ApiModelProperty(value = "项目名称") + private String name; + @JsonProperty("introduction") + @ApiModelProperty(value = "项目简介") + private String introduction; + @JsonProperty("uuid") + @ApiModelProperty(value = "项目uuid") + private String uuid; + @JsonProperty("org_uuid") + @ApiModelProperty(value = "组织uuid") + private String org_uuid; + @JsonProperty("created_at") + @ApiModelProperty(value = "创建时间") + private Long createdAt; + @JsonProperty("updated_at") + @ApiModelProperty(value = "更新时间") + private Long updatedAt; + @JsonProperty("project_work_center_point") + @ApiModelProperty(value = "项目作业中心点") + private ProjectWorkCenterPoint projectWorkCenterPoint; + @Data + public static class ProjectWorkCenterPoint{ + @JsonProperty("latitude") + @ApiModelProperty(value = "项目作业中心点的纬度") + private String latitude; + @JsonProperty("longitude") + @ApiModelProperty(value = "项目作业中心点的经度") + private String longitude; + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/StartLiveReqRespDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/StartLiveReqRespDto.java new file mode 100644 index 0000000..4a8d3ca --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/StartLiveReqRespDto.java @@ -0,0 +1,19 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class StartLiveReqRespDto { + @JsonProperty("expire_ts") + @ApiModelProperty("直播推流Token有效期") + private Integer expire_ts; + @ApiModelProperty("直播拉流播放地址") + @JsonProperty("url") + private String url; + @ApiModelProperty("直播推流类型") + @JsonProperty("url_type") + private String url_type; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/VideoStreamResp.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/VideoStreamResp.java new file mode 100644 index 0000000..c828c7a --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/drone/VideoStreamResp.java @@ -0,0 +1,15 @@ +package com.ltgk.smartFishingPort.domain.drone; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class VideoStreamResp { + @JsonProperty("code") + @ApiModelProperty(value = "非0表示异常") + private Integer code; + @JsonProperty("msg") + @ApiModelProperty(value = "如果任何已存在,返回:任务已存在") + private String msg; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/AlarmDataResultDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/AlarmDataResultDto.java new file mode 100644 index 0000000..75b7456 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/AlarmDataResultDto.java @@ -0,0 +1,44 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +public class AlarmDataResultDto implements Serializable { + + private static final long serialVersionUID = 1L; + + private int lCommand; + + private Object result; + + private Date alarmTime; + + public int getlCommand() { + return lCommand; + } + + public void setlCommand(int lCommand) { + this.lCommand = lCommand; + } + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getAlarmTime() { + return alarmTime; + } + + public void setAlarmTime(Date alarmTime) { + this.alarmTime = alarmTime; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/BoatDynamicDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/BoatDynamicDto.java new file mode 100644 index 0000000..1b84a96 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/BoatDynamicDto.java @@ -0,0 +1,77 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 船舶实时动态实体类 + */ +@Data +//@Document(collection = "boat_dynamic_data") +public class BoatDynamicDto implements Serializable { + + private static final long serialVersionUID = 1L; + +// @Id + private String uuid; + + //@ApiModelProperty(value = "设备类型") + private String deviceType; + +// @MongoField(condition = MongoUtil.LIKE) + //@ApiModelProperty(value = "终端号码") + private String terminalCode; + +// @MongoField(condition = MongoUtil.LIKE) + //@ApiModelProperty(value = "渔船名称") + private String boatName; + private String boatNameEn; + + //@ApiModelProperty(value = "经度") +// @Field(targetType = FieldType.DOUBLE) + private Double longitude; + + //@ApiModelProperty(value = "纬度") +// @Field(targetType = FieldType.DOUBLE) + private Double latitude; + + //@ApiModelProperty(value = "船速") + private String sog; + + //@ApiModelProperty(value = "航向") + private String cog; + + //@ApiModelProperty(value = "船艏向") + private String heading; + + //@ApiModelProperty(value = "来源") + private String dataSource; + + //@ApiModelProperty(value = "报文内容") + private String msgContent; + + //@ApiModelProperty(value = "定位时间") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date gpsTime; + + //@ApiModelProperty(value = "船长") + private BigDecimal boatLength; +// +// //@ApiModelProperty(value = "型宽") +// private BigDecimal moldedBreadth; +// +// private String shipId; +// +// private String boatLabel; +// +// private String region; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/DsArtemisDTO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/DsArtemisDTO.java new file mode 100644 index 0000000..47affff --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/DsArtemisDTO.java @@ -0,0 +1,23 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @Author: zhouyaoyao + * @Date 2025/1/22 13:42 + * Description: 综合安防平台在controller层请求参数封装参数视图 + */ +@Data +public class DsArtemisDTO { + + @ApiModelProperty("视频监控设备编号") + @NotBlank(message = "视频监控设备编号不能为空") + private String videoCode; + + @ApiModelProperty("视频流预览链接类型") + private String previewProtocol; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/LinkageParamDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/LinkageParamDto.java new file mode 100644 index 0000000..e004a94 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/LinkageParamDto.java @@ -0,0 +1,25 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/4/2 17:49 + * Description: 光电联动功能调试参数对象 + */ +@Data +public class LinkageParamDto implements Serializable { + + /** + * 视频监控设备与联动目标的距离(公里) + */ + private Double distance; + + /** + * 偏移量值 + */ + private Double number; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/UpdateVideoIdentificationDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/UpdateVideoIdentificationDto.java new file mode 100644 index 0000000..6866f4b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/UpdateVideoIdentificationDto.java @@ -0,0 +1,150 @@ +package com.ltgk.smartFishingPort.domain.dto; + + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 更新监控识别告警记录对象 + * + * @author Qi ChengBin + * @date 2025/12/01 + */ +@Data +@Accessors(chain = true) +public class UpdateVideoIdentificationDto { + + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "识别类型(船体识别、船号识别)") + private String identificationType; + + @ApiModelProperty(value = "抓拍类型(无人机、卡口)") + private String takeType; + + @ApiModelProperty(value = "违规类型") + private String illegalType; + + @ApiModelProperty(value = "有无AIS信号") + private String isHasAis; + + @ApiModelProperty(value = "mmsi") + private String mmsi; + + @ApiModelProperty(value = "AIS状态") + private String aisStatus; + + @ApiModelProperty(value = "船舶名称") + private String boatName; + + @ApiModelProperty(value = "船舶英文名称") + private String boatNameEn; + + @ApiModelProperty(value = "摄像头名称") + private String videoName; + + @ApiModelProperty(value = "进出港方向(进港、出港)") + private String entryOut; + + @ApiModelProperty(value = "航向") + private String cog; + + @ApiModelProperty(value = "街道") + private String streetName; + + @ApiModelProperty(value = "原始图片保存路径") + private String sourcePicPath; + + @ApiModelProperty(value = "识别图片保存路径") + private String trackerPicPath; + + @ApiModelProperty(value = "船牌图片保存路径") + private String boatCodePath; + + @ApiModelProperty(value = "抓拍视频链接") + private String videoUrl; + + @ApiModelProperty(value = "抓拍时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date takeTime; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "创建日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑人") + private String updateBy; + + @ApiModelProperty(value = "编辑日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "海康识别船名") + private String hkResult; + + @ApiModelProperty(value = "系统识别船名") + private String sysShipName; + + @ApiModelProperty(value = "系统更正标注船名") + private String sysUpdateName; + + @ApiModelProperty(value = "系统识别结果正误") + private String systemResult; + + @ApiModelProperty(value = "船型") + private String shipType; + + @ApiModelProperty(value = "经度") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + private BigDecimal latitude; + + @ApiModelProperty(value = "救生衣状态") + private String jacketStatus; + + @ApiModelProperty("船只长度") + private BigDecimal length; + + @ApiModelProperty("船只高度") + private BigDecimal height; + + @ApiModelProperty("船只高度范围") + private String heightRange; + + @ApiModelProperty("船只速度") + private BigDecimal speed; + + @ApiModelProperty("船只宽度") + private BigDecimal width; + + @ApiModelProperty(value = "所属港口") + private String belongPort; + + @ApiModelProperty("是否关闭舱门") + private String isCloseDoor; + + @ApiModelProperty("越线偏航时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date crossLineTime; + + @ApiModelProperty("吃水刻度") + private BigDecimal draftMarks; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoIdentificationDto.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoIdentificationDto.java new file mode 100644 index 0000000..4d13101 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoIdentificationDto.java @@ -0,0 +1,316 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import com.baomidou.mybatisplus.annotation.SqlCondition; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ltgk.smartFishingPort.utils.DateTimeConverter; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@ColumnWidth(25) +@HeadRowHeight(20) +@ContentRowHeight(18) +public class VideoIdentificationDto implements Serializable { + + private static final long serialVersionUID=1L; + + @ExcelProperty(value = "摄像头名称") + @ApiModelProperty(value = "摄像头名称") + private String videoName; + + @ExcelProperty(value = "抓拍时间", converter = DateTimeConverter.class) + @ApiModelProperty(value = "抓拍时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date takeTime; + + @ApiModelProperty("抓拍时间-开始查询条件") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date beginTime; + + @ApiModelProperty("抓拍时间-结束查询条件") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endTime; + + @ExcelProperty(value = "所属港口") + @ApiModelProperty(value = "所属港口") + @TableField(value = "belong_port",condition = SqlCondition.LIKE) + private String belongPort; + + @ExcelProperty(value = "船舶类型") + @ApiModelProperty(value = "船舶类型") + private String shipType; + + @ExcelProperty(value = "船只长度") + @ApiModelProperty("船只长度") + private BigDecimal length; + + @ExcelProperty(value = "船只高度") + @ApiModelProperty("船只高度") + private BigDecimal height; + + @ExcelProperty(value = "船只高度范围") + @ApiModelProperty("船只高度范围") + private String heightRange; + + @ExcelProperty(value = "船只速度") + @ApiModelProperty("船只速度") + private BigDecimal speed; + + @ExcelProperty(value = "进出港方向") + @ApiModelProperty(value = "进出港方向(进港、出港)") + private String entryOut; + + @ExcelProperty(value = "经度") + @ApiModelProperty(value="经度") + private BigDecimal longitude; + + @ExcelProperty(value = "纬度") + @ApiModelProperty(value = "纬度") + private BigDecimal latitude; + + @ExcelProperty(value = "救生衣状态") + @ApiModelProperty(value = "救生衣状态") + private String jacketStatus; + + @ApiModelProperty(value = "原始图片保存路径") + private String sourcePicPath; + + @ApiModelProperty(value = "识别图片保存路径") + private String trackerPicPath; + + @ApiModelProperty(value = "船牌图片保存路径") + private String boatCodePath; + + @ExcelProperty(value = "船舶名称") + @ApiModelProperty(value = "船舶名称") + @TableField(value = "belong_port",condition = SqlCondition.LIKE) + private String boatName; + + @ExcelProperty(value = "识别类型") + @ApiModelProperty(value = "识别类型(船脸识别、船牌识别)") + private String identificationType; + + @ApiModelProperty("页容量") + private Integer pageSize; + + @ApiModelProperty("页码") + private Integer pageNo; + + @TableField(exist = false) + private BigDecimal distance; + + public BigDecimal getLength() { + return length; + } + + public void setLength(BigDecimal length) { + this.length = length; + } + + public String getVideoName() { + return videoName; + } + + public void setVideoName(String videoName) { + this.videoName = videoName; + } + + public Date getTakeTime() { + return takeTime; + } + + public void setTakeTime(Date takeTime) { + this.takeTime = takeTime; + } + + public Date getBeginTime() { + return beginTime; + } + + public void setBeginTime(Date beginTime) { + this.beginTime = beginTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public String getBelongPort() { + return belongPort; + } + + public void setBelongPort(String belongPort) { + this.belongPort = belongPort; + } + + public String getShipType() { + return shipType; + } + + public void setShipType(String shipType) { + this.shipType = shipType; + } + + public BigDecimal getHeight() { + return height; + } + + public void setHeight(BigDecimal height) { + this.height = height; + } + + public String getHeightRange() { + return heightRange; + } + + public void setHeightRange(String heightRange) { + this.heightRange = heightRange; + } + + public BigDecimal getSpeed() { + return speed; + } + + public void setSpeed(BigDecimal speed) { + this.speed = speed; + } + + public String getEntryOut() { + return entryOut; + } + + public void setEntryOut(String entryOut) { + this.entryOut = entryOut; + } + + public BigDecimal getLongitude() { + return longitude; + } + + public void setLongitude(BigDecimal longitude) { + this.longitude = longitude; + } + + public BigDecimal getLatitude() { + return latitude; + } + + public void setLatitude(BigDecimal latitude) { + this.latitude = latitude; + } + + public String getJacketStatus() { + return jacketStatus; + } + + public void setJacketStatus(String jacketStatus) { + this.jacketStatus = jacketStatus; + } + + public String getSourcePicPath() { + return sourcePicPath; + } + + public void setSourcePicPath(String sourcePicPath) { + this.sourcePicPath = sourcePicPath; + } + + public String getTrackerPicPath() { + return trackerPicPath; + } + + public void setTrackerPicPath(String trackerPicPath) { + this.trackerPicPath = trackerPicPath; + } + + public String getBoatCodePath() { + return boatCodePath; + } + + public void setBoatCodePath(String boatCodePath) { + this.boatCodePath = boatCodePath; + } + + public String getBoatName() { + return boatName; + } + + public void setBoatName(String boatName) { + this.boatName = boatName; + } + + public String getIdentificationType() { + return identificationType; + } + + public void setIdentificationType(String identificationType) { + this.identificationType = identificationType; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public Integer getPageNo() { + return pageNo; + } + + public void setPageNo(Integer pageNo) { + this.pageNo = pageNo; + } + + public BigDecimal getDistance() { + return distance; + } + + public void setDistance(BigDecimal distance) { + this.distance = distance; + } + + @ApiModelProperty(value = "航向") + private String cog; + + @ApiModelProperty(value = "抓拍类型(无人机、卡口)") + private String takeType; + + @ApiModelProperty(value = "违规类型") + private String illegalType; + + @ApiModelProperty(value = "有无AIS信号") + private String isHasAis; + + @ApiModelProperty(value = "AIS信号") + private String mmsi; + + @ApiModelProperty(value = "AIS状态") + private String aisStatus; + + @ApiModelProperty(value = "船舶英文名称") + @TableField("boat_name_en") + private String boatNameEn; + + @ApiModelProperty(value = "街道") + @TableField("street_name") + private String streetName; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoServoDTO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoServoDTO.java new file mode 100644 index 0000000..c8ece3e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/dto/VideoServoDTO.java @@ -0,0 +1,30 @@ +package com.ltgk.smartFishingPort.domain.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @Author: zhouyaoyao + * @Date 2025/2/27 16:09 + * Description: + */ +@Data +@Accessors(chain = true) +public class VideoServoDTO { + /** + * 监控设备编号 + */ + private String deviceCode; + /** + * 联动目标终端号 + */ + private String terminalCode; + /** + * 联动目标经度 + */ + private String gpsX; + /** + * 联动目标纬度 + */ + private String gpsY; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatData.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatData.java new file mode 100644 index 0000000..146c4cc --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatData.java @@ -0,0 +1,133 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Author: zhouyaoyao + * @Date 2025/6/10 17:49 + * Description: + */ + +@TableName("haishiju.boat_data") +@Data +public class BoatData implements Serializable { + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 类型 */ + @ApiModelProperty(value = "类型") + private String type; + + /** 船号 */ + @ApiModelProperty(value = "船号") + private String boatName; + + /** 设备编号 */ + @ApiModelProperty(value = "设备编号") + private String boatCode; + + /** 船主 */ + @ApiModelProperty(value = "船主") + private String boatOwner; + + /** 手机 */ + @ApiModelProperty(value = "手机") + private String ownerPhone; + + /** 身份证号码 */ + @ApiModelProperty(value = "身份证号码") + private String ownerIdcard; + + /** 所在县区 */ + @ApiModelProperty(value = "所在县区") + private String county; + + /** 所在乡镇 */ + @ApiModelProperty(value = "所在乡镇") + private String town; + + /** 所在村委 */ + @ApiModelProperty(value = "所在村委") + private String village; + + /** 详细地址 */ + @ApiModelProperty(value = "详细地址") + private String address; + + /** 归属地 */ + @ApiModelProperty(value = "归属地") + private String belongArea; + + /** 设备厂商 */ + @ApiModelProperty(value = "设备厂商") + private String factory; + + /** 船舶类型 */ + @ApiModelProperty(value = "船舶类型") + private String boatType; + + /** 作业类型 */ + @ApiModelProperty(value = "作业类型") + private String jobType; + + /** 船体材质 */ + @ApiModelProperty(value = "船体材质") + private String material; + + /** 长(米) */ + @ApiModelProperty(value = "长") + private Long length; + + /** 宽(米) */ + @ApiModelProperty(value = "宽") + private Long width; + + /** 深(米) */ + @ApiModelProperty(value = "深") + private Long deep; + + /** 安装日期 */ + @ApiModelProperty(value = "安装日期") + private String installDate; + + /** 删除标记 */ + private Integer delFlag; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + /** + * 页容量 + */ + @TableField(exist = false) + private Integer pageSize; + + /** + * 页码 + */ + @TableField(exist = false) + private Integer pageNum; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatDynamic.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatDynamic.java new file mode 100644 index 0000000..9ce950e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatDynamic.java @@ -0,0 +1,81 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 船舶实时动态实体类 + */ +@Accessors(chain = true) +@Data +@TableName("haishiju.boat_dynamic") +public class BoatDynamic implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "uuid",type = IdType.ASSIGN_UUID) + private String uuid; + + @ApiModelProperty(value = "设备类型") + private String deviceType; + +// @MongoField(condition = MongoUtil.LIKE) + @ApiModelProperty(value = "终端号码") + private String terminalCode; + +// @MongoField(condition = MongoUtil.LIKE) + @ApiModelProperty(value = "渔船名称") + private String boatName; + + @ApiModelProperty(value = "渔船英文名称") + private String boatNameEn; + + @ApiModelProperty(value = "经度") +// @Field(targetType = FieldType.DOUBLE) + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") +// @Field(targetType = FieldType.DOUBLE) + private BigDecimal latitude; + + @ApiModelProperty(value = "船速") + private String sog; + + @ApiModelProperty(value = "航向") + private String cog; + + @ApiModelProperty(value = "船艏向") + private String heading; + + @ApiModelProperty(value = "来源") + private String dataSource; + + @ApiModelProperty(value = "定位时间") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date gpsTime; + + @ApiModelProperty(value = "船长") + private BigDecimal boatLength; + + @ApiModelProperty(value = "型宽") + private BigDecimal modelWidth; + + private String region; + + @ApiModelProperty("原始报文") + private String msg; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatPath.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatPath.java new file mode 100644 index 0000000..51e7e98 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/BoatPath.java @@ -0,0 +1,94 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 船舶轨迹表 + *

+ * + * @author zhou + * @since 2022-10-22 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +@TableName("haishiju.boat_path") +@ApiModel(value = "BoatPath对象", description = "船舶轨迹表") +public class BoatPath extends Model { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "UUID") + @TableId(value = "uuid", type = IdType.ASSIGN_UUID) + private String uuid; + + @ApiModelProperty(value = "定位设备类型") + @TableField("device_type") + private String deviceType; + + @ApiModelProperty(value = "定位设备终端号") + @TableField("terminal_code") + private String terminalCode; + + @ApiModelProperty(value = "船舶名称") + @TableField("boat_name") + private String boatName; + + @ApiModelProperty(value = "经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "速度") + @TableField("sog") + private String sog; + + @ApiModelProperty(value = "航向") + @TableField("cog") + private String cog; + + @ApiModelProperty(value = "船艏向") + @TableField("heading") + private String heading; + + @ApiModelProperty(value = "定位时间") + @TableField("gps_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date gpsTime; + + @ApiModelProperty(value = "创建时间") + @TableField("create_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + + @Override + public Serializable pkVal() { + return this.uuid; + } + + @TableField(exist = false) + private String bs; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/DsVideo.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/DsVideo.java new file mode 100644 index 0000000..8b46429 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/DsVideo.java @@ -0,0 +1,238 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 视频监控管理表 + *

+ * + * @author zhouyaoyao + * @since 2025-01-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("haishiju.ds_video") +@ApiModel(value = "DsVideo对象", description = "视频监控管理表") +public class DsVideo extends Model { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + @ApiModelProperty(value = "监控编号") + @TableField(value = "video_code", condition = SqlCondition.LIKE) + private String videoCode; + + @ApiModelProperty(value = "监控名称") + @TableField(value = "video_name", condition = SqlCondition.LIKE) + private String videoName; + + @ApiModelProperty(value = "监控坐标经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "监控坐标纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "监控安装高度(米)") + @TableField("height") + private BigDecimal height; + + @ApiModelProperty(value = "可视距离(公里)") + @TableField("vision_distance") + private BigDecimal visionDistance; + + @ApiModelProperty(value = "设备ip") + @TableField("video_ip") + private String videoIp; + + @ApiModelProperty(value = "设备端口号") + @TableField("video_port") + private String videoPort; + + @ApiModelProperty(value = "设备账号") + @TableField("video_account") + private String videoAccount; + + @ApiModelProperty(value = "设备密码") + @TableField("video_password") + private String videoPassword; + + @ApiModelProperty(value = "通道号") + @TableField("channel_no") + private String channelNo; + + @ApiModelProperty(value = "所属渔港") + @TableField(value = "belong_port", condition = SqlCondition.LIKE) + private String belongPort; + + @ApiModelProperty(value = "监控类型(球机、云台)") + @TableField("video_type") + private String videoType; + + @ApiModelProperty(value = "镜头传感器类型(可见光、热成像)") + @TableField("sensor_type") + private String sensorType; + + @ApiModelProperty(value = "监管所属单位") + @TableField(value = "belong_unit", condition = SqlCondition.LIKE) + private String belongUnit; + + @ApiModelProperty(value = "运行状态") + @TableField("run_status") + private String runStatus; + + @ApiModelProperty(value = "备注") + @TableField("remarks") + private String remarks; + + @ApiModelProperty(value = "创建时间") + @TableField("create_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑时间") + @TableField("update_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "编辑人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "报警划线坐标") + @TableField("line_point") + private String linePoint; + + @ApiModelProperty(value = "视频预览链接") + @TableField("video_url") + private String videoUrl; + + @ApiModelProperty(value = "是否智能识别渔船") + @TableField("is_analysis_boat") + private String isAnalysisBoat; + + @ApiModelProperty(value = "删除标记") + @TableField("del_flag") + @TableLogic(delval = "1", value = "0") + @JsonIgnore + private Integer delFlag; + + @ApiModelProperty(value = "行政区域编码") + private String areaCode; + + @ApiModelProperty(value = "行政区域名称") + private String areaName; + /** + * 页容量 + */ + @TableField(exist = false) + @JsonIgnore + private Integer pageSize; + + /** + * 页码 + */ + @TableField(exist = false) + @JsonIgnore + private Integer pageNum; + + /** + * 热成像设备最大变倍参数 + */ + @ApiModelProperty("热成像设备最大变倍参数") + private Double zRcxVal; + + /** + * 俯仰角调节参数 + */ + @ApiModelProperty("俯仰角调节参数") + private Double yVal; + private String yValArr; + + /** + * 水平旋转调节参数 + */ + @ApiModelProperty("水平旋转调节参数") + private Double xVal; + private String xValArr; + + /** + * 距离与变倍参数换算参数 + */ + @ApiModelProperty("距离与变倍参数换算参数") + private Double zNumVal; + private String zNumValArr; + + /** + * 水平遮挡方位角区间 + */ + @ApiModelProperty("水平遮挡方位角区间") + private String xRotateVal; + + /** + * 可见光设备变倍最大参数 + */ + @ApiModelProperty("可见光设备变倍最大参数") + private Double zMaxVal; + + /** + * 监控顺逆时针旋转参数 -1: 旋转角度大于零,顺时针右侧旋转 旋转角度小于零,逆时针左侧旋转;1: 旋转角度大于零,逆时针右侧旋转 旋转角度小于零,顺时针左侧旋转 + */ + private Integer rotateT; + + /** + * 监控设备与联动目标的实际距离 + */ + @TableField(exist = false) + private BigDecimal distance; + /** + * 监控设备与联动目标的距离(对比可视距离后) + */ + @TableField(exist = false) + private double distanceVal; + /** + * 监控设备与联动目标的距离(对比遮挡范围后) + */ + @TableField(exist = false) + private BigDecimal distance1; + + @ApiModelProperty(value = "是否卡口;1-是,0-否") + @TableField("be_bayonet") + private Integer beBayonet; + + @ApiModelProperty(value = "是否锁定;1-是,0-否") + @TableField("be_lock") + private Integer beLock; + + @TableField(exist = false) + private JSONObject PTZCfg; + + @ApiModelProperty(value = "是否开启可视范围;1-是,0-否") + @TableField(value = "whether_to_turn_on_the_view") + private Integer whetherToTurnOnTheView; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EmergencyRescue.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EmergencyRescue.java new file mode 100644 index 0000000..3b2dce9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EmergencyRescue.java @@ -0,0 +1,195 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.google.common.collect.Lists; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; +import java.util.List; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 15:17 + * Description: + */ + +@TableName("haishiju.emergency_rescue") +@ApiModel("应急救援事故实体类") +@Data +public class EmergencyRescue extends Model { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + @ApiModelProperty("id") + private String id; + + /** + * 经度 + */ + @ApiModelProperty("经度") + private String longitude; + + /** + * 纬度 + */ + @ApiModelProperty("纬度") + private String latitude; + + /** + * 事故船只 + */ + @ApiModelProperty("事故船只") + private String accidentShip; + + /** + * 发生时间 + */ + @ApiModelProperty("发生时间") + private Date happenTime; + + /** + * 应急预案状态(①应急救援预案 ②制定救援计划 ③实时救援监控 ④救援后期处置 ⑤已处置) + */ + @ApiModelProperty("应急预案状态(“1” 未处置 “2”已处置)") + private String emergencyStatus; + + /** + * 事故名称 + */ + @ApiModelProperty("事故名称") + private String accidentName; + + /** + * 渔区 + */ + @ApiModelProperty("渔区") + private String fishingArea; + + /** + * 渔船信息 + */ + @TableField(exist = false) + private List shipinfoNewList = Lists.newArrayList(); + + /** + * 事故类型 + */ + @ApiModelProperty("事故类型") + private String accidentType; + + /** + * 事故描述 + */ + @ApiModelProperty("事故描述") + private String accidentBrief; + + /** + * 创建时间 + */ + @TableField(value = "create_time", fill = FieldFill.INSERT) + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 创建用户 + */ + private Long createUser; + + /** + * 修改时间 + */ + @TableField(value = "update_time") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 修改用户 + */ + private Long updateUser; + + /** + * 处置结果 + */ + @ApiModelProperty("处置结果") + private String disposeResult; + + /** + * 完成时间 + */ + @ApiModelProperty("完成时间") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date completeTime; + + /** + * 人员伤亡 + */ + @ApiModelProperty("人员伤亡") + private String casualties; + + /** + * 财产损失情况 + */ + @ApiModelProperty("财产损失情况") + private String propertyDamage; + + /** + * 参与救援船只 + */ + @ApiModelProperty("参与救援船只") + private String rescueShip; + + /** + * 备注 + */ + @ApiModelProperty("备注") + private String remark; + +// /** +// * 材料文件信息列表 +// */ +// @TableField(exist = false) +// @ApiModelProperty("材料文件信息列表,返回材料文件信息") +// private List materialsFileList; +// +// /** +// * 现场照片文件信息列表 +// */ +// @TableField(exist = false) +// @ApiModelProperty("现场照片文件信息列表,返回现场照片文件信息") +// private List sitePhotosFileList; +// +// /** +// * 事故报告文件信息列表 +// */ +// @TableField(exist = false) +// @ApiModelProperty("事故报告文件信息列表,返回事故报告文件信息") +// private List accidentReportFileList; + + /** + * 页容量 + */ + @TableField(exist = false) + private Integer pageSize; + + /** + * 页码 + */ + @TableField(exist = false) + private Integer pageNum; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EnvEquipment.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EnvEquipment.java new file mode 100644 index 0000000..d867f0e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/EnvEquipment.java @@ -0,0 +1,181 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 监控设备表 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +@TableName("haishiju.env_equipment") +@ApiModel(value="EnvEquipment对象", description="环境检测设备表") +public class EnvEquipment extends Model { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "监控编号") + @TableField("video_code") + private String videoCode; + + @ApiModelProperty(value = "视频源类型") + @TableField("source_type") + private String sourceType; + + @ApiModelProperty(value = "摄像头名称") + @TableField("video_name") + private String videoName; + + @ApiModelProperty(value = "摄像头类型") + @TableField("video_type") + private String videoType; + + @ApiModelProperty(value = "摄像头图片") + @TableField("video_image") + private String videoImage; + + @ApiModelProperty(value = "录入单位") + @TableField("depart_name") + private String departName; + + @ApiModelProperty(value = "录入单位ID") + @TableField("depart_id") + private String departId; + + @ApiModelProperty(value = "经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "运行状态(正常、不正常)") + @TableField("run_status") + private String runStatus; + + @ApiModelProperty(value = "布设区域") + @TableField("layout_area") + private String layoutArea; + + @ApiModelProperty(value = "联网类型(政务网)") + @TableField("innet_type") + private String innetType; + + @ApiModelProperty(value = "摄像头所属单位") + @TableField("video_belong") + private String videoBelong; + + @ApiModelProperty(value = "监控范围") + @TableField("range_info") + private String rangeInfo; + + @ApiModelProperty(value = "视频预览链接") + @TableField("preview_url") + private String previewUrl; + + @ApiModelProperty(value = "是否在使用") + @TableField("is_available") + private String isAvailable; + + @ApiModelProperty(value = "传感器类型(可见光、热成像)") + @TableField("sensor_type") + private String sensorType; + + @ApiModelProperty(value = "是否全景") + @TableField("is_ar") + private Integer isAr; + + @ApiModelProperty(value = "是否用于智能分析") + @TableField("is_analyze") + private Integer isAnalyze; + + @ApiModelProperty(value = "报警视频名称") + @TableField("alarm_video_name") + private String alarmVideoName; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "编辑人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "创建日期") + @TableField("create_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑日期") + @TableField("update_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "删除标记") + @TableField("del_flag") + private Integer delFlag; + + @ApiModelProperty(value = "备注") + @TableField("remark") + private String remark; + + @ApiModelProperty(value = "回访功能0启用1未启用") + @TableField("play_back") + private Integer playBack; + + /** + * 摄像头ip + */ + private String videosIp; + + /** + * 摄像头端口 + */ + private String videosPort; + + /** + * 摄像头账户 + */ + private String videosAccount; + + /** + * 摄像头密码 + */ + private String videosPass; + + @Override + public Serializable pkVal() { + return this.id; + } + + private Integer isSdkControl; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/UavEquipment.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/UavEquipment.java new file mode 100644 index 0000000..c252efe --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/UavEquipment.java @@ -0,0 +1,203 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 监控设备表 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +@TableName("haishiju.uav_equipment") +@ApiModel(value="UavEquipment对象", description="无人机设备表") +public class UavEquipment extends Model { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "监控编号") + @TableField("video_code") + private String videoCode; + + @ApiModelProperty(value = "视频源类型") + @TableField("source_type") + private String sourceType; + + @ApiModelProperty(value = "摄像头名称") + @TableField("video_name") + private String videoName; + + @ApiModelProperty(value = "摄像头类型") + @TableField("video_type") + private String videoType; + + @ApiModelProperty(value = "摄像头图片") + @TableField("video_image") + private String videoImage; + + @ApiModelProperty(value = "录入单位") + @TableField("depart_name") + private String departName; + + @ApiModelProperty(value = "录入单位ID") + @TableField("depart_id") + private String departId; + + @ApiModelProperty(value = "经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "运行状态(正常、不正常)") + @TableField("run_status") + private String runStatus; + + @ApiModelProperty(value = "布设区域") + @TableField("layout_area") + private String layoutArea; + + @ApiModelProperty(value = "联网类型(政务网)") + @TableField("innet_type") + private String innetType; + + @ApiModelProperty(value = "摄像头所属单位") + @TableField("video_belong") + private String videoBelong; + + @ApiModelProperty(value = "监控范围") + @TableField("range_info") + private String rangeInfo; + + @ApiModelProperty(value = "视频预览链接") + @TableField("preview_url") + private String previewUrl; + + @ApiModelProperty(value = "是否在使用") + @TableField("is_available") + private String isAvailable; + + @ApiModelProperty(value = "传感器类型(可见光、热成像)") + @TableField("sensor_type") + private String sensorType; + + @ApiModelProperty(value = "是否全景") + @TableField("is_ar") + private Integer isAr; + + @ApiModelProperty(value = "是否用于智能分析") + @TableField("is_analyze") + private Integer isAnalyze; + + @ApiModelProperty(value = "报警视频名称") + @TableField("alarm_video_name") + private String alarmVideoName; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "编辑人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "创建日期") + @TableField("create_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑日期") + @TableField("update_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "删除标记") + @TableField("del_flag") + private Integer delFlag; + + @ApiModelProperty(value = "备注") + @TableField("remark") + private String remark; + + @ApiModelProperty(value = "回访功能0启用1未启用") + @TableField("play_back") + private Integer playBack; + + /** + * 摄像头ip + */ + private String videosIp; + + /** + * 摄像头端口 + */ + private String videosPort; + + /** + * 摄像头账户 + */ + private String videosAccount; + + /** + * 摄像头密码 + */ + private String videosPass; + + @Override + public Serializable pkVal() { + return this.id; + } + + private Integer isSdkControl; + @JsonProperty("gatewaySn") + @ApiModelProperty(value = "机巢sn") + @TableField("gateway_sn") + private String gatewaySn; + @JsonProperty("droneSn") + @ApiModelProperty(value = "无人机sn") + @TableField("drone_sn") + private String droneSn; + @JsonProperty("systemUuid") + @ApiModelProperty(value = "系统uuid") + @TableField("system_uuid") + private String systemUuid; + @ApiModelProperty(value = "海波高度") + @TableField("altitude") + @JsonProperty("altitude") + private BigDecimal altitude; + @ApiModelProperty(value = "离地高度") + @TableField("height") + @JsonProperty("height") + private BigDecimal height; + + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoCamera.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoCamera.java new file mode 100644 index 0000000..8f00c2d --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoCamera.java @@ -0,0 +1,181 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 监控设备表 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +@TableName("haishiju.video_camera") +@ApiModel(value="VideoCamera对象", description="监控设备表") +public class VideoCamera extends Model { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "监控编号") + @TableField("video_code") + private String videoCode; + + @ApiModelProperty(value = "视频源类型") + @TableField("source_type") + private String sourceType; + + @ApiModelProperty(value = "摄像头名称") + @TableField("video_name") + private String videoName; + + @ApiModelProperty(value = "摄像头类型") + @TableField("video_type") + private String videoType; + + @ApiModelProperty(value = "摄像头图片") + @TableField("video_image") + private String videoImage; + + @ApiModelProperty(value = "录入单位") + @TableField("depart_name") + private String departName; + + @ApiModelProperty(value = "录入单位ID") + @TableField("depart_id") + private String departId; + + @ApiModelProperty(value = "经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "运行状态(正常、不正常)") + @TableField("run_status") + private String runStatus; + + @ApiModelProperty(value = "布设区域") + @TableField("layout_area") + private String layoutArea; + + @ApiModelProperty(value = "联网类型(政务网)") + @TableField("innet_type") + private String innetType; + + @ApiModelProperty(value = "摄像头所属单位") + @TableField("video_belong") + private String videoBelong; + + @ApiModelProperty(value = "监控范围") + @TableField("range_info") + private String rangeInfo; + + @ApiModelProperty(value = "视频预览链接") + @TableField("preview_url") + private String previewUrl; + + @ApiModelProperty(value = "是否在使用") + @TableField("is_available") + private String isAvailable; + + @ApiModelProperty(value = "传感器类型(可见光、热成像)") + @TableField("sensor_type") + private String sensorType; + + @ApiModelProperty(value = "是否全景") + @TableField("is_ar") + private Integer isAr; + + @ApiModelProperty(value = "是否用于智能分析") + @TableField("is_analyze") + private Integer isAnalyze; + + @ApiModelProperty(value = "报警视频名称") + @TableField("alarm_video_name") + private String alarmVideoName; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "编辑人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "创建日期") + @TableField("create_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑日期") + @TableField("update_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "删除标记") + @TableField("del_flag") + private Integer delFlag; + + @ApiModelProperty(value = "备注") + @TableField("remark") + private String remark; + + @ApiModelProperty(value = "回访功能0启用1未启用") + @TableField("play_back") + private Integer playBack; + + /** + * 摄像头ip + */ + private String videosIp; + + /** + * 摄像头端口 + */ + private String videosPort; + + /** + * 摄像头账户 + */ + private String videosAccount; + + /** + * 摄像头密码 + */ + private String videosPass; + + @Override + public Serializable pkVal() { + return this.id; + } + + private Integer isSdkControl; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoIdentification.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoIdentification.java new file mode 100644 index 0000000..4476b08 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/entity/VideoIdentification.java @@ -0,0 +1,218 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 监控识别记录表 + *

+ * + * @author zhou + * @since 2024-12-10 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) + +@TableName("haishiju.video_identification") +@ApiModel(value="VideoIdentification对象", description="监控识别记录表") +public class VideoIdentification extends Model { + + private static final long serialVersionUID=1L; + + @ApiModelProperty(value = "主键") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "识别类型(船体识别、船号识别)") + @TableField("identification_type") + private String identificationType; + + @ApiModelProperty(value = "抓拍类型(无人机、卡口)") + @TableField("take_type") + private String takeType; + + @ApiModelProperty(value = "违规类型") + @TableField(value = "illegal_type",condition = SqlCondition.LIKE) + private String illegalType; + + @ApiModelProperty(value = "有无AIS信号") + @TableField("is_has_ais") + private String isHasAis; + + @ApiModelProperty(value = "mmsi") + @TableField("mmsi") + private String mmsi; + + @ApiModelProperty(value = "AIS状态") + @TableField("ais_status") + private String aisStatus; + + @ApiModelProperty(value = "船舶名称") + @TableField(value = "boat_name",condition = SqlCondition.LIKE) + private String boatName; + + @ApiModelProperty(value = "船舶英文名称") + @TableField("boat_name_en") + private String boatNameEn; + + @ApiModelProperty(value = "摄像头名称") + @TableField(value = "video_name",condition = SqlCondition.LIKE) + private String videoName; + + @TableField(exist = false) + private String videoCode; + + @ApiModelProperty(value = "进出港方向(进港、出港)") + @TableField("entry_out") + private String entryOut; + + @ApiModelProperty(value = "航向") + @TableField("cog") + private String cog; + + @ApiModelProperty(value = "街道") + @TableField("street_name") + private String streetName; + + @ApiModelProperty(value = "原始图片保存路径") + @TableField("source_pic_path") + private String sourcePicPath; + + @ApiModelProperty(value = "识别图片保存路径") + @TableField("tracker_pic_path") + private String trackerPicPath; + + @ApiModelProperty(value = "船牌图片保存路径") + @TableField("boat_code_path") + private String boatCodePath; + + @ApiModelProperty(value = "抓拍视频链接") + @TableField("video_url") + private String videoUrl; + + @ApiModelProperty(value = "抓拍时间") + @TableField("take_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date takeTime; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "创建日期") + @TableField("create_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createAt; + + @ApiModelProperty(value = "编辑人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "编辑日期") + @TableField("update_at") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateAt; + + @ApiModelProperty(value = "删除标记") + @TableField("del_flag") + @TableLogic(value = "0", delval = "1") + private Integer delFlag; + + @ApiModelProperty(value = "海康识别船名") + @TableField("hk_result") + private String hkResult; + + @TableField("sys_ship_name") + @ApiModelProperty(value = "系统识别船名") + private String sysShipName; + + @TableField("sys_update_name") + @ApiModelProperty(value = "系统更正标注船名") + private String sysUpdateName; + + @TableField("system_result") + @ApiModelProperty(value = "系统识别结果正误") + private String systemResult; + + @ApiModelProperty(value = "船型") + @TableField("ship_type") + private String shipType; + + @Override + public Serializable pkVal() { + return this.id; + } + + @ApiModelProperty(value="经度") + @TableField("longitude") + private BigDecimal longitude; + + @ApiModelProperty(value = "纬度") + @TableField("latitude") + private BigDecimal latitude; + + @ApiModelProperty(value = "救生衣状态") + @TableField("jacket_status") + private String jacketStatus; + + @ApiModelProperty("船只长度") + @TableField("length") + private BigDecimal length; + + @ApiModelProperty("船只高度") + @TableField("height") + private BigDecimal height; + + @TableField("height_range") + @ApiModelProperty("船只高度范围") + private String heightRange; + + @ApiModelProperty("船只速度") + @TableField("speed") + private BigDecimal speed; + + @ApiModelProperty("船只宽度") + @TableField("width") + private BigDecimal width; + + @ApiModelProperty(value = "所属港口") + @TableField("belong_port") + private String belongPort; + + @TableField(exist = false) + private BigDecimal distance; + + @ApiModelProperty("是否关闭舱门") + @TableField("is_close_door") + private String isCloseDoor; + + @ApiModelProperty("越线偏航时间") + @TableField("cross_line_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date crossLineTime; + + @ApiModelProperty("吃水刻度") + @TableField("draft_marks") + private BigDecimal draftMarks; + + @ApiModelProperty("备注") + @TableField(value = "remark") + private String remark; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/hikvision/AlarmData.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/hikvision/AlarmData.java new file mode 100644 index 0000000..5d6a276 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/hikvision/AlarmData.java @@ -0,0 +1,44 @@ +package com.ltgk.smartFishingPort.domain.hikvision; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +public class AlarmData implements Serializable { + + private static final long serialVersionUID = 1L; + + private int lCommand; + + private Object result; + + private Date alarmTime; + + public int getlCommand() { + return lCommand; + } + + public void setlCommand(int lCommand) { + this.lCommand = lCommand; + } + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + public Date getAlarmTime() { + return alarmTime; + } + + public void setAlarmTime(Date alarmTime) { + this.alarmTime = alarmTime; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AirportCameraSwitchReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AirportCameraSwitchReq.java new file mode 100644 index 0000000..c9df5c9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AirportCameraSwitchReq.java @@ -0,0 +1,23 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AirportCameraSwitchReq extends DroneDeviceReq{ + @NotBlank(message = "机场sn不能为空") + @JsonProperty("sn") + @ApiModelProperty(value = "机场sn") + private String sn; + @JsonProperty("camera_index") + @ApiModelProperty(value = "相机索引") + @NotBlank(message = "相机索引不能为空") + private String camera_index; + @JsonProperty("camera_position") + @ApiModelProperty(value = "相机位置 indoor:舱内摄像头 outdoor:舱外摄像头") + @NotBlank(message = "相机位置不能为空") + private String camera_position; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataExcelVo.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataExcelVo.java new file mode 100644 index 0000000..bbf8762 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataExcelVo.java @@ -0,0 +1,75 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 船只检测视图 + */ +@Data +public class AlarmDataExcelVo implements Serializable { + + /** + * 船只方向 + */ + @ApiModelProperty("船只方向") + private String direction; + + /** + * 船只检测状态 + */ + @ApiModelProperty("船只检测状态") + private String detState; + + /** + * 船只长度 + */ + @ApiModelProperty("船只长度") + private BigDecimal length; + + /** + * 船只高度 + */ + @ApiModelProperty("船只高度") + private BigDecimal height; + + /** + * 船只宽度 + */ + @ApiModelProperty("船只宽度") + private BigDecimal width; + + /** + * 船只速度 + */ + @ApiModelProperty("船只速度") + private BigDecimal speed; + + /** + * 检测线ID + */ + @ApiModelProperty("检测线ID") + private Integer triggerLineId; + + /** + * 告警时间 + */ + @ApiModelProperty("抓拍时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date alarmTime; + + /** + * 监控设备名称 + */ + @ApiModelProperty("监控设备名称") + private String videoName; + + private static final long serialVersionUID = 1L; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataVo.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataVo.java new file mode 100644 index 0000000..9b0871b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AlarmDataVo.java @@ -0,0 +1,219 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 船只检测视图 + */ +@Data +public class AlarmDataVo implements Serializable { + + /** + * 船只方向 + */ + @ApiModelProperty("船只方向") + private String direction; + + /** + * 船只检测状态 + */ + @ApiModelProperty("船只检测状态") + private String detState; + + /** + * 船只长度 + */ + @ApiModelProperty("船只长度") + private BigDecimal length; + + /** + * 船只高度 + */ + @ApiModelProperty("船只高度") + private BigDecimal height; + + /** + * 船只宽度 + */ + @ApiModelProperty("船只宽度") + private BigDecimal width; + + /** + * 船只速度 + */ + @ApiModelProperty("船只速度") + private BigDecimal speed; + + /** + * 检测线ID + */ + @ApiModelProperty("检测线ID") + private Integer triggerLineId; + + /** + * 可见光抓拍图片地址 + */ + @ApiModelProperty("可见光抓拍图片地址") + private String dwPicUrl; + + /** + * 热成像抓拍图片地址 + */ + @ApiModelProperty("热成像抓拍图片地址") + private String dwThermalPicUrl; + + /** + * 告警时间 + */ + @ApiModelProperty("抓拍时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date alarmTime; + + @ApiModelProperty("抓拍时间-开始查询条件") + private String beginTime; + + @ApiModelProperty("抓拍时间-结束查询条件") + private String endTime; + + /** + * 监控设备名称 + */ + @ApiModelProperty("监控设备名称") + private String videoName; + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("页容量") + private Integer pageSize; + + @ApiModelProperty("页码") + private Integer pageNo; + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getDetState() { + return detState; + } + + public void setDetState(String detState) { + this.detState = detState; + } + + public BigDecimal getLength() { + return length; + } + + public void setLength(BigDecimal length) { + this.length = length; + } + + public BigDecimal getHeight() { + return height; + } + + public void setHeight(BigDecimal height) { + this.height = height; + } + + public BigDecimal getWidth() { + return width; + } + + public void setWidth(BigDecimal width) { + this.width = width; + } + + public BigDecimal getSpeed() { + return speed; + } + + public void setSpeed(BigDecimal speed) { + this.speed = speed; + } + + public Integer getTriggerLineId() { + return triggerLineId; + } + + public void setTriggerLineId(Integer triggerLineId) { + this.triggerLineId = triggerLineId; + } + + public String getDwPicUrl() { + return dwPicUrl; + } + + public void setDwPicUrl(String dwPicUrl) { + this.dwPicUrl = dwPicUrl; + } + + public String getDwThermalPicUrl() { + return dwThermalPicUrl; + } + + public void setDwThermalPicUrl(String dwThermalPicUrl) { + this.dwThermalPicUrl = dwThermalPicUrl; + } + + public Date getAlarmTime() { + return alarmTime; + } + + public void setAlarmTime(Date alarmTime) { + this.alarmTime = alarmTime; + } + + public String getBeginTime() { + return beginTime; + } + + public void setBeginTime(String beginTime) { + this.beginTime = beginTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getVideoName() { + return videoName; + } + + public void setVideoName(String videoName) { + this.videoName = videoName; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public Integer getPageNo() { + return pageNo; + } + + public void setPageNo(Integer pageNo) { + this.pageNo = pageNo; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AppVersionVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AppVersionVO.java new file mode 100644 index 0000000..a58a78b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/AppVersionVO.java @@ -0,0 +1,24 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +@ApiModel(value = "App更新的实体") +public class AppVersionVO implements Serializable { + + private static final long serialVersionUID = 1L; + @ApiModelProperty(value = "版本号") + private String version; + @ApiModelProperty(value = "是否强制更新") + private String isForce; + @ApiModelProperty(value = "Android下载路径") + private String path; + @ApiModelProperty(value = "ios下载路径") + private String iosPath; + @ApiModelProperty(value = "更新日志") + private String releaseNote; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CreateDroneTaskReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CreateDroneTaskReq.java new file mode 100644 index 0000000..085ac3a --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CreateDroneTaskReq.java @@ -0,0 +1,79 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.List; + +@Data +public class CreateDroneTaskReq extends DroneDeviceReq{ + @ApiModelProperty("任务名称") + @JsonProperty("name") + @NotBlank(message = "任务名称不能为空") + private String name; + @ApiModelProperty("航线ID") + @JsonProperty("wayline_uuid") + @NotBlank(message = "航线ID不能为空") + private String wayline_uuid; + @ApiModelProperty("机场SN") + @JsonProperty("sn") + @NotBlank(message = "机场SN不能为空") + private String sn; + @ApiModelProperty("降落机场SN,非蛙跳任务可不填") + @JsonProperty("landing_dock_sn") + private String landing_dock_sn; + @ApiModelProperty("返航高度") + @JsonProperty("rth_altitude") + @NotBlank(message = "返航高度不能为空") + private Integer rth_altitude; + @ApiModelProperty("返航模式 optimal:智能高度 preset:设定高度") + @JsonProperty("rth_mode") + @NotBlank(message = "返航模式不能为空") + private String rth_mode; + @ApiModelProperty("任务精度 gps:GNSS 任务:飞行器无需等待 RTK 收敛便可以直接开始执行。建议精度要求不高的任务使用该模式。rtk:高精度 RTK 任务:飞行器起飞后会在空中等待 RTK 收敛后再执行任务,等待过程中无法暂停任务。建议高精度航线任务使用该模式。") + @JsonProperty("wayline_precision_type") + @NotBlank(message = "任务精度不能为空") + private String wayline_precision_type; + @ApiModelProperty("丢失信号后无人机动作 return_home:返航 continue_task:继续执行") + @JsonProperty("out_of_control_action_in_flight") + @NotBlank(message = "丢失信号后无人机动作不能为空") + private String out_of_control_action_in_flight; + @ApiModelProperty("自动断点续飞 auto: 自动断点续飞 manual:手动断点续飞") + @JsonProperty("resumable_status") + @NotBlank(message = "自动断点续飞不能为空") + private String resumable_status; + @ApiModelProperty("任务类型 immediate:立即任务 timed:单次定时任务 recurring:重复任务 continuous:连续任务") + @JsonProperty("task_type") + @NotBlank(message = "任务类型不能为空") + private String task_type; + @ApiModelProperty("时区,TZ database中的时区名称") + @JsonProperty("time_zone") + @NotBlank(message = "时区不能为空") + private String time_zone; + @ApiModelProperty("任务重复模式 nonrepeating:不重复 默认 daily:每几天 weekly:每几周 absolute_monthly:每几月(按日期) relative_monthly:每几月(按星期)") + @JsonProperty("repeat_type") + @NotBlank(message = "任务重复模式不能为空") + private String repeat_type; + private T repeat_option; + @ApiModelProperty("任务开始时间,秒级时间戳,立即任务不需要填,对于定时任务这个值代表任务执行时间。对于重复任务和连续任务这个值代表任务的开始时间。") + @JsonProperty("begin_at") + private Integer begin_at; + @ApiModelProperty("任务结束时间,秒级时间戳,重复/连续任务必须填写") + @JsonProperty("end_at") + private Integer end_at; + @ApiModelProperty("重复任务的多个开始执行的时间,秒级时间戳,必须跟“begin_at”时间同一天。") + @JsonProperty("recurring_task_start_time_list") + private List recurring_task_start_time_list; + @ApiModelProperty("连续任务的多个执行时间段,秒级时间戳,必须跟“begin_at”时间同一天。") + @JsonProperty("continuous_task_periods") + private List continuous_task_periods; + @ApiModelProperty("连续执行最低执行电量 >= 50 <= 100") + @JsonProperty("min_battery_capacity") + @NotBlank(message = "连续执行最低执行电量") + private Integer min_battery_capacity; + + + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CurrentAisDynamicVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CurrentAisDynamicVO.java new file mode 100644 index 0000000..4921987 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/CurrentAisDynamicVO.java @@ -0,0 +1,43 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Author: zhouyaoyao + * @Date 2025/10/12 13:47 + * Description: + */ +@Data +@Accessors(chain = true) +public class CurrentAisDynamicVO implements Serializable { + + private String shipPlate; + + private String boatName; + + private String mmsi; + + private String aisStatus; + + private String sog; + + private String cog; + + private Double longitude; + + private Double latitude; + + private String dataSource; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date gpsTime; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCameraSwitchReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCameraSwitchReq.java new file mode 100644 index 0000000..16fdee5 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCameraSwitchReq.java @@ -0,0 +1,23 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class DroneCameraSwitchReq extends DroneDeviceReq{ + @NotBlank(message = "机场sn不能为空") + @JsonProperty("sn") + @ApiModelProperty(value = "机场sn") + private String sn; + @JsonProperty("camera_index") + @ApiModelProperty(value = "相机索引") + @NotBlank(message = "相机索引不能为空") + private String camera_index; + @JsonProperty("lens_type") + @ApiModelProperty(value = "镜头类型 wide:广角镜头 zoom:变焦镜头 ir:红外镜头") + @NotBlank(message = "镜头位置不能为空") + private String lens_type; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCommandReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCommandReq.java new file mode 100644 index 0000000..2da84a0 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneCommandReq.java @@ -0,0 +1,19 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class DroneCommandReq extends DroneDeviceReq{ + @NotBlank(message = "机场sn不能为空") + @JsonProperty("deviceSn") + @ApiModelProperty(value = "机场sn") + private String deviceSn; + @JsonProperty("device_command") + @ApiModelProperty(value = "指令类型 return_home:返航 return_specific_home:蛙跳任务指定目标机场返航 return_home_cancel:取消返航 flighttask_pause:飞行任务暂停 flighttask_recovery:飞行任务恢复") + @NotBlank(message = "指令不能为空") + private String device_command; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReq.java new file mode 100644 index 0000000..c2c3335 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReq.java @@ -0,0 +1,21 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class DroneControlObtainReq extends DroneDeviceReq { + @NotBlank(message = "无人机sn不能为空") + @JsonProperty("drone_sn") + @ApiModelProperty(value = "无人机sn") + private String drone_sn; + @NotNull(message = "负载索引不能为空") + @JsonProperty("payload_index") + @ApiModelProperty(value = "负载的索引,此参数可通过获取设备列表中data.list.drone.camera_list.camera_index传入。") + private List payload_index; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReqV2.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReqV2.java new file mode 100644 index 0000000..5975730 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlObtainReqV2.java @@ -0,0 +1,27 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Data +public class DroneControlObtainReqV2 extends DroneDeviceReq{ + @NotBlank(message = "无人机sn不能为空") + @JsonProperty("drone_sn") + @ApiModelProperty(value = "无人机sn") + private String drone_sn; + @NotNull(message = "负载索引不能为空") + @JsonProperty("control_keys") + @ApiModelProperty(value = "请求的控制权限列表,flight-飞行控制权 payload_{产品负载类型key} -产品负载类型key对应负载的控制权,例如:payload_98-0-0,此参数可通过获取设备列表中data.list.drone.camera_list.camera_index传入。") + private List control_keys; + @ApiModelProperty(value = "控制权获取或释放 true 控制 false释放") + @JsonProperty("obtain_or_release") + private Boolean obtainOrRelease = true; + @JsonProperty("gateway_sn") + @ApiModelProperty(value = "网关设备SN (可选,用于指定控制的网关设备,例如DJI Dock SN)") + private String gateway_sn; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlStatusReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlStatusReq.java new file mode 100644 index 0000000..4a3caad --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneControlStatusReq.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class DroneControlStatusReq extends DroneDeviceReq{ + @JsonProperty("drone_sn_list") + @ApiModelProperty(value = "无人机sn列表") + private List drone_sn_list; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceReq.java new file mode 100644 index 0000000..31bb912 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceReq.java @@ -0,0 +1,15 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class DroneDeviceReq { + @JsonProperty("uuid") + @ApiModelProperty(value = "设备uuid 项目列表下的uuid") + @NotBlank(message = "设备uuid不能为空") + private String uuid; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceVo.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceVo.java new file mode 100644 index 0000000..67d02ca --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneDeviceVo.java @@ -0,0 +1,7 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import lombok.Data; + +@Data +public class DroneDeviceVo { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneOneTouchTakeoffReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneOneTouchTakeoffReq.java new file mode 100644 index 0000000..ce04538 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneOneTouchTakeoffReq.java @@ -0,0 +1,60 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class DroneOneTouchTakeoffReq extends DroneDeviceReq{ + @ApiModelProperty(value = "指点飞行高度") + @JsonProperty("commander_flight_height") + private Integer commander_flight_height; + @ApiModelProperty(value = "指点飞行模式") + @JsonProperty("commander_flight_mode") + private Integer commander_flight_mode; + @ApiModelProperty(value = "机场设备SN") + @JsonProperty("device_sn") + @NotBlank(message = "设备SN不能为空") + private String device_sn; + @ApiModelProperty(value = "最大速度") + @JsonProperty("max_speed") + @NotNull(message = "最大速度不能为空") + private Integer max_speed; + @ApiModelProperty(value = "媒体文件夹名称") + @JsonProperty("media_folder_name") + @NotBlank(message = "媒体文件夹名称不能为空") + private String media_folder_name; + @ApiModelProperty(value = "失控动作Hover ReturnHome Continue") + @JsonProperty("out_of_control_action") + @NotBlank(message = "失控动作不能为空") + private String out_of_control_action; + @ApiModelProperty(value = "返航高度 >= 15 <= 1500") + @NotNull(message = "返航高度不能为空") + @JsonProperty("rth_altitude") + private Integer rth_altitude; + @ApiModelProperty(value = "返航模式 0:智能高度 1:设定高度") + @JsonProperty("rth_mode") + private Integer rth_mode; + @ApiModelProperty(value = "安全起飞高度 >= 8 <= 1500") + @NotNull(message = "安全起飞高度不能为空") + @JsonProperty("security_takeoff_height") + private Integer security_takeoff_height; + @ApiModelProperty(value = "起飞模式 Takeoff TakeoffWithFlyTo") + @JsonProperty("takeoff_mode") + @NotBlank(message = "起飞模式不能为空") + private String takeoff_mode; + @ApiModelProperty(value = "目标高度 >= 2 <= 10000") + @NotNull(message = "目标高度不能为空") + @JsonProperty("target_height") + private double target_height; + @ApiModelProperty(value = "机场纬度") + @JsonProperty("target_latitude") + private double target_latitude; + @ApiModelProperty(value = "机场经度") + @JsonProperty("target_longitude") + private double target_longitude; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneProjectVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneProjectVO.java new file mode 100644 index 0000000..5c0afa9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneProjectVO.java @@ -0,0 +1,42 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.ltgk.smartFishingPort.domain.drone.ProjectRespDto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +public class DroneProjectVO { + @JsonProperty("name") + @ApiModelProperty(value = "项目名称") + private String name; + @JsonProperty("introduction") + @ApiModelProperty(value = "项目简介") + private String introduction; + @JsonProperty("uuid") + @ApiModelProperty(value = "项目uuid") + private String uuid; + @JsonProperty("org_uuid") + @ApiModelProperty(value = "组织uuid") + private String org_uuid; + @JsonProperty("createdAt") + @ApiModelProperty(value = "创建时间") + private Date createdAt; + @JsonProperty("updatedAt") + @ApiModelProperty(value = "更新时间") + private Date updatedAt; + @JsonProperty("work_center_point") + @ApiModelProperty(value = "项目作业中心点") + private ProjectRespDto.ProjectWorkCenterPoint projectWorkCenterPoint; + @Data + public static class ProjectWorkCenterPoint{ + @JsonProperty("latitude") + @ApiModelProperty(value = "项目作业中心点的纬度") + private String latitude; + @JsonProperty("longitude") + @ApiModelProperty(value = "项目作业中心点的经度") + private String longitude; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneSystemStatusVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneSystemStatusVO.java new file mode 100644 index 0000000..2f91ee0 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DroneSystemStatusVO.java @@ -0,0 +1,18 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 无人机系统状态 + */ +@Data +public class DroneSystemStatusVO { + @JsonProperty("code") + @ApiModelProperty(value = "非0表示异常") + private Integer code; + @JsonProperty("message") + @ApiModelProperty(value = "消息提示") + private String message; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DsDynamicLkdVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DsDynamicLkdVO.java new file mode 100644 index 0000000..8bfebce --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/DsDynamicLkdVO.java @@ -0,0 +1,61 @@ +package com.ltgk.smartFishingPort.domain.vo; + + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +public class DsDynamicLkdVO { + + @ApiModelProperty("目标来源 1雷达,2ais") + public Integer source; + + @ApiModelProperty("目标源id 目标在设备端的唯一标识") + public String targetSourceId; + public String mmsi; + + @ApiModelProperty("DPL_ID 站点编号0~255") + public Integer stationNumber; + @ApiModelProperty("设备id 设备唯一ID号") + public Integer deviceId; + @ApiModelProperty("当前系统时间,格式:yyyy-MM-dd hh:mm:ss.ms") + public String time; + @ApiModelProperty("时间 当前系统时间,格式:yyyy-MM-dd hh:mm:ss.ms") + public Date locationTime; + @ApiModelProperty("存在标识 0:目标消失1:目标存在 2:外推") + public Integer exist; + @ApiModelProperty("目标类型 -1:未知其他,0:大船,1:中型船,2:小船,10:行人,20:无人机,30:汽车") + public Integer type; + @ApiModelProperty("目标名:船名") + public String name; + @ApiModelProperty("长度 目标长度,单位:米(m)") + public Double length; + @ApiModelProperty("宽度 目标宽度,单位:米(m)") + public Double width; + @ApiModelProperty(" 质量等级 默认无,1~255,质量等级由低到高。") + public Integer level; + @ApiModelProperty("方位 目标所在方位(相对设备),单位:度(°)") + public Double azimuth; + @ApiModelProperty("距离 目标和设备之间的距离,单位:米(m)") + public Double distance; + @ApiModelProperty("纬度 目标所在的纬度,单位:度(°)") + public Double latitude; + @ApiModelProperty("经度 目标所在的经度,单位:度(°)") + public Double longitude; + @ApiModelProperty("径向速度 目标相对设备的径向速度,单位:米/秒(m/s)。") + public Double radialVelocity; + @ApiModelProperty("仰角 目标相对设备的仰角,单位:度(°)") + public Double elevation; + @ApiModelProperty("航向 目标的绝对航向(0-360°),单位:度(°)") + public Double course; + @ApiModelProperty("航速 目标的实际速度(m/s)") + public Double speed; + @ApiModelProperty(" 高度 目标相对设备的高度,单位:米(m)") + public Double altitude; + @ApiModelProperty(" 幅度目标幅度,单位:分贝(dB)") + public Double amplitude; + @ApiModelProperty(" 噪声 目标噪声,单位:分贝(dB)") + public Double noise; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneTaskListReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneTaskListReq.java new file mode 100644 index 0000000..2a49316 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneTaskListReq.java @@ -0,0 +1,33 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class GetDroneTaskListReq extends DroneDeviceReq{ + @JsonProperty("sn") + @ApiModelProperty("设备SN") + @NotBlank(message = "设备SN不能为空") + private String sn; + @JsonProperty("name") + @ApiModelProperty("任务名称") + private String name; + @JsonProperty("begin_at") + @NotNull(message = "任务开始时间戳不能为空") + @ApiModelProperty("任务开始时间戳") + private Long begin_at; + @JsonProperty("end_at") + @NotNull(message = "任务结束时间戳不能为空") + @ApiModelProperty("任务结束时间戳") + private Long end_at; + @JsonProperty("task_type") + @ApiModelProperty("任务类型:immediate:立即任务,timed:单次定时任务,recurring:重复任务,continuous:连续任务,非必填,不填写则为全部类型") + private String task_type; + @JsonProperty("status") + @ApiModelProperty("任务状态数组:waiting:待开始,starting_failure:启动失败,executing:执行中,paused: 暂停,terminated:终止,success:成功,suspended:挂起,timeout:超时,非必填,不填写则为全部状态") + private String status; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneWayLineDetailReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneWayLineDetailReq.java new file mode 100644 index 0000000..b557645 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetDroneWayLineDetailReq.java @@ -0,0 +1,12 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class GetDroneWayLineDetailReq extends DroneDeviceReq{ + @JsonProperty("wayLineId") + @ApiModelProperty("航线ID") + private String wayLineId; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetVideoStreamReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetVideoStreamReq.java new file mode 100644 index 0000000..c3fb3d9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/GetVideoStreamReq.java @@ -0,0 +1,31 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetVideoStreamReq { + @JsonProperty("sn") + @ApiModelProperty(value = "无人机SN") + @NotBlank(message = "sn不能为空") + private String sn; + + @JsonProperty("task_id") + @ApiModelProperty(value = "任务ID") + private String task_id; + + @JsonProperty("status") + @ApiModelProperty(value = "算法开关,填写start或者stop, 开启算法检测或关闭算法检测") + private String status; + + @JsonProperty("class_codes") + @ApiModelProperty(value = "算法类别识别码,支持多个,以逗号分隔,参见识别编码统一说明") + private String class_codes; + + @JsonProperty("enable_orc") + @ApiModelProperty(value = "开启算法orc识别") + private Boolean enable_orc = false; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/IdentityRateVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/IdentityRateVO.java new file mode 100644 index 0000000..ca2d50e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/IdentityRateVO.java @@ -0,0 +1,24 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 13:23 + * Description: + */ +@Data +public class IdentityRateVO implements Serializable { + + @ApiModelProperty("全部数量") + private Integer totalCount; + + @ApiModelProperty("已识别数量") + private Integer identityCount; + + @ApiModelProperty("识别率") + private String rate; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortIdentityTotalVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortIdentityTotalVO.java new file mode 100644 index 0000000..c6a02f9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortIdentityTotalVO.java @@ -0,0 +1,42 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 13:48 + * Description: + */ +@Data +public class PortIdentityTotalVO implements Serializable { + + @ApiModelProperty("船名识别数量") + private Integer boatNameIdentityCount; + + @ApiModelProperty("船型识别数量") + private Integer boatTypeIdentityCount; + + @ApiModelProperty("未封舱预警数量") + private Integer notCloseDoorCount; + + @ApiModelProperty("未穿救生衣数量") + private Integer notWearSafeCount; + + @ApiModelProperty("横越/偏航预警数量") + private Integer crossLineCount; + + @ApiModelProperty("吃水线预警") + private Integer draftCount; + + public PortIdentityTotalVO(Integer boatNameIdentityCount,Integer boatTypeIdentityCount,Integer notCloseDoorCount,Integer notWearSafeCount,Integer crossLineCount,Integer draftCount) { + this.boatNameIdentityCount = boatNameIdentityCount; + this.boatTypeIdentityCount = boatTypeIdentityCount; + this.notCloseDoorCount = notCloseDoorCount; + this.notWearSafeCount = notWearSafeCount; + this.crossLineCount = crossLineCount; + this.draftCount = draftCount; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortTrendVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortTrendVO.java new file mode 100644 index 0000000..100aaf7 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/PortTrendVO.java @@ -0,0 +1,22 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: wss + * @Date 2025/5/6 22:54 + * Description: + */ +@Data +public class PortTrendVO implements Serializable { + + @ApiModelProperty("日期") + private String timeStr; + + @ApiModelProperty("数量") + private long count; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/StartLiveReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/StartLiveReq.java new file mode 100644 index 0000000..11164d0 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/StartLiveReq.java @@ -0,0 +1,28 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class StartLiveReq extends DroneDeviceReq { + @JsonProperty("sn") + @ApiModelProperty(value = "设备sn") + @NotBlank(message = "设备sn不能为空") + private String sn; + @JsonProperty("camera_index") + @ApiModelProperty(value = "设备camera_index camera_index 信息可通过获取组织下的设备列表接口下的 data.list.drone.camera_list 中获取。") + @NotBlank(message = "设备camera_index不能为空") + private String camera_index; + @JsonProperty("video_expire") + @ApiModelProperty(value = "直播推流Token有效期,超过这个有限期直播将中止。") + @NotNull(message = "直播推流Token有效期不能为空") + private Integer video_expire; + @JsonProperty("quality_type") + @ApiModelProperty(value = "直播清晰度 adaptive:自动 smooth:流畅 ultra_high_definition:超清") + @NotBlank(message = "直播清晰度不能为空") + private String quality_type; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVIdentityTotalVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVIdentityTotalVO.java new file mode 100644 index 0000000..387b35c --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVIdentityTotalVO.java @@ -0,0 +1,45 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 13:57 + * Description: + */ +@Data +public class UAVIdentityTotalVO implements Serializable { + + @ApiModelProperty("船名识别数量") + private Integer boatNameIdentityCount; + + @ApiModelProperty("船型识别数量") + private Integer boatTypeIdentityCount; + + @ApiModelProperty("危险品旗帜标识数量") + private Integer dangerSignCount; + + @ApiModelProperty("未悬挂国旗数量") + private Integer notCountrySignCount; + + @ApiModelProperty("航线偏离预警数量") + private Integer crossLineCount; + + @ApiModelProperty("超速预警数量") + private Integer outSpeedCount; + + @ApiModelProperty("异常停靠预警数量") + private Integer notNormalBerthCount; + + @ApiModelProperty("人员落水协助预警") + private Integer dropCount; + + @ApiModelProperty("船舶火灾预警数量") + private Integer fireCount; + + @ApiModelProperty("船舶漏油预警数量") + private Integer oilCount; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVOperateCountVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVOperateCountVO.java new file mode 100644 index 0000000..7b4039c --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UAVOperateCountVO.java @@ -0,0 +1,21 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 13:44 + * Description: + */ +@Data +public class UAVOperateCountVO implements Serializable { + + @ApiModelProperty("手动执行次数") + private Integer operateCount; + + @ApiModelProperty("自动执行次数") + private Integer autoCount; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UpdateDroneTaskStatusReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UpdateDroneTaskStatusReq.java new file mode 100644 index 0000000..ec6878e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/UpdateDroneTaskStatusReq.java @@ -0,0 +1,19 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class UpdateDroneTaskStatusReq extends DroneDeviceReq{ + @JsonProperty("task_uuid") + @ApiModelProperty(value = "任务id") + @NotBlank(message = "任务id不能为空") + private String task_uuid; + @JsonProperty("status") + @ApiModelProperty(value = "任务状态") + @NotBlank(message = "任务状态不能为空suspended:任务挂起 restored:任务恢复") + private String status; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoIdentificationVo.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoIdentificationVo.java new file mode 100644 index 0000000..c28e769 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoIdentificationVo.java @@ -0,0 +1,82 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import com.baomidou.mybatisplus.annotation.SqlCondition; +import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ltgk.smartFishingPort.utils.DateTimeConverter; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@ColumnWidth(25) +@HeadRowHeight(20) +@ContentRowHeight(18) +public class VideoIdentificationVo implements Serializable { + + private static final long serialVersionUID=1L; + + @ExcelProperty(value = "摄像头名称") + @ApiModelProperty(value = "摄像头名称") + @TableField(value = "video_name",condition = SqlCondition.LIKE) + private String videoName; + + @ExcelProperty(value = "抓拍时间", converter = DateTimeConverter.class) + @ApiModelProperty(value = "抓拍时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date takeTime; + + @ExcelProperty(value = "所属港口") + @ApiModelProperty(value = "所属港口") + @TableField(value = "belong_port",condition = SqlCondition.LIKE) + private String belongPort; + + @ExcelProperty(value = "船舶类型") + @ApiModelProperty(value = "船舶类型") + private String shipType; + + @ExcelProperty(value = "船只长度") + @ApiModelProperty("船只长度") + private BigDecimal length; + + @ExcelProperty(value = "船只高度") + @ApiModelProperty("船只高度") + private BigDecimal height; + + @ExcelProperty(value = "船只速度") + @ApiModelProperty("船只速度") + private BigDecimal speed; + + @ExcelProperty(value = "进出港方向") + @ApiModelProperty(value = "进出港方向(进港、出港)") + private String entryOut; + + @ExcelProperty(value = "经度") + @ApiModelProperty(value="经度") + private BigDecimal longitude; + + @ExcelProperty(value = "纬度") + @ApiModelProperty(value = "纬度") + private BigDecimal latitude; + + @ExcelProperty(value = "救生衣状态") + @ApiModelProperty(value = "救生衣状态") + private String jacketStatus; + + @ExcelProperty(value = "船舶名称") + @ApiModelProperty(value = "船舶名称") + private String boatName; + + @ExcelProperty(value = "识别类型") + @ApiModelProperty(value = "识别类型(船脸识别、船牌识别)") + private String identificationType; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchReq.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchReq.java new file mode 100644 index 0000000..623ccbc --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchReq.java @@ -0,0 +1,27 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class VideoStreamDetectSwitchReq { + @JsonProperty("sn") + @ApiModelProperty(value = "无人机SN") + @NotBlank(message = "sn不能为空") + private String sn; + @JsonProperty("task_id") + @ApiModelProperty(value = "任务ID") + private String task_id; + @JsonProperty("status") + @ApiModelProperty(value = "算法开关,填写start或者stop, 开启算法检测或关闭算法检测") + private String status; + @JsonProperty("class_codes") + @ApiModelProperty(value = "算法类别识别码,支持多个,以逗号分隔,参见识别编码统一说明") + private String class_codes; + @JsonProperty("enable_orc") + @ApiModelProperty(value = "开启算法orc识别") + private Boolean enable_orc = true; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchResp.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchResp.java new file mode 100644 index 0000000..24325de --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/VideoStreamDetectSwitchResp.java @@ -0,0 +1,15 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class VideoStreamDetectSwitchResp { + @JsonProperty("httpUrl") + @ApiModelProperty(value = "直播流地址") + private String httpUrl; + @JsonProperty("taskId") + @ApiModelProperty(value = "任务ID") + private String taskId; +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayVelocityVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayVelocityVO.java new file mode 100644 index 0000000..1bfa32f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayVelocityVO.java @@ -0,0 +1,34 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 14:26 + * Description: + */ +@Data +public class WaterwayVelocityVO implements Serializable { + + @ApiModelProperty("深度观测站编号") + private Integer deepSiteCode; + + @ApiModelProperty("雷达流量") + private Integer radarVelocity; + + @ApiModelProperty("雷达水位") + private Integer radarLevel; + + @ApiModelProperty("压力式水位") + private Integer pressureLevel; + + @ApiModelProperty("温度") + private Integer temperature; + + @ApiModelProperty("倾角") + private Integer angle; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayWeatherVO.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayWeatherVO.java new file mode 100644 index 0000000..ad43926 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/domain/vo/WaterwayWeatherVO.java @@ -0,0 +1,40 @@ +package com.ltgk.smartFishingPort.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 14:45 + * Description: + */ +@Data +public class WaterwayWeatherVO implements Serializable { + + @ApiModelProperty("气象观测站编号") + private Integer deepSiteCode; + + @ApiModelProperty("温度") + private Integer temperature; + + @ApiModelProperty("湿度") + private Integer humidity; + + @ApiModelProperty("风速") + private Integer windSpeed; + + @ApiModelProperty("风向") + private Integer windDirect; + + @ApiModelProperty("大气压") + private Integer pressure; + + @ApiModelProperty("降水量") + private Integer rainFall; + + @ApiModelProperty("光照度") + private Integer illuminance; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDataMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDataMapper.java new file mode 100644 index 0000000..dd99289 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDataMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.BoatData; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/6/10 17:53 + * Description: + */ +@Repository +public interface BoatDataMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDynamicMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDynamicMapper.java new file mode 100644 index 0000000..dd2ab44 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatDynamicMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.BoatDynamic; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 15:56 + * Description: + */ +@Repository +public interface BoatDynamicMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatPathMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatPathMapper.java new file mode 100644 index 0000000..d6e6b85 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/BoatPathMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.BoatPath; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 15:59 + * Description: + */ +@Repository +public interface BoatPathMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/DsVideoMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/DsVideoMapper.java new file mode 100644 index 0000000..f160d33 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/DsVideoMapper.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.DsVideo; + +/** + *

+ * 视频监控管理表 Mapper 接口 + *

+ * + * @author zhouyaoyao + * @since 2025-01-19 + */ +public interface DsVideoMapper extends BaseMapper { + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EmergencyRescueMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EmergencyRescueMapper.java new file mode 100644 index 0000000..8c00c2f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EmergencyRescueMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.EmergencyRescue; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 15:55 + * Description: + */ +@Repository +public interface EmergencyRescueMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EnvEquipmentMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EnvEquipmentMapper.java new file mode 100644 index 0000000..f2bd87f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/EnvEquipmentMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.EnvEquipment; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/28 17:31 + * Description: + */ +@Repository +public interface EnvEquipmentMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/UavEquipmentMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/UavEquipmentMapper.java new file mode 100644 index 0000000..0da001f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/UavEquipmentMapper.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.UavEquipment; +import org.springframework.stereotype.Repository; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/28 17:32 + * Description: + */ +@Repository +public interface UavEquipmentMapper extends BaseMapper { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoCameraMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoCameraMapper.java new file mode 100644 index 0000000..1d6a879 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoCameraMapper.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.VideoCamera; + +/** + *

+ * 监控设备表 Mapper 接口 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +public interface VideoCameraMapper extends BaseMapper { + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoIdentificationMapper.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoIdentificationMapper.java new file mode 100644 index 0000000..7a5d863 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/mapper/VideoIdentificationMapper.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ltgk.smartFishingPort.domain.entity.VideoIdentification; + +/** + *

+ * 监控识别记录表 Mapper 接口 + *

+ * + * @author zhou + * @since 2024-12-10 + */ +public interface VideoIdentificationMapper extends BaseMapper { + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/DroneService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/DroneService.java new file mode 100644 index 0000000..2b4709e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/DroneService.java @@ -0,0 +1,63 @@ +package com.ltgk.smartFishingPort.service; + + +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.domain.drone.*; +import com.ltgk.smartFishingPort.domain.vo.*; + +import java.util.List; + +/** + * @author liutailin + * @description 无人机模块 + * @date 2019-06-02 9:06. + */ +public interface DroneService { + Response getDroneSystemStatus(); + + Response> getDroneProject(); + + Response> getDroneDevice(DroneDeviceReq req); + + Response droneCommand(DroneCommandReq req); + + Response airportCameraSwitch(AirportCameraSwitchReq req); + + Response droneCameraSwitch(DroneCameraSwitchReq req); + + Response droneControlObtain(DroneControlObtainReq req); + + Response droneControlRelease(DroneControlObtainReq req); + + Response> getDroneWayLine(DroneDeviceReq req); + + Response getDroneWayLineDetail(GetDroneWayLineDetailReq req); + + Response createDroneTask(CreateDroneTaskReq req); + + Response startLive(StartLiveReq req); + + Response updateDroneTaskStatus(UpdateDroneTaskStatusReq req); + + Response> getDroneTaskList(GetDroneTaskListReq req); + + Response droneOneTouchTakeoff(DroneOneTouchTakeoffReq req); + + Response droneControlObtainV2(DroneControlObtainReqV2 req); + + Response> droneControlStatus(DroneControlStatusReq req); + + Response videoStreamDetectSwitch(VideoStreamDetectSwitchReq req); + + /** + * 获取视频流地址: + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/11/27 + */ + Response getVideoStream(GetVideoStreamReq req); + + Response doStartOrStopUavAlgorithm(GetVideoStreamReq req); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDataService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDataService.java new file mode 100644 index 0000000..a679c8d --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDataService.java @@ -0,0 +1,25 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.entity.BoatData; + +/** + * @Author: zhouyaoyao + * @Date 2025/6/10 17:54 + * Description: + */ +public interface IBoatDataService extends IService { + IPage selectByPage(BoatData boatData); + + /** + * 根据经纬度获取AIS数据中距离最近的点位且更新时间为±1分钟之内的数据 + * + * @param longitude:经度 + * @param latitude:维度 + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/2 + */ + Object getNearestAisData(String longitude, String latitude); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDynamicService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDynamicService.java new file mode 100644 index 0000000..378064a --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatDynamicService.java @@ -0,0 +1,12 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.entity.BoatDynamic; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:06 + * Description: + */ +public interface IBoatDynamicService extends IService { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatPathService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatPathService.java new file mode 100644 index 0000000..aa51140 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IBoatPathService.java @@ -0,0 +1,12 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.entity.BoatPath; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:00 + * Description: + */ +public interface IBoatPathService extends IService { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IDsVideoService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IDsVideoService.java new file mode 100644 index 0000000..ddfc048 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IDsVideoService.java @@ -0,0 +1,58 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.common.core.domain.AjaxResult; +import com.ltgk.smartFishingPort.domain.entity.DsVideo; + +import java.util.List; + +/** + *

+ * 视频监控管理表 服务类 + *

+ * + * @author zhouyaoyao + * @since 2025-01-19 + */ +public interface IDsVideoService extends IService { + + /** + * 分页查询 + * @param dsVideo + * @return + */ + IPage selectByPage(DsVideo dsVideo); + + /** + * 根据视频监控设备名称批量添加更新 + * @param dsVideos + * @return + */ + boolean saveBatchByName(List dsVideos); + + /** + * 光电随动控制 + * @param msg + * @return + */ + boolean servoByRadar(String msg); + + /** + * 光电联动反向定位联动控制,根据监控设备和将要联动的定位目标经纬度控制视频监控设备转动对焦 + * + * @return + */ + AjaxResult sitMoveByGps(String deviceCode, String gpsX, String gpsY); + + DsVideo getVideoInfo(DsVideo dsVideo); + + /** + * 更新摄像头可视范围字段状态,并获取所有的开启了可视摄像头范围的相关数据 + * @author Qi ChengBin + * @param dsVideo:需开启摄像头可视范围的相关摄像头数据 + * @return com.yuhuan.common.core.domain.AjaxResult + * @date 2025/9/15 + */ + List updateOneAndFindVideoInfoList(DsVideo dsVideo); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IEmergencyRescueService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IEmergencyRescueService.java new file mode 100644 index 0000000..928733b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IEmergencyRescueService.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.entity.EmergencyRescue; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:08 + * Description: + */ +public interface IEmergencyRescueService extends IService { + IPage selectByPage(EmergencyRescue boatData); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoCameraService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoCameraService.java new file mode 100644 index 0000000..0f262f3 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoCameraService.java @@ -0,0 +1,34 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.entity.VideoCamera; + +/** + *

+ * 监控设备表 服务类 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +public interface IVideoCameraService extends IService { + + /** + * 分页查询 + * @param videoCamera + * @param pageNo + * @param pageSize + * @return + */ + IPage findPage(VideoCamera videoCamera, Integer pageNo, Integer pageSize); + + Object loginDH(String mStrIp, String mNPort, String mStrUser, String mStrPassword); + + Boolean attachTraffic(Long loginHandler, Integer channelId); + + Boolean attachAlarmChanDHByAccount(String videoIp, String videoPort, String videoAccount, String videoPass, String channelId); + Boolean attachAlarmChanHKByAccount(String videoIp, String videoPort, String videoAccount, String videoPass); + + IPage selectByPage(VideoCamera videoCamera); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoIdentificationService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoIdentificationService.java new file mode 100644 index 0000000..2893ce2 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/IVideoIdentificationService.java @@ -0,0 +1,19 @@ +package com.ltgk.smartFishingPort.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ltgk.smartFishingPort.domain.dto.VideoIdentificationDto; +import com.ltgk.smartFishingPort.domain.entity.VideoIdentification; + +/** + *

+ * 监控识别记录表 服务类 + *

+ * + * @author zhou + * @since 2024-12-10 + */ +public interface IVideoIdentificationService extends IService { + + IPage findByPage(VideoIdentificationDto videoIdentificationDto); +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/ArtemisPostService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/ArtemisPostService.java new file mode 100644 index 0000000..500aa08 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/ArtemisPostService.java @@ -0,0 +1,1169 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; +import com.ltgk.smartFishingPort.common.constant.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * 海康开放api调用 + * + * @author limap + */ +@Component +public class ArtemisPostService { + + private static final Logger logger = LoggerFactory.getLogger(ArtemisPostService.class); + + private static final String SERVER_IP = "125.124.131.105"; + + private static final String SERVER_PORT = "6811"; + private static final String SERVER_PORT2 = "6811"; + + private static final String REAL_NAME = "www.yhships.cn"; + + private static final String CONTEXT_PATH = "/api"; + private static final String CONTEXT_WEB_PATH = "/web"; + + /** + * 请根据自己的appKey和appSecret更换static静态块中的三个参数. [1 host] + * 如果你选择的是和现场环境对接,host要修改为现场环境的ip,https端口默认为443,http端口默认为80.例如10.33.25.22:443 或者10.33.25.22:80 + * appKey和appSecret请按照或得到的appKey和appSecret更改. + * TODO 调用前先要清楚接口传入的是什么,是传入json就用doPostStringArtemis方法,下载图片doPostStringImgArtemis方法 + */ + /** + * 根据API文档可以看出来,这是一个POST请求的Rest接口,而且传入的参数值为一个json + * ArtemisHttpUtil工具类提供了doPostStringArtemis这个函数,一共六个参数在文档里写明其中的意思,因为接口是https, + * 所以第一个参数path是一个hashmap类型,请put一个key-value,query为传入的参数,body为传入的json数据 + * 传入的contentType为application/json,accept不指定为null + * header没有额外参数可不传,指定为null + * + */ + static { + + // 代理API网关nginx服务器ip端口 + ArtemisConfig.host = "39.175.75.233:10443"; + // 秘钥appkey + ArtemisConfig.appKey = "28273161"; + // 秘钥appSecret + ArtemisConfig.appSecret = "pvQSichVMqtLGh4Ltedo"; + } + + /** + * 能力开放平台的网站路径 + * 路径不用修改,就是/artemis + */ + private static final String ARTEMIS_PATH = "/artemis"; + + /** + * post请求application/json类型参数 + */ + private static final String CONTENT_TYPE = "application/json"; + + /** + * TODO 根据现场环境部署确认是http还是https + */ + + private static final String HTTPS_TYPE = "https://"; + + private static final String HTTP_TYPE = "http://"; + /** + * 分页获取监控点资源API + */ + private static final String GET_MONITOR_POINT_URL = "/api/resource/v1/cameras"; + + /** + * 获取监控点预览取流API + */ + private static final String GET_PREVIEW_URL = "/api/video/v2/cameras/previewURLs"; + + /** + * 订阅事件API + */ + private static final String SIGN_INTERFACE = "/api/eventService/v1/eventSubscriptionByEventTypes"; + + /** + * 查询订阅事件API + */ + private static final String GET_SIGN_INFO = "/api/eventService/v1/eventSubscriptionView"; + + /** + * 图片下载API + */ + private static final String GET_IMG_URL = "/api/video/v1/events/picture"; + /** + * 云台操作API + */ + private static final String CONTROL_URL = "/api/video/v1/ptzs/controlling"; + /** + * 3D放大API + */ + private static final String SEL_ZOOM_URL = "/api/video/v1/ptzs/selZoom"; + + /** + * 设置预置点信息API + */ + private static final String PRESETS_ADDITION_URL = "/api/video/v1/presets/addition"; + /** + * 查询预置点信息API + */ + private static final String PRESETS_SEARCHES_URL = "/api/video/v1/presets/searches"; + /** + * 删除预置点信息API + */ + private static final String PRESETS_DELETION_URL = "/api/video/v1/presets/deletion"; + + /** + * 手动抓图API + */ + private static final String MANUAL_CAPTURE_URL = "/api/video/v1/manualCapture"; + + /** + * 录像锁定与解锁API + */ + private static final String LOCK_URL = "/api/video/v1/record/lock"; + + /** + * 开始手动录像API + */ + private static final String START_RECORD_URL = "/api/video/v1/manualRecord/start"; + + /** + * 停止手动录像API + */ + private static final String STOP_RECORD_URL = "/api/video/v1/manualRecord/stop"; + + /** + * 获取监控点回放取流API + */ + private static final String PLAY_BACK_URL = "/api/video/v2/cameras/playbackURLs"; + + /** + * 根据广播分区获取广播点 + */ + private static final String FETCH_AUDIO_AREA_PAGE_URL = "/api/ibas/audioArea/v1/fetchAudioAreaPage"; + + /** + * 根据广播分区获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_BY_AREA_URL = "/api/ibas/audioArea/v1/fetchAudioChannelByArea"; + + /** + * 分页查询媒体文件 + */ + private static final String FETCH_MEDIA_PAGE_URL = "/api/ibas/media/v1/fetchMediaPage"; + + /** + * 分页获取广播媒体库目录接口 + */ + private static final String FETCH_MEDIA_LIBRARY_URL = "/api/ibas/media/v1/fetchMediaLibrary"; + + /** + * 根据指定标识获取广播媒体库文件 + */ + private static final String FETCH_MEDIA_BY_INDEX_CODE_URL = "/api/ibas/media/v1/fetchMediaByIndexCode"; + + /** + * 分页获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_URL = "/api/ibas/resource/v1/fetchAudioChannel"; + + /** + * 分页获取广播设备列表 + */ + private static final String FETCH_AUDIO_DEVICE_URL = "/api/ibas/resource/v1/fetchAudioDevice"; + + /** + * 根据设备信息获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_BY_DEVICE_URL = "/api/ibas/resource/v1/fetchAudioChannelByDevice"; + + /** + * 分页查询定时任务 + */ + private static final String FETCH_AUDIO_TASK_PAGE_URL = "/api/ibas/audioTask/v1/fetchAudioTaskPage"; + + /** + * 分页获取广播预案接口 + */ + private static final String FETCH_AUDIO_PLAN_URL = "/api/ibas/audioPlan/v1/fetchAudioPlanPage"; + + /** + * 广播设备自定义播放或停止 + */ + private static final String CUSTOM_BROAD_CAST_URL = "/api/ibas/v1/customBroadcast"; + + /** + * 获取H5实时广播URL + */ + private static final String BROAD_CAST_URL = "/api/ibas/media/v1/broadcastURLs"; + + /** + * 设置广播点音量 + */ + private static final String SET_AUDIO_VOLUME_PPARAM_URL = "/api/ibas/resource/v1/setAudioVolumeParam"; + + static final String onLineURLsApi = ARTEMIS_PATH + "/api/nms/v1/online/camera/get"; + + static final String cameraURLsApi = ARTEMIS_PATH + "/api/resource/v1/cameras/indexCode"; + + + + /** + * 根据广播分区获取广播点 + * @param param + * @return + */ + public static Object fetchAudioAreaPage(Object param) { + + final String fetchAudioAreaPage = ARTEMIS_PATH + FETCH_AUDIO_AREA_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioAreaPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据广播分区获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannelByArea(Object param) { + + final String fetchAudioChannelByArea = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_BY_AREA_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannelByArea); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页查询媒体文件 + * @param param + * @return + */ + public static Object fetchMediaPage(Object param) { + + final String fetchMediaPage = ARTEMIS_PATH + FETCH_MEDIA_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播媒体库目录接口 + * @param param + * @return + */ + public static Object fetchMediaLibrary(Object param) { + + final String fetchMediaLibrary = ARTEMIS_PATH + FETCH_MEDIA_LIBRARY_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaLibrary); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据指定标识获取广播媒体库文件 + * @param param + * @return + */ + public static Object fetchMediaByIndexCode(Object param) { + + final String fetchMediaByIndexCode = ARTEMIS_PATH + FETCH_MEDIA_BY_INDEX_CODE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaByIndexCode); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannel(Object param) { + + final String fetchAudioChannel = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannel); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播设备列表 + * @param param + * @return + */ + public static Object fetchAudioDevice(Object param) { + + final String fetchAudioDevice = ARTEMIS_PATH + FETCH_AUDIO_DEVICE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioDevice); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据设备信息获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannelByDevice(Object param) { + + final String fetchAudioChannelByDevice = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_BY_DEVICE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannelByDevice); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页查询定时任务 + * @param param + * @return + */ + public static Object fetchAudioTaskPage(Object param) { + + final String fetchAudioTaskPage = ARTEMIS_PATH + FETCH_AUDIO_TASK_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioTaskPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播预案接口 + * @param param + * @return + */ + public static Object fetchAudioPlanPage(Object param) { + + final String fetchAudioPlanPage = ARTEMIS_PATH + FETCH_AUDIO_PLAN_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioPlanPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 广播设备自定义播放或停止 + * @param param + * @return + */ + public static Object customBroadcast(Object param) { + + final String customBroadcast = ARTEMIS_PATH + CUSTOM_BROAD_CAST_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, customBroadcast); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 获取H5实时广播URL + * @param param + * @return + */ + public static Object broadcastURLs(Object param) { + + final String broadcastURLs = ARTEMIS_PATH + BROAD_CAST_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, broadcastURLs); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 设置广播点音量 + * @param param + * @return + */ + public static Object setAudioVolumeParam(Object param) { + + final String setAudioVolumeParam = ARTEMIS_PATH + SET_AUDIO_VOLUME_PPARAM_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, setAudioVolumeParam); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取监控点资源 + * + * @return 调用结果 + */ + public static String callPostStringApi() { + + final String getCamsApi = ARTEMIS_PATH + GET_MONITOR_POINT_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + jsonBody.put("pageNo", 1); + jsonBody.put("pageSize", 200); + jsonBody.put("treeCode", null); + String body = jsonBody.toJSONString(); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + } + + /** + * 获取监控点预览取流URLv2 + * + * @param code 监控点唯一标识 + * @param previewProtocol 取流协议(应用层协议) + * @return 调用结果 + */ + public static String getPreviewUrl(String code,String previewProtocol) { + if (StringUtils.isEmpty(previewProtocol)) { + previewProtocol = "rtsp"; + } + final String getCamsApi = ARTEMIS_PATH + GET_PREVIEW_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + // 码流类型,0:主码流 1:子码流 2:第三码流 参数不填,默认为主码流 + Integer streamType = 0; + // 取流协议(应用层协议), + // “hik”:HIK私有协议,使用视频SDK进行播放时,传入此类型; + // “rtsp”:RTSP协议; + // “rtmp”:RTMP协议(RTMP协议只支持海康SDK协议、EHOME协议、ONVIF协议接入的设备;只支持H264视频编码和AAC音频编码); + // “hls”:HLS协议(HLS协议只支持海康SDK协议、EHOME协议、ONVIF协议接入的设备;只支持H264视频编码和AAC音频编码); + // “ws”:Websocket协议(一般用于H5视频播放器取流播放)。 + String protocol = previewProtocol; + // 传输协议(传输层协议),0:UDP 1:TCP 默认是TCP 注:GB28181 2011及以前版本只支持UDP传输 + Integer transmode = 1; + // 转码标志,不携带此字段或传0表示不转码,传1或2表示转码。0 不转码 1组件转码 2设备转码,仅支持分辨率、比特率、帧率转码参数进行转码 + String expand = "transcode=0"; + // 输出码流转封装格式,“ps”:PS封装格式、“rtp”:RTP封装协议。当protocol=rtsp时生效,且不传值时默认为RTP封装协议。 + String streamform = "rtp"; + + jsonBody.put("cameraIndexCode", code); + jsonBody.put("streamType", streamType); + jsonBody.put("protocol", protocol); + jsonBody.put("transmode", transmode); + jsonBody.put("expand", expand); + jsonBody.put("streamform", streamform); + + String body = jsonBody.toJSONString(); + + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + JSONObject resultObject = JSONObject.parseObject(result); + JSONObject data = resultObject.getJSONObject("data"); + return data.getString("url"); + } + + /** + * 订阅事件(事件注册) + * + * @return 调用结果 + */ +// public static String signAreaInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Integer.parseInt(Constants.AREA_WARN_CODE)); +// eventTypes.add(Integer.parseInt(Constants.IDENTIFY_CODE)); +// jsonBody.put("eventTypes", eventTypes); +// JSONArray eventLvl = new JSONArray(); +// eventLvl.add(2); +// jsonBody.put("eventLvl", eventLvl); +// jsonBody.put("subType", 0); +// // TODO 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT2 + CONTEXT_WEB_PATH + "/rest/videoWarning/listenAreaWarn"); +//// jsonBody.put("eventDest", HTTPS_TYPE + REAL_NAME + CONTEXT_PATH + "/rest/videoWarning/listenAreaWarn"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signFireSmokeInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.FIRE_SMOKE_WARN_CODE); +// eventTypes.add(Constants.FIRE_POINT_WARN_CODE); +// eventTypes.add(Constants.SMOKE_WARN_CODE); +// jsonBody.put("eventTypes", eventTypes); +// // TODO 回调接口 +// // jsonBody.put("eventDest", "http://60.212.191.109:4001/wdyc/rest/videoMonitorAlarm/listen"); +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/smokeFireCallBack"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅车辆报警事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signVehicleInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.VEHICLE_BLACKLIST_WARN_CODE); +// eventTypes.add(Constants.VEHICLE_SPEED_WARN_CODE); +// eventTypes.add(Constants.VEHICLE_RETROGRADE_WARN_CODE); +// eventTypes.add(Constants.ILLEGALLY_PARK_WARN_CODE); +// jsonBody.put("eventTypes", eventTypes); +// // 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/vehicleCallBack"); +// +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅重点人员识别报警事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signMainPersonInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.MAIN_PERSON_WARN_CODE); +// +// jsonBody.put("eventTypes", eventTypes); +// // 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/mainFaceCallBack"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + + /** + * 获取报警截图 + * + * @param svrIndexCode 设备唯一标识 + * @param captureId url + * @return 调用结果 + */ + public static String imgUrl(String svrIndexCode, String captureId) throws Exception { + final String getCamsApi = ARTEMIS_PATH + GET_IMG_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + jsonBody.put("svrIndexCode", svrIndexCode); + jsonBody.put("picUri", captureId); + + jsonBody.put("netProtocol", "http"); + + String body = jsonBody.toJSONString(); + + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + JSONObject resultObject = JSONObject.parseObject(result); + JSONObject data = resultObject.getJSONObject("data"); + // TODO 待确认如何替换 + result = data.getString("picUrl").replaceAll("https:", "http:").replaceAll(":6113", ":6040"); + return result; + } + + /** + * 查询订阅信息 + * + * @return 调用结果 + */ + public static String signInfo() { + final String getCamsApi = ARTEMIS_PATH + GET_SIGN_INFO; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + return ArtemisHttpUtil.doPostStringArtemis(path, null, null, null, CONTENT_TYPE, null); + } + + + /** + * 查询预置点信息 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject presetsSearch(String cameraIndexCode) { +// final String presetsSearchApi = ARTEMIS_PATH + PRESETS_SEARCHES_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, presetsSearchApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("查询监控点上的预置点请求参数:{} ," + +// "\n查询监控点上的预置点的响应信息:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 云台跳转到指定预置点 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param speed 台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 调用结果 + */ +// public static JSONObject goToPreset(String cameraIndexCode, Integer speed, String presetIndex) { +// final String goToPresetApi = ARTEMIS_PATH + CONTROL_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, goToPresetApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// jsonBody.put("action", 0); +// jsonBody.put("command", "GOTO_PRESET"); +// if (speed == null) { +// speed = 50; +// } +// jsonBody.put("speed", speed); +// jsonBody.put("presetIndex", presetIndex); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("跳转到监控点请求参数:{} ," + +// "\n跳转到监控点响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 手动抓图 + * 该接口用于手动触发设备抓图,返回图片的地址,抓图前请确保平台上已配置图片存储信息。抓图时间为触发手动抓图命令的时间 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject catchImage(String cameraIndexCode) { +// final String catchImageApi = ARTEMIS_PATH + MANUAL_CAPTURE_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// JSONObject jsonBody = new JSONObject(); +// +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("手动抓图请求参数:{} ," + +// "\n手动抓图响应结果:{}", body, response); +// response = response.replaceAll("https:", "http:").replaceAll(":6113", ":6040"); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 手动录像 + * 通过向中心存储接入服务下发锁定/解锁指定编码器,指定时间段的录像。 + * 进行录像锁定/解锁操作的用户需要配置相应监控点的录像回放权限,本接口会根据合作方的userId进行权限过滤。 + * 仅支持中心存储,暂不支持设备存储。 + * 综合安防管理平台iSecure Center V1.4及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param start 录像时长,单位秒 + * @param end 结束 + * @return 调用结果 + */ +// public static JSONObject lockVideo(String cameraIndexCode, Date start, Date end) { +// final String lockVideoApi = ARTEMIS_PATH + LOCK_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, lockVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) +// jsonBody.put("startTime", DateFormatUtils.format(start, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// jsonBody.put("endTime", DateFormatUtils.format(end, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// //锁定时长,单位:秒,为0时表示解锁,取值范围:0-1576800000 +// jsonBody.put("lockTime", (end.getTime() - start.getTime()) / 1000); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("锁定录像请求参数:{} ," + +// "\n锁定录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 开始手动录像 + * 1.该接口用于向存储接入服务下发开始手动录像请求,将前端实时流存储到存储设备上,支持中心存储和设备存储两种存储模式。萤石设备不支持手动录像功能。 + * 2.由于开始手动录像命令需要先下发到sac再到存储,实际录像开始时间与调用接口时间会稍有延迟。 + * 综合安防管理平台iSecure Center V1.3及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject startCatchVideo(String cameraIndexCode) { +// final String startCatchVideoApi = ARTEMIS_PATH + START_RECORD_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, startCatchVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// //报警触发或移动侦测 +// jsonBody.put("recordType", 3); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("开始手动录像请求参数:{} ," + +// "\n开始手动录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// result.put("taskID", result.getJSONObject("data").getString("taskID")); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 停止手动录像 + * 1.该接口用于根据手动录像任务ID,向存储接入服务下发停止手动录像请求, 支持中心存储和设备存储两种存储模式。萤石设备不支持手动录像功能。 + * 2.由于停止手动录像命令需要先下发到sac再到存储,实际录像结束时间与调用接口时间会稍有延迟。 + * 综合安防管理平台iSecure Center V1.5及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param taskId 录像任务id + * @return 调用结果 + */ +// public static JSONObject stopCatchVideo(String cameraIndexCode, String taskId) { +// final String stopCatchVideoApi = ARTEMIS_PATH + STOP_RECORD_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, stopCatchVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// jsonBody.put("taskID", taskId); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("停止手动录像请求参数:{} ," + +// "\n停止手动录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 录像回放 + * + * @param cameraIndexCode 监控点唯一标识 + * @param start 查询开始时间 + * @param end 查询结束时间 + * @return 调用结果 + */ +// public static JSONObject getHistoryVideoURL(String cameraIndexCode, Date start, Date end) { +// final String getHistoryVideoURLApi = ARTEMIS_PATH + PLAY_BACK_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getHistoryVideoURLApi); +// +// String contentType = "application/json"; +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) +// jsonBody.put("beginTime", DateFormatUtils.format(start, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) +// jsonBody.put("endTime", DateFormatUtils.format(end, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// //0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("recordLocation", 0); +// //hik,rtsp,rtmp-beginTime=20190902T100303&endTime=20190902T100400,hls +// jsonBody.put("protocol", "rtsp"); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); +// logger.debug("获取手动录像Url请求参数:{} ," + +// "\n获取手动录像Url响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + /** + * 云台操作 + * 根据监控点编号进行云台操作接口 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param action 0-开始 ,1-停止 注:GOTO_PRESET命令下填任意值均可转到预置点,建议填0即可 + * @param command 不区分大小写,说明: + * LEFT 左转 + * RIGHT右转 + * UP 上转 + * DOWN 下转 + * ZOOM_IN 焦距变大 + * ZOOM_OUT 焦距变小 + * LEFT_UP 左上 + * LEFT_DOWN 左下 + * RIGHT_UP 右上 + * RIGHT_DOWN 右下 + * FOCUS_NEAR 焦点前移 + * FOCUS_FAR 焦点后移 + * IRIS_ENLARGE 光圈扩大 + * IRIS_REDUCE 光圈缩小 + * WIPER_SWITCH 接通雨刷开关 + * START_RECORD_TRACK 开始记录轨迹 + * STOP_RECORD_TRACK 停止记录轨迹 + * START_TRACK 开始轨迹 + * STOP_TRACK 停止轨迹; + * 以下命令presetIndex不可为空: + * GOTO_PRESET到预置点 + * @param speed 云台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 查询结果 + */ +// public static JSONObject controlling(String cameraIndexCode, Integer action, String command, Integer speed, Integer presetIndex) { +// final String catchImageApi = ARTEMIS_PATH + CONTROL_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// jsonBody.put("action", action); +// jsonBody.put("command", command); +// if (speed != null) { +// jsonBody.put("speed", speed); +// } +// if (presetIndex != null) { +// jsonBody.put("presetIndex", presetIndex); +// } +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("云台操作请求参数:{} ," + +// "\n云台操作响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + /** + * 3D放大 + * 该接口用于控制监控点进行3D电子放大。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param startX 开始放大的X坐标,范围:0-255。由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕X坐标/屏幕宽 * 255,即该坐标位X坐标占总屏幕宽的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param startY 开始放大的Y坐标,范围:0-255,由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕Y坐标/屏幕高 * 255,即该坐标位Y坐标占总屏幕高的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param endX 结束放大的X坐标,范围以及计算方式同startX + * @param endY 结束放大的Y坐标,范围以及计算方式同startY + * @return 查询结果 + */ + public static JSONObject selZoom(String cameraIndexCode, Integer startX, Integer startY, Integer endX, Integer endY) { + final String catchImageApi = ARTEMIS_PATH + SEL_ZOOM_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("startX", startX); + jsonBody.put("startY", startY); + jsonBody.put("endX", endX); + jsonBody.put("endY", endY); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("3D放大请求参数:{} ," + + "\n3D放大响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 设置预置点信息 + * 该接口用于设置监控点的预置点信息,若参数传已经存在的预置点编号,则可修改预置点信息 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param presetName 预置点名称 + * @param presetIndex 预置点编号(1 - 300) + * @return 调用结果 + * @throws Exception 抛出异常 + */ +// public static JSONObject presetsAddition(String cameraIndexCode, String presetName, Integer presetIndex) { +// final String catchImageApi = ARTEMIS_PATH + PRESETS_ADDITION_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// jsonBody.put("presetName", presetName); +// jsonBody.put("presetIndex", presetIndex); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("设置预置点信息请求参数:{} ," + +// "\n设置预置点信息响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + /** + * 查询预置点信息 + * 该接口用于查询监控点的预置点信息。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject presetsSearches(String cameraIndexCode) { +// final String catchImageApi = ARTEMIS_PATH + PRESETS_SEARCHES_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("查询预置点信息请求参数:{} ," + +// "\n查询预置点信息响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + +// /** +// * 删除预置点信息 +// * 该接口用于删除监控点的预置点信息。 +// * 综合安防管理平台iSecure Center V1.2及以上版本 +// * +// * @param cameraIndexCode 监控点唯一标识 +// * @param presetIndex 预置点编号 +// * @return 调用结果 +// */ +// public static JSONObject presetsDeletion(String cameraIndexCode, Integer presetIndex) { +// final String catchImageApi = ARTEMIS_PATH + PRESETS_DELETION_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// jsonBody.put("presetIndex", presetIndex); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("删除预置点信息请求参数:{} ," + +// "\n删除预置点信息响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + +// /** +// * 获取监控点在线状态接口 +// * @param camerasList +// * @param size +// * @return +// */ +// public static List getCameraStatus(String[] camerasList,int size){ +// Map onlinePath = new HashMap(2) { +// { +// put("https://", onLineURLsApi);//根据现场环境部署确认是http还是https +// } +// }; +// JSONObject onLineParam = new JSONObject(); +// onLineParam.put("pageNo",1); +// onLineParam.put("pageSize",size); +// onLineParam.put("indexCodes",camerasList); +// +// String result2 = ArtemisHttpUtil.doPostStringArtemis(onlinePath, onLineParam.toString(), null, null, CONTENT_TYPE , null); +// JSONObject result2Json = JSON.parseObject(result2); +// +// JSONObject data2Json = result2Json.getJSONObject("data"); +// JSONArray list2 = data2Json.getJSONArray("list"); +// List onlineBeans = list2.toJavaList(OnlineBean.class); +// +// return onlineBeans; +// } + + public static String getCameraInfo(String cameraIndexCode){ + Map onlinePath = new HashMap(2) { + { + put("https://", cameraURLsApi);//根据现场环境部署确认是http还是https + } + }; + JSONObject onLineParam = new JSONObject(); + onLineParam.put("cameraIndexCode",cameraIndexCode); + + String result2 = ArtemisHttpUtil.doPostStringArtemis(onlinePath, onLineParam.toString(), null, null, CONTENT_TYPE , null); + JSONObject result2Json = JSON.parseObject(result2); + + JSONObject data2Json = result2Json.getJSONObject("data"); + + return JSON.toJSONString(data2Json); + } + + /** + * 云台跳转 + * 综合安防管理平台iSecure Center V1.0及以上版本 + *

https://open.hikvision.com/docs/8530061f19534a9993e2afeb70e7c96a#e30b9484

+ * @param cameraIndexCode 监控点唯一标识 + * @param speed 台速度,取值范围为1-100,默认50 + * @param cameraIndexCode 监控点编号 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return + * @throws Exception + */ + public static JSONObject videoController(String cameraIndexCode,String command,Integer speed,String presetIndex,Integer action) { + final String goToPresetApi = ARTEMIS_PATH +"/api/video/v1/ptzs/controlling"; + Map path = new HashMap(2) { + { + put("https://", goToPresetApi); + } + }; + + String contentType = "application/json"; + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("action", action); + jsonBody.put("command", command); + if(speed==null) { + speed = 50; + } + jsonBody.put("speed", speed); + jsonBody.put("presetIndex", presetIndex); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// + logger.debug("跳转到监控点请求参数:\t" + body + "\n跳转到监控点响应结果:\t" + response); + JSONObject result = JSON.parseObject(response); + if("0".equals(result.getString("code"))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + + public static void main(String[] args) { + // System.out.println(callPostStringApi()); + // System.out.println("===:"+getCameraInfo("5dadcc624c454be1a280c39fc18f043a")); + + // String StringeResult = signInfo(); +// String imageUrl = "http://192.168.100.22:6120/pic?=d08ie912iace=o90-bp511az8e*fs2i6493428660e2=t1i9m*dp=*3pdi=*1sdi=*5b2i36bee5757d=a0--872e67*l194od1-651025d8"; +// String picUrl = "/" + imageUrl.split("/")[3]; +// System.out.println(picUrl); +// String StringeResult = imgUrl("64bba8f5-c381-48b3-9b23-749f28885909", +// "/pic?=d08ie912iace=o90-bp511az8e*fs2i6493428660e2=t1i9m*dp=*3pdi=*1sdi=*5b2i36bee5757d=a0--872e67*l194od1-651025d8"); +// System.out.println("StringeResult结果示例: "+StringeResult); + // callPostImgStringApi(); + // String jsonstr = "{\"code\":\"0\",\"msg\":\"success\",\"data\":{\"total\":26,\"pageNo\":1,\"pageSize\":100,\"list\":[{\"altitude\":null,\"cameraIndexCode\":\"1c14df35daa449bf8a34c28d0e1ffabd\",\"cameraName\":\"蓝湾test\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,remote_vss,event_vss,vss,record,ptz,net,maintenance,status\",\"capabilitySetName\":\"IO能力,视频设备远程获取能力,视频事件能力,视频能力,录像能力,云台能力,网络参数配置能力,设备维护能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-21T11:43:49.672+08:00\",\"encodeDevIndexCode\":\"835163c8ba454b7cb9cd2544bc1ee39a\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000026\",\"installLocation\":\"\",\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":null,\"recordLocationName\":null,\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-21T14:46:53.107+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"9f471a45013e4e06873f58b8539a0347\",\"cameraName\":\"test\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,remote_vss,event_vss,vss,record,ptz,net,maintenance,status\",\"capabilitySetName\":\"IO能力,视频设备远程获取能力,视频事件能力,视频能力,录像能力,云台能力,网络参数配置能力,设备维护能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-19T12:23:33.703+08:00\",\"encodeDevIndexCode\":\"a529d4b439b648dba9dcd438861abffc\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000025\",\"installLocation\":\"\",\"keyBoardCode\":null,\"latitude\":\"\",\"longitude\":\"\",\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":null,\"recordLocationName\":null,\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-21T14:47:24.797+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"da7c22239c97411282570849c9fc4c74\",\"cameraName\":\"岭前头村\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T15:48:06.610+08:00\",\"encodeDevIndexCode\":\"0d88a7eeada846698537318abddcd46f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000024\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.215+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"66a1232da34e4767a167c923c1dc59fb\",\"cameraName\":\"万达维湾东南\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:11:23.389+08:00\",\"encodeDevIndexCode\":\"6146a7c85f24440198752a1f26d1a996\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000023\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.456+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2fc59c6955e34a10a322935773381084\",\"cameraName\":\"张托村\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:48.409+08:00\",\"encodeDevIndexCode\":\"071813d4b72d4bcaa74709fdca8a42b6\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000022\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.593+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2befe46315a843d39141a127f906a909\",\"cameraName\":\"陈家贡大桥 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:08:50.645+08:00\",\"encodeDevIndexCode\":\"71d980f084214e688d98d0801ce0a05f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000021\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.975+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"ebf3f1e476d641e69f7528ef5152ef40\",\"cameraName\":\"陈家贡大桥02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:08:50.645+08:00\",\"encodeDevIndexCode\":\"71d980f084214e688d98d0801ce0a05f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000020\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.012+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"b2eb5b869d354db5979c47a589d803dd\",\"cameraName\":\"积米崖 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:06:01.488+08:00\",\"encodeDevIndexCode\":\"de57ebfabf204c18b0ae9fe443b60073\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000019\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.565+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"6d69d98d3fd746518e6d41db3c53d33a\",\"cameraName\":\"积米崖 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:06:01.490+08:00\",\"encodeDevIndexCode\":\"de57ebfabf204c18b0ae9fe443b60073\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000018\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.637+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2c2bb022b76941cd89a77017d746b004\",\"cameraName\":\"西杨家洼 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:07.693+08:00\",\"encodeDevIndexCode\":\"89277e1ff5464a608c1f22a349067898\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000017\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.693+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"5e8d65c89e5645ea89369c2993ec96e1\",\"cameraName\":\"西杨家洼 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:07.695+08:00\",\"encodeDevIndexCode\":\"89277e1ff5464a608c1f22a349067898\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000016\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.726+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"f20b9a15035c458eb41b8a9a9cb1da35\",\"cameraName\":\"跨海大桥\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:12:04.354+08:00\",\"encodeDevIndexCode\":\"d0628f35db8d4c0b9f75d0ba35524d21\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000015\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.344+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"52f8edd67f00492399be1fc289eef7da\",\"cameraName\":\"胡家山 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:02.222+08:00\",\"encodeDevIndexCode\":\"9b3eb53f22d9458a83c3885f0a23c459\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000014\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.361+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2b068286a653476f9fb1dfeaef11e109\",\"cameraName\":\"胡家山 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:02.224+08:00\",\"encodeDevIndexCode\":\"9b3eb53f22d9458a83c3885f0a23c459\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000013\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.430+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"63950ef4abbf46dd8b8646111b6cf3ed\",\"cameraName\":\"上戏东 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:40.749+08:00\",\"encodeDevIndexCode\":\"cdeb9164940f4a3c81d45b5cc9c1e6d9\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000012\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.159+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"a65565df7c6c4556bd365d8adaa5dd83\",\"cameraName\":\"上戏东 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:40.803+08:00\",\"encodeDevIndexCode\":\"cdeb9164940f4a3c81d45b5cc9c1e6d9\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000011\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.224+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"328c9d58b31a405a8ce189cc61fe4fc6\",\"cameraName\":\"爱琴海 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:09:18.941+08:00\",\"encodeDevIndexCode\":\"d0e4c74338454a9b99c324643c119d05\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000010\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.838+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"dca7c29cfc9e43f1b5f40c6b92405b27\",\"cameraName\":\"爱琴海 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:09:18.943+08:00\",\"encodeDevIndexCode\":\"d0e4c74338454a9b99c324643c119d05\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000009\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.868+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"11902fe0bc43431eb07530903460e7db\",\"cameraName\":\"琴岛之眼\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:18:57.498+08:00\",\"encodeDevIndexCode\":\"f9018b010d5140b4ac1ae1fa76f06d93\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000008\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.853+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"4637b2e263a2409a9682a35e9df77c81\",\"cameraName\":\"王台铲尖村东北\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:20:16.450+08:00\",\"encodeDevIndexCode\":\"51a66e215c4f49cea6e65a9b72f38618\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000007\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.753+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"a411dd3c829047b6b49d70d65428e439\",\"cameraName\":\"欢乐海湾 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_gis,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_face,event_rule\",\"capabilitySetName\":\"IO能力,可视域事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,人脸事件能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:17:57.610+08:00\",\"encodeDevIndexCode\":\"13881aa4a2a24e328033f19dd7323f1c\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000006\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.965+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"8c1954b15bfd4b00a4de219ad7afb1dc\",\"cameraName\":\"欢乐海湾 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_gis,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_face,event_rule\",\"capabilitySetName\":\"IO能力,可视域事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,人脸事件能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:17:57.612+08:00\",\"encodeDevIndexCode\":\"13881aa4a2a24e328033f19dd7323f1c\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000005\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.000+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"08e707b1446d4dafa83a23cf2b682ddf\",\"cameraName\":\"保利海上罗兰南\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:55:02.064+08:00\",\"encodeDevIndexCode\":\"5843ee94013d446ab4be58afe2df951f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000004\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.106+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"295fbd04c7494a85b01214a612de8782\",\"cameraName\":\"星光岛一号桥\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_rule\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:44:26.978+08:00\",\"encodeDevIndexCode\":\"28817e4d0abb4a8e8a42ad1c4d3f0856\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000003\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.221+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"4030e6e41dae44c1a56abcb018046d56\",\"cameraName\":\"望海宾馆 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,gis,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status,event_rule,event_heat\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,可视域能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力,热成像事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:41:29.690+08:00\",\"encodeDevIndexCode\":\"d60de69b808742308e2314a2967fcbfe\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000002\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.375+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"cb6511ef7eb04c37948ab7de7f2925d1\",\"cameraName\":\"望海宾馆 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,gis,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status,event_rule,event_heat\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,可视域能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力,热成像事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:41:29.698+08:00\",\"encodeDevIndexCode\":\"d60de69b808742308e2314a2967fcbfe\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000001\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.445+08:00\"}]}}"; + // JSONObject json = JSONObject.parseObject(jsonstr); + System.out.println(callPostStringApi()); +// System.out.println(getPreviewUrl("4a018f27158b44ecb83682b00b9ec3c3","")); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDataServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDataServiceImpl.java new file mode 100644 index 0000000..b2a1f71 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDataServiceImpl.java @@ -0,0 +1,128 @@ +package com.ltgk.smartFishingPort.service.impl; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.common.core.redis.RedisCache; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.domain.dto.BoatDynamicDto; +import com.ltgk.smartFishingPort.domain.entity.BoatData; +import com.ltgk.smartFishingPort.domain.vo.CurrentAisDynamicVO; +import com.ltgk.smartFishingPort.mapper.BoatDataMapper; +import com.ltgk.smartFishingPort.service.IBoatDataService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @Author: zhouyaoyao + * @Date 2025/6/10 17:54 + * Description: + */ +@Service +@Slf4j +public class BoatDataServiceImpl extends ServiceImpl implements IBoatDataService { + + @Resource + private RedisCache redisUtils; + + @Override + public IPage selectByPage(BoatData boatData) { + + int pageNum = Objects.isNull(boatData.getPageNum()) ? 1 : boatData.getPageNum(); + int pageSize = Objects.isNull(boatData.getPageSize()) ? 15 : boatData.getPageSize(); + IPage page = new Page<>(pageNum, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = MybatisUtil.notNullField(boatData).lambda(); + lambdaQueryWrapper.orderByDesc(BoatData::getUpdateTime); + return baseMapper.selectPage(page, lambdaQueryWrapper); + } + + /** + * 根据经纬度获取AIS数据中距离最近的点位且更新时间为±1分钟之内的数据 + * + * @param longitude:经度 + * @param latitude:维度 + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/2 + */ + @Override + public Object getNearestAisData(String longitude, String latitude) { + DateTime startTime = DateUtil.date(); + List objList = redisUtils.getMByScript("ais-collect-name:*"); + DateTime entTime = DateUtil.date(); + log.info("keys * 查询redis 耗时:{} s", (entTime.getTime() - startTime.getTime()) / 1000); + // 不为空的情况下继续执行 + if (!Objects.isNull(objList) && CollectionUtils.isNotEmpty(objList)) { + + // 2. 计算筛选时间范围:当前时间 ±5 分钟 + DateTime now = DateUtil.date(); // 当前时间(Hutool封装,等价于 new Date(),线程安全) + DateTime fiveMinAgo = DateUtil.offsetMinute(now, -1); // 左边界:5分钟前 + DateTime fiveMinLater = DateUtil.offsetMinute(now, 1); // 右边界:5分钟后 + // 获取并且定位时间在 ± 5分钟之内的数据 + List list = objList.stream().map(m -> { + BoatDynamicDto boatDynamicDto = JSONObject.parseObject(m.toString(), BoatDynamicDto.class); + return new CurrentAisDynamicVO() + .setShipPlate(boatDynamicDto.getBoatName()) + .setBoatName(boatDynamicDto.getBoatNameEn()) + .setMmsi(boatDynamicDto.getTerminalCode()) + .setAisStatus("已开启") + .setSog(boatDynamicDto.getSog()) + .setCog(boatDynamicDto.getCog()) + .setLatitude(boatDynamicDto.getLatitude()) + .setLongitude(boatDynamicDto.getLongitude()) + .setDataSource(boatDynamicDto.getDataSource()) + .setGpsTime(boatDynamicDto.getGpsTime()); +// }).filter(f -> "YingJue".equals(f.getDataSource()) && DateUtil.isIn(f.getGpsTime(), fiveMinAgo, fiveMinLater)) + }).filter(f -> DateUtil.isIn(f.getGpsTime(), fiveMinAgo, fiveMinLater)) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(list)) { + double targetLon = Double.parseDouble(longitude); + double targetLat = Double.parseDouble(latitude); + + +// List collect = list.stream() +// .filter(vo -> calculateDistance(targetLon, targetLat, vo.getLongitude(), vo.getLatitude()) <= 11.1) +// .collect(Collectors.toList()); + + return list.stream() + .min((vo1, vo2) -> { + double dist1 = calculateDistance(targetLon, targetLat, vo1.getLongitude(), vo1.getLatitude()); + double dist2 = calculateDistance(targetLon, targetLat, vo2.getLongitude(), vo2.getLatitude()); + return Double.compare(dist1, dist2); + }) + .orElse(null); + } + } + return null; + } + + /** + * 使用 Haversine 公式计算两个经纬度坐标之间的距离(单位:米) + * + * @param lon1 经度1 + * @param lat1 纬度1 + * @param lon2 经度2 + * @param lat2 纬度2 + * @return 距离(米) + */ + private double calculateDistance(double lon1, double lat1, double lon2, double lat2) { + final int R = 6371; // 地球半径(千米) + double dLat = Math.toRadians(lat2 - lat1); + double dLon = Math.toRadians(lon2 - lon1); + double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) + * Math.sin(dLon / 2) * Math.sin(dLon / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return R * c * 1000; // 返回米 + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDynamicServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDynamicServiceImpl.java new file mode 100644 index 0000000..202388b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatDynamicServiceImpl.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.domain.entity.BoatDynamic; +import com.ltgk.smartFishingPort.mapper.BoatDynamicMapper; +import com.ltgk.smartFishingPort.service.IBoatDynamicService; +import org.springframework.stereotype.Service; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:07 + * Description: + */ +@Service +public class BoatDynamicServiceImpl extends ServiceImpl implements IBoatDynamicService { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatPathServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatPathServiceImpl.java new file mode 100644 index 0000000..170ca1e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/BoatPathServiceImpl.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.domain.entity.BoatPath; +import com.ltgk.smartFishingPort.mapper.BoatPathMapper; +import com.ltgk.smartFishingPort.service.IBoatPathService; +import org.springframework.stereotype.Service; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:01 + * Description: + */ +@Service +public class BoatPathServiceImpl extends ServiceImpl implements IBoatPathService { +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DroneServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DroneServiceImpl.java new file mode 100644 index 0000000..af8fd69 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DroneServiceImpl.java @@ -0,0 +1,456 @@ +package com.ltgk.smartFishingPort.service.impl; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.TypeReference; +import com.ltgk.smartFishingPort.common.DroneClientCommon; +import com.ltgk.smartFishingPort.common.DroneResponseBase; +import com.ltgk.smartFishingPort.common.constant.DroneConstruct; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.common.core.redis.RedisCache; +import com.ltgk.smartFishingPort.common.enums.ClassCodes; +import com.ltgk.smartFishingPort.common.enums.DroneToRtmp; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.domain.drone.*; +import com.ltgk.smartFishingPort.domain.vo.*; +import com.ltgk.smartFishingPort.service.DroneService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; + +/** + * @author liutailin + * @description 无人机模块 + * @date 2019-06-02 9:06. + */ +@Slf4j +@Service +public class DroneServiceImpl implements DroneService { + @Autowired + private DroneClientCommon droneClientCommon; + @Resource + private RedisCache redisUtils; + + private final String UAV_VIDEO_STREAM_TASK_ID = "uav:videoStream:taskId:"; + + /** + * 获取司空系统状态 + * + * @return + */ + @Override + public Response getDroneSystemStatus() { + DroneResponseBase resp = droneClientCommon.getDroneSystemStatus(); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + DroneSystemStatusVO droneSystemStatusVO = new DroneSystemStatusVO(); + droneSystemStatusVO.setCode(resp.getCode()); + droneSystemStatusVO.setMessage(resp.getMessage()); + return Response.ok(droneSystemStatusVO); + } + + /** + * 获取项目列表 + * + * @return + */ + + @Override + public Response> getDroneProject() { + String respStr = droneClientCommon.sendDroneGetRequest(DroneConstruct.PROJECT, null, null); + DroneResponseBase> resp = JSON.parseObject(respStr, new TypeReference>>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + List result = new ArrayList<>(); + resp.getData().getList().forEach(projectRespDto -> { + DroneProjectVO droneProjectVO = new DroneProjectVO(); + BeanUtils.copyProperties(projectRespDto, droneProjectVO); + droneProjectVO.setCreatedAt(new Date(projectRespDto.getCreatedAt())); + droneProjectVO.setUpdatedAt(new Date(projectRespDto.getUpdatedAt())); + result.add(droneProjectVO); + }); + return Response.ok(result); + } + + /** + * 获取设备列表 + * + * @param req + * @return + */ + @Override + public Response> getDroneDevice(DroneDeviceReq req) { + String respStr = droneClientCommon.sendDroneGetRequest(DroneConstruct.DEVICE, null, req.getUuid()); + DroneResponseBase> resp = JSON.parseObject(respStr, new TypeReference>>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData().getList()); + } + + /** + * 给设备发送指令 + * + * @param req + * @return + */ + @Override + public Response droneCommand(DroneCommandReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.COMMAND.replace("$command", req.getDeviceSn()), JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + DroneSystemStatusVO droneSystemStatusVO = new DroneSystemStatusVO(); + droneSystemStatusVO.setCode(resp.getCode()); + droneSystemStatusVO.setMessage(resp.getMessage()); + return Response.ok(droneSystemStatusVO); + } + + /** + * 机场相机切换 + * + * @param req + * @return + */ + @Override + public Response airportCameraSwitch(AirportCameraSwitchReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.AIRPORT_CAMERA_SWITCH, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + DroneSystemStatusVO droneSystemStatusVO = new DroneSystemStatusVO(); + droneSystemStatusVO.setCode(resp.getCode()); + droneSystemStatusVO.setMessage(resp.getMessage()); + return Response.ok(droneSystemStatusVO); + } + + /** + * 飞行器相机切换 + * + * @param req + * @return + */ + @Override + public Response droneCameraSwitch(DroneCameraSwitchReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.DRONE_CAMERA_SWITCH, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + DroneSystemStatusVO droneSystemStatusVO = new DroneSystemStatusVO(); + droneSystemStatusVO.setCode(resp.getCode()); + droneSystemStatusVO.setMessage(resp.getMessage()); + return Response.ok(droneSystemStatusVO); + } + + /** + * 获取控制权 + * + * @param req + * @return + */ + @Override + public Response droneControlObtain(DroneControlObtainReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.DRONE_CONTROL_OBTAIN, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + /** + * 释放控制权 + * + * @param req + * @return + */ + @Override + public Response droneControlRelease(DroneControlObtainReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.DRONE_CONTROL_RELEASE, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + /** + * 获取航线列表 + * + * @param req + * @return + */ + @Override + public Response> getDroneWayLine(DroneDeviceReq req) { + String respStr = droneClientCommon.sendDroneGetRequest(DroneConstruct.DRONE_WAY_LINE, null, req.getUuid()); + DroneResponseBase> resp = JSON.parseObject(respStr, new TypeReference>>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData().getList()); + } + + /** + * 获取航线详情 + * + * @param req + * @return + */ + @Override + public Response getDroneWayLineDetail(GetDroneWayLineDetailReq req) { + String respStr = droneClientCommon.sendDroneGetRequest(DroneConstruct.DRONE_WAY_LINE_DETAIL.replace("$waylineId", req.getWayLineId()), null, req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + /** + * 创建飞行任务 + * + * @param req + * @return + */ + @Override + public Response createDroneTask(CreateDroneTaskReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.CREATE_FLIGHT_TASK, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + /** + * 开始直播 + * + * @param req + * @return + */ + @Override + public Response startLive(StartLiveReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.START_LIVE, JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + /** + * 更新飞行任务状态 + * + * @param req + * @return + */ + @Override + public Response updateDroneTaskStatus(UpdateDroneTaskStatusReq req) { + String respStr = droneClientCommon.sendDronePostRequest(DroneConstruct.CREATE_FLIGHT_TASK_STATUS.replace("$taskUuid", req.getTask_uuid()), JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + @Override + public Response> getDroneTaskList(GetDroneTaskListReq req) { + Map param = new HashMap<>(); + param.put("uuid", req.getUuid()); + param.put("sn", req.getSn()); + param.put("name", req.getName()); + param.put("begin_at", req.getBegin_at()); + param.put("end_at", req.getEnd_at()); + param.put("task_type", req.getTask_type()); + param.put("status", req.getStatus()); + String respStr = droneClientCommon.sendDroneGetRequest(DroneConstruct.GET_FLIGHT_TASK_LIST, param, req.getUuid()); + DroneResponseBase> resp = JSON.parseObject(respStr, new TypeReference>>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData().getList()); + } + + @Override + public Response droneOneTouchTakeoff(DroneOneTouchTakeoffReq req) { + String respStr = droneClientCommon.sendDroneOneTouchTakeoffPostRequest(DroneConstruct.ONE_TOUCH_TAKEOFF.replace("$taskUuid", req.getUuid()), JSONUtil.toJsonStr(req), req.getUuid()); + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + @Override + public Response droneControlObtainV2(DroneControlObtainReqV2 req) { + String respStr = null; + if (req.getObtainOrRelease()) { + respStr = droneClientCommon.sendDroneOneTouchTakeoffPostRequest(DroneConstruct.DRONE_CONTROL_OBTAIN_V2.replace("$projUuid", req.getUuid()), JSONUtil.toJsonStr(req), req.getUuid()); + } else { + respStr = droneClientCommon.sendDroneOneTouchTakeoffDeleteRequest(DroneConstruct.DRONE_CONTROL_OBTAIN_V2.replace("$projUuid", req.getUuid()), JSONUtil.toJsonStr(req), req.getUuid()); + } + if (StringUtils.isBlank(respStr)) { + return Response.fail("请求失败"); + } + DroneResponseBase resp = JSON.parseObject(respStr, new TypeReference>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + @Override + public Response> droneControlStatus(DroneControlStatusReq req) { + Map map = new HashMap<>(); + map.put("drone_sn_list", req.getDrone_sn_list()); + String respStr = droneClientCommon.sendDroneOneTouchTakeoffGetRequest(DroneConstruct.DRONE_CONTROL_OBTAIN_V2.replace("$projUuid", req.getUuid()), map, req.getUuid()); + DroneResponseBase> resp = JSON.parseObject(respStr, new TypeReference>>() { + }); + if (!resp.getCode().equals(0)) { + return Response.fail(resp.getMessage()); + } + return Response.ok(resp.getData()); + } + + @Override + public Response videoStreamDetectSwitch(VideoStreamDetectSwitchReq req) { + + // 检测预警算法添加 + if (req.getStatus().equals("start") && ObjectUtils.isNotEmpty(DroneToRtmp.getRtmpByName(req.getSn()))) { + req.setTask_id(UUID.randomUUID().toString()); + AddStreamDetectTaskReq addStreamDetectTaskReq = new AddStreamDetectTaskReq(); + addStreamDetectTaskReq.setTask_id(req.getTask_id()); + addStreamDetectTaskReq.setSrc_url(DroneToRtmp.getRtmpByName(req.getSn()).getSrcUrl()); + addStreamDetectTaskReq.setDst_url(DroneToRtmp.getRtmpByName(req.getSn()).getDstUrl()); + addStreamDetectTaskReq.setClass_codes(ClassCodes.getAllCode()); + addStreamDetectTaskReq.setDevice_sn(req.getSn()); + String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.ADD_STREAM_DETECT_TASK, JSONUtil.toJsonStr(addStreamDetectTaskReq)); + VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + req.setClass_codes(ClassCodes.getAllCode()); + // 开启算法 + respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.CONTROL_DETECTION, JSONUtil.toJsonStr(req)); + resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + VideoStreamDetectSwitchResp videoStreamDetectSwitchResp = new VideoStreamDetectSwitchResp(); + videoStreamDetectSwitchResp.setTaskId(req.getTask_id()); + videoStreamDetectSwitchResp.setHttpUrl(DroneToRtmp.getRtmpByName(req.getSn()).getHttpUrl()); + return Response.ok(videoStreamDetectSwitchResp); + } else { + String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.CONTROL_DETECTION, JSONUtil.toJsonStr(req)); + VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + return Response.ok("关闭算法流成功"); + } + + } + + /** + * 获取无人机视频流 + * + * @param req: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/11/27 + */ + @Override + public Response getVideoStream(GetVideoStreamReq req) { + String taskId = UUID.randomUUID().toString(); + redisUtils.setCacheObject(UAV_VIDEO_STREAM_TASK_ID + req.getSn(), taskId); + req.setTask_id(taskId); + // 检测预警算法添加 +// if (req.getStatus().equals("start") && ObjectUtils.isNotEmpty(DroneToRtmp.getRtmpByName(req.getSn()))) { + AddStreamDetectTaskReq addStreamDetectTaskReq = new AddStreamDetectTaskReq() + .setTask_id(req.getTask_id()) + .setSrc_url(DroneToRtmp.getRtmpByName(req.getSn()).getSrcUrl()) + .setDst_url(DroneToRtmp.getRtmpByName(req.getSn()).getDstUrl()) + .setClass_codes(ClassCodes.getAllCode()) + .setDevice_sn(req.getSn()); + String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.ADD_STREAM_DETECT_TASK, JSONUtil.toJsonStr(addStreamDetectTaskReq)); + log.info(">>>>>>>>>>>>>>>获取无人机视频流:{}", respStr); + VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + VideoStreamDetectSwitchResp videoStreamDetectSwitchResp = new VideoStreamDetectSwitchResp(); + videoStreamDetectSwitchResp.setTaskId(req.getTask_id()); + videoStreamDetectSwitchResp.setHttpUrl(DroneToRtmp.getRtmpByName(req.getSn()).getHttpUrl()); + return Response.ok(videoStreamDetectSwitchResp); +// } else { +// String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.CONTROL_DETECTION, JSONUtil.toJsonStr(req)); +// VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { +// }); +// if (!resp.getCode().equals(200)) { +// return Response.fail(resp.getMsg()); +// } +// return Response.ok("关闭算法流成功"); +// } + } + + @Override + public Response doStartOrStopUavAlgorithm(GetVideoStreamReq req) { + String taskId = redisUtils.getCacheObject(UAV_VIDEO_STREAM_TASK_ID + req.getSn()).toString(); + req.setTask_id(taskId); + // 检测预警算法添加 + if (req.getStatus().equals("start") && ObjectUtils.isNotEmpty(DroneToRtmp.getRtmpByName(req.getSn()))) { + // 开启算法 + String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.CONTROL_DETECTION, JSONUtil.toJsonStr(req)); + log.info(">>>>>>>>>>>>>>>>开启算法:{}", respStr); + VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + VideoStreamDetectSwitchResp videoStreamDetectSwitchResp = new VideoStreamDetectSwitchResp(); + videoStreamDetectSwitchResp.setTaskId(req.getTask_id()); + videoStreamDetectSwitchResp.setHttpUrl(DroneToRtmp.getRtmpByName(req.getSn()).getHttpUrl()); + return Response.ok(videoStreamDetectSwitchResp); + } else { + log.info(">>>>>>>>>>>>关闭无人机算法:{}", JSONUtil.toJsonStr(req)); + req.setClass_codes(ClassCodes.getAllCode()); + String respStr = droneClientCommon.sendVideoStreamDetectSwitch(DroneConstruct.CONTROL_DETECTION, JSONUtil.toJsonStr(req)); + VideoStreamResp resp = JSON.parseObject(respStr, new TypeReference() { + }); + if (!resp.getCode().equals(200)) { + return Response.fail(resp.getMsg()); + } + return Response.ok("关闭算法流成功"); + } + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsCameraService.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsCameraService.java new file mode 100644 index 0000000..d8ae248 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsCameraService.java @@ -0,0 +1,84 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.common.utils.http.HttpUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * @Author: zhouyaoyao + * @Date 2025/2/25 16:45 + * Description: 通过 SDK 远程操作监控设备 + */ +@Service +public class DsCameraService { + + /** + * 获取监控设备 PTZ 配置链接 + */ + @Value("${sdk.hk.getPtzCfgUrl}") + private String hkGetPtzCfgUrl; + + /** + * 设置监控设备 PTZ 配置链接 + */ + @Value("${sdk.hk.setPtzCfgUrl}") + private String hkSetPtzCfgUrl; + + /** + * 订阅布防监控摄像头链接 + */ + @Value("${sdk.hk.setupAlarmChanUrl}") + private String setupAlarmChanUrl; + /** + * 获取监控设备 PTZ 配置 + */ + public Object hkGetPtzCfg(String videoIp, String videoPort, String videoAccount, String videoPass) { + + String param = "videoIp="+videoIp+"&videoPort="+videoPort+"&videoAccount="+videoAccount+"&videoPass="+videoPass; + String resultStr = HttpUtils.sendPost(hkGetPtzCfgUrl,param); + if (StringUtils.isEmpty(resultStr)) { + return null; + } + JSONObject resultObj = JSONObject.parseObject(resultStr); + boolean success = resultObj.getBooleanValue("success"); + if (success) { + return resultObj.getJSONObject("result"); + } else { + return null; + } + } + /** + * 订阅布防监控摄像头 + */ + public Object setupAlarmChan(String videoIp, String videoPort, String videoAccount, String videoPass) { + + String param = "videoIp="+videoIp+"&videoPort="+videoPort+"&videoAccount="+videoAccount+"&videoPass="+videoPass; + String resultStr = HttpUtils.sendPost(setupAlarmChanUrl,param); + if (StringUtils.isEmpty(resultStr)) { + return null; + } + JSONObject resultObj = JSONObject.parseObject(resultStr); + boolean success = resultObj.getBooleanValue("success"); + if (success) { + return resultObj.getJSONObject("result"); + } else { + return null; + } + } + + /** + * 设置监控设备 PTZ 配置 + */ + public boolean hkSetPtzCfg(String videoIp, String videoPort, String videoAccount, String videoPass, Integer pValue, Integer tValue, Integer zValue) { + String param = "videoIp="+videoIp+"&videoPort="+videoPort+"&videoAccount="+videoAccount+"&videoPass="+videoPass+"&pValue="+pValue+"&tValue="+tValue+"&zValue="+zValue; + String resultStr = HttpUtils.sendPost(hkSetPtzCfgUrl,param); + if (StringUtils.isEmpty(resultStr)) { + return false; + } + JSONObject resultObj = JSONObject.parseObject(resultStr); + boolean success = resultObj.getBooleanValue("success"); + return success; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsVideoServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsVideoServiceImpl.java new file mode 100644 index 0000000..c228dec --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/DsVideoServiceImpl.java @@ -0,0 +1,401 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.common.core.domain.AjaxResult; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.common.utils.StringUtils; +import com.ltgk.smartFishingPort.common.utils.http.HttpUtils; +import com.ltgk.smartFishingPort.domain.dto.LinkageParamDto; +import com.ltgk.smartFishingPort.domain.entity.DsVideo; +import com.ltgk.smartFishingPort.mapper.DsVideoMapper; +import com.ltgk.smartFishingPort.service.IDsVideoService; +import com.ltgk.smartFishingPort.utils.CameraDegreesUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 视频监控管理表 服务实现类 + *

+ * + * @author zhouyaoyao + * @since 2025-01-19 + */ +@Service +@Slf4j +public class DsVideoServiceImpl extends ServiceImpl implements IDsVideoService { + + @Resource + private DsCameraService dsCameraService; + + @Resource + RedisTemplate redisTemplate; + + @Resource + IDsVideoService dsVideoService; + + private static final String HTTPS_TYPE = "https://"; + + /** + * 能力开放平台的网站路径 + * 路径不用修改,就是/artemis + */ + private static final String ARTEMIS_PATH = "/artemis"; + + /** + * 手动抓图API + */ + private static final String MANUAL_CAPTURE_URL = "/api/video/v1/manualCapture"; + + /** + * post请求application/json类型参数 + */ + private static final String CONTENT_TYPE = "application/json"; + + /** + * 图片下载API + */ + private static final String GET_IMG_URL = "/api/video/v1/events/picture"; + + /** + * 获取监控点在线状态 + */ + public static final String GET_POINT_ONLINE_STATUS_URL = "/api/nms/v1/online/camera/get"; + + /** + * 获取监控设备 PTZ 配置链接 + */ + @Value("${sdk.hk.getPtzCfgUrl}") + private String hkGetPtzCfgUrl; + + /** + * 分页查询 + * + * @param dsVideo + * @return + */ + @Override + public IPage selectByPage(DsVideo dsVideo) { + int pageNum = Objects.isNull(dsVideo.getPageNum()) ? 1 : dsVideo.getPageNum(); + int pageSize = Objects.isNull(dsVideo.getPageSize()) ? 10 : dsVideo.getPageSize(); + IPage page = new Page<>(pageNum, pageSize); + LambdaQueryWrapper queryWrapper = MybatisUtil.notNullField(dsVideo).lambda(); + queryWrapper.orderByDesc(DsVideo::getUpdateAt); + return baseMapper.selectPage(page, queryWrapper); + } + + // @PostConstruct + @Scheduled(cron = "0 0 */2 * * *") + public void startAlarmChanTask() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.like(DsVideo::getVideoName, "热成像"); + List list = list(queryWrapper); + list.stream().forEach(video -> { + try { + dsCameraService.setupAlarmChan(video.getVideoIp(), video.getVideoPort(), video.getVideoAccount(), video.getVideoPassword()); + Thread.sleep(3000); + } catch (Exception e) { + } + }); + } + + /** + * 根据视频监控设备名称批量添加更新 + * + * @param dsVideos + * @return + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean saveBatchByName(List dsVideos) { + + for (DsVideo dsVideo : dsVideos) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(DsVideo::getVideoName, dsVideo.getVideoName()); + if (!update(dsVideo, updateWrapper)) { + save(dsVideo); + } + } + + return true; + } + + /** + * 光电随动控制 + * + * @param msg + * @return + */ + public boolean servoByRadar(String msg) { + JSONObject jsonObject = JSONObject.parseObject(msg); + if (Objects.isNull(jsonObject)) { + return false; + } + Double longitude = jsonObject.getDouble("longitude"); + Double latitude = jsonObject.getDouble("latitude"); + String targetSourceId = jsonObject.getString("targetSourceId"); + String mmsi = jsonObject.getString("mmsi"); + Integer source = jsonObject.getInteger("source"); + if (Objects.isNull(longitude) || Objects.isNull(latitude) || Objects.isNull(source)) { + return false; + } + if (StringUtils.isNotEmpty(targetSourceId) && redisTemplate.hasKey("servo:" + targetSourceId)) { + String deviceCode = redisTemplate.opsForValue().get("servo:" + targetSourceId).toString(); + AjaxResult result = sitMoveByGps(deviceCode, longitude.toString(), latitude.toString()); + return result.isSuccess(); + } else if (StringUtils.isNotEmpty(mmsi) && redisTemplate.hasKey("servo:" + mmsi)) { + String deviceCode = redisTemplate.opsForValue().get("servo:" + mmsi).toString(); + AjaxResult result = sitMoveByGps(deviceCode, longitude.toString(), latitude.toString()); + return result.isSuccess(); + } else { + return false; + } + } + + /** + * 光电联动反向定位联动控制,根据监控设备和将要联动的定位目标经纬度控制视频监控设备转动对焦 + * + * @return + */ + public AjaxResult sitMoveByGps(String deviceCode, String gpsX, String gpsY) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(DsVideo::getVideoCode, deviceCode); + queryWrapper.isNotNull(DsVideo::getHeight); + queryWrapper.last("limit 1"); + DsVideo video = dsVideoService.getOne(queryWrapper); + Double height = video.getHeight().doubleValue(); + if (StringUtils.isBlank(deviceCode) || Objects.isNull(video)) { + return AjaxResult.error("暂时没有该编号的监控摄像头,请核实摄像头编号是否正确!"); + } + String latitude = video.getLatitude().toString(); + String longitude = video.getLongitude().toString(); + int rotateT = video.getRotateT(); + if (StringUtils.isBlank(latitude) || StringUtils.isBlank(longitude)) { + return AjaxResult.error("该监控摄像头没有经纬度定位信息!"); + } + try { + double latitudeVal = Double.parseDouble(latitude); + double longitudeVal = Double.parseDouble(longitude); + double gpsXVal = Double.parseDouble(gpsX); + double gpsYVal = Double.parseDouble(gpsY); + BigDecimal degreeX = CameraDegreesUtil.rotateForNorthByLR(longitudeVal, latitudeVal, gpsXVal, gpsYVal, rotateT); + Integer degreeXVal = (degreeX.multiply(new BigDecimal(10))).intValue(); + degreeXVal = degreeXVal < 0 ? 3600 + degreeXVal : degreeXVal; + BigDecimal degreeY = CameraDegreesUtil.rotateByUD(Objects.isNull(height) ? 0.2 : (height / 1000), longitudeVal, latitudeVal, gpsXVal, gpsYVal); + Integer degreeYVal = (degreeY.multiply(new BigDecimal(10))).intValue(); + BigDecimal distance = CameraDegreesUtil.getDistance(longitudeVal, latitudeVal, gpsXVal, gpsYVal).setScale(5, RoundingMode.HALF_UP); + + + double zNumVal = 1d; + double yVal = 0d; + double xVal = 0d; + String xValArr = video.getXValArr(); + String yValArr = video.getYValArr(); + String zNumValArr = video.getZNumValArr(); + if (StringUtils.isNotBlank(xValArr)) { + List xValArray = JSONObject.parseArray(xValArr, LinkageParamDto.class); + xValArray = xValArray.stream().filter(f -> !Objects.isNull(f.getNumber()) && f.getDistance() >= 0) + .sorted(Comparator.comparing(LinkageParamDto::getDistance).reversed()) + .collect(Collectors.toList()); + // 根据与联动目标的距离调节水平旋转参数 +// if (xValArray.size() == 1) { +// xVal = xValArray.get(0).getNumber(); +// } else +// if (xValArray.size() > 1) { +// for (int i=0;i=linkageParamDto.getDistance()) { +// xVal = linkageParamDto.getNumber(); +// } +// } +// } + // 根据与联动目标的相对方位角调节水平旋转参数 + if (!CollectionUtils.isEmpty(xValArray)) { + int degreeXValTmp = degreeXVal; + Optional optional = xValArray.stream() + .map(m -> { + m.setDistance(new BigDecimal((degreeXValTmp / 10) - m.getDistance()).abs() + .setScale(6, RoundingMode.HALF_UP).doubleValue()); + return m; + }).sorted(Comparator.comparing(LinkageParamDto::getDistance)).findFirst(); + if (optional.isPresent()) { + xVal = optional.get().getNumber(); + } + } + } + // 根据与联动目标的相对距离调节俯仰角参数 + if (StringUtils.isNotBlank(yValArr)) { + List yValArray = JSONObject.parseArray(yValArr, LinkageParamDto.class); + yValArray = yValArray.stream().filter(f -> !Objects.isNull(f.getNumber()) && f.getDistance() >= 0d) + .sorted(Comparator.comparing(LinkageParamDto::getDistance).reversed()) + .collect(Collectors.toList()); +// if (yValArray.size() == 1) { +// yVal = yValArray.get(0).getNumber(); +// } else +// if (yValArray.size() > 1) { +// for (int i=0;i=linkageParamDto.getDistance()) { +// yVal = linkageParamDto.getNumber(); +// } +// } +// } + if (!CollectionUtils.isEmpty(yValArray)) { + BigDecimal distanceTmp = distance; + Optional optional = yValArray.stream() + .map(m -> { + m.setDistance(new BigDecimal(distanceTmp.doubleValue() - m.getDistance().doubleValue()) + .abs().setScale(6, RoundingMode.HALF_UP).doubleValue()); + return m; + }) + .sorted(Comparator.comparing(LinkageParamDto::getDistance)) + .findFirst(); + if (optional.isPresent()) { + yVal = optional.get().getNumber(); + } + } + } + + if (StringUtils.isNotBlank(zNumValArr)) { + List zValArray = JSONObject.parseArray(zNumValArr, LinkageParamDto.class); + zValArray = zValArray.stream().filter(f -> !Objects.isNull(f.getNumber()) && f.getDistance() >= 0d) + .sorted(Comparator.comparing(LinkageParamDto::getDistance).reversed()) + .collect(Collectors.toList()); +// if (zValArray.size() == 1) { +// Double number = zValArray.get(0).getNumber(); +// number = Objects.isNull(number) || number==0d ? 1:number.doubleValue(); +// zNumVal = new BigDecimal(number).doubleValue(); +// } else +// if (zValArray.size() > 1) { +// for (int i=0;i=linkageParamDto.getDistance()) { +// zNumVal = new BigDecimal(number).doubleValue(); +// } +// } +// } + if (!CollectionUtils.isEmpty(zValArray)) { + BigDecimal distanceTmp = distance; + Optional optional = zValArray.stream() + .map(m -> { + m.setDistance(new BigDecimal(distanceTmp.doubleValue() - m.getDistance().doubleValue()) + .abs().setScale(6, RoundingMode.HALF_UP).doubleValue()); + return m; + }) + .sorted(Comparator.comparing(LinkageParamDto::getDistance)) + .findFirst(); + if (optional.isPresent()) { + zNumVal = optional.get().getNumber(); + } + } + } + degreeYVal = degreeYVal + new BigDecimal(yVal * 10).intValue(); + degreeXVal = degreeXVal + new BigDecimal(xVal * 10).intValue(); + double zVal = (distance.multiply(new BigDecimal(zNumVal))).doubleValue(); + + log.debug("degreeXVal:" + degreeXVal); + log.debug("degreeYVal:" + degreeYVal); + log.debug("distance:" + distance); + log.debug("zVal:" + zVal); + double zMaxVal = 60; + if (StringUtils.isNotBlank(video.getVideoIp()) && video.getVideoName().contains("热成像")) { + zMaxVal = Objects.isNull(video.getZRcxVal()) ? 10 : video.getZRcxVal(); + } else { + zMaxVal = Objects.isNull(video.getZMaxVal()) ? 60 : video.getZMaxVal(); + } + zVal = zVal > zMaxVal ? zMaxVal : zVal; + if (StringUtils.isNotEmpty(video.getVideoIp()) && StringUtils.isNotEmpty(video.getVideoPort()) + && StringUtils.isNotEmpty(video.getVideoAccount()) && StringUtils.isNotEmpty(video.getVideoPassword())) { + + boolean ptzResult = dsCameraService.hkSetPtzCfg(video.getVideoIp(), video.getVideoPort() + , video.getVideoAccount(), video.getVideoPassword() + , degreeXVal, degreeYVal, new BigDecimal(zVal * 10).setScale(0, RoundingMode.HALF_UP).intValue()); + return ptzResult ? AjaxResult.success() : AjaxResult.error(); + } + } catch (Exception e) { + return AjaxResult.error("服务异常:" + e.getMessage()); + } finally { +// new Thread(() -> {updateVisualResion();}).start(); + } + return AjaxResult.error(); + } + + @Override + public DsVideo getVideoInfo(DsVideo dsVideo) { + DsVideo dbDsVideo = dsVideoService.getById(dsVideo.getId()); + + return getDsVideoPTZ(dbDsVideo); + } + + /** + * 更新摄像头可视范围字段状态,并获取所有的开启了可视摄像头范围的相关数据 + * + * @param dsVideo:需开启摄像头可视范围的相关摄像头数据 + * @return com.yuhuan.common.core.domain.AjaxResult + * @author Qi ChengBin + * @date 2025/9/15 + */ + @Override + public List updateOneAndFindVideoInfoList(DsVideo dsVideo) { + List resultDsVideoList = new ArrayList<>(); + if (dsVideoService.updateById(dsVideo)) { + // 获取所有的开启了可视摄像头范围相关的数据 + List dsVideoList = dsVideoService.list(new LambdaQueryWrapper() + .eq(DsVideo::getWhetherToTurnOnTheView, 1) + ); + for (DsVideo video : dsVideoList) { + resultDsVideoList.add(getDsVideoPTZ(video)); + } + } + return resultDsVideoList; + } + + /** + * 通过 监控实体获取相关的监控PTZ数据 + * + * @param dbDsVideo:监控视频实体 + * @return com.yuhuan.video.domain.entity.DsVideo + * @author Qi ChengBin + * @date 2025/9/15 + */ + private DsVideo getDsVideoPTZ(DsVideo dbDsVideo) { + String param = "videoIp=" + dbDsVideo.getVideoIp() + "&videoPort=" + dbDsVideo.getVideoPort() + "&videoAccount=" + dbDsVideo.getVideoAccount() + "&videoPass=" + dbDsVideo.getVideoPassword(); + String resultStr = HttpUtils.sendPost(hkGetPtzCfgUrl, param); + + if (StringUtils.isNotBlank(resultStr)) { + JSONObject resultObj = JSONObject.parseObject(resultStr); + boolean success = resultObj.getBooleanValue("success"); + if (success) { + dbDsVideo.setPTZCfg(resultObj.getJSONObject("result")); + } + } + return dbDsVideo; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/EmergencyRescueServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/EmergencyRescueServiceImpl.java new file mode 100644 index 0000000..faa5322 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/EmergencyRescueServiceImpl.java @@ -0,0 +1,32 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.domain.entity.EmergencyRescue; +import com.ltgk.smartFishingPort.mapper.EmergencyRescueMapper; +import com.ltgk.smartFishingPort.service.IEmergencyRescueService; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/** + * @Author: zhouyaoyao + * @Date 2025/9/26 16:09 + * Description: + */ +@Service +public class EmergencyRescueServiceImpl extends ServiceImpl implements IEmergencyRescueService { + @Override + public IPage selectByPage(EmergencyRescue boatData) { + + int pageNum = Objects.isNull(boatData.getPageNum()) ? 1 : boatData.getPageNum(); + int pageSize = Objects.isNull(boatData.getPageSize()) ? 15 : boatData.getPageSize(); + IPage page = new Page<>(pageNum, pageSize); + LambdaQueryWrapper lambdaQueryWrapper = MybatisUtil.notNullField(boatData).lambda(); + lambdaQueryWrapper.orderByDesc(EmergencyRescue::getUpdateTime); + return baseMapper.selectPage(page, lambdaQueryWrapper); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoCameraServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoCameraServiceImpl.java new file mode 100644 index 0000000..b7426de --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoCameraServiceImpl.java @@ -0,0 +1,250 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.common.constant.GlobalConstant; +import com.ltgk.smartFishingPort.common.core.domain.Response; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.domain.entity.VideoCamera; +import com.ltgk.smartFishingPort.mapper.VideoCameraMapper; +import com.ltgk.smartFishingPort.service.IVideoCameraService; +import okhttp3.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + *

+ * 监控设备表 服务实现类 + *

+ * + * @author zhou + * @since 2024-12-16 + */ +@Service +public class VideoCameraServiceImpl extends ServiceImpl implements IVideoCameraService { + + @Value("${sdk.loginDHUrl}") + String loginDHUrl; + @Value("${sdk.attachTrafficDHUrl}") + String attachTrafficDHUrl; + @Value("${sdk.attachAlarmChanDHByAccountUrl}") + String attachAlarmChanDHByAccountUrl; + @Value("${sdk.attachAlarmChanHKByAccountUrl}") + String attachAlarmChanHKByAccountUrl; + + @Override + public IPage findPage(VideoCamera videoCamera, Integer pageNo, Integer pageSize) { + IPage page = new Page<>(pageNo, pageSize); + QueryWrapper wrapper = MybatisUtil.notNullField(videoCamera); + IPage pageList = baseMapper.selectPage(page, wrapper); + return pageList; + } + + @Override + public Object loginDH(String mStrIp, String mNPort, String mStrUser, String mStrPassword) { + OkHttpClient client = new OkHttpClient().newBuilder() + .writeTimeout(1, TimeUnit.MINUTES) + .readTimeout(1, TimeUnit.MINUTES) + .connectTimeout(1, TimeUnit.MINUTES) + .build(); + MediaType mediaType = MediaType.parse("text/plain"); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("m_nPort", mNPort) + .addFormDataPart("m_strIp", mStrIp) + .addFormDataPart("m_strPassword", mStrPassword) + .addFormDataPart("m_strUser", mStrUser) + .build(); + Request request = new Request.Builder() + .url(loginDHUrl) + .method("POST", body) + .build(); + try { + okhttp3.Response response = client.newCall(request).execute(); + return response.body().string(); + } catch (IOException e) { + e.printStackTrace(); + return Response.fail(e.getMessage()); + } + } + + @Override + public Boolean attachTraffic(Long loginHandler, Integer channelId) { + OkHttpClient client = new OkHttpClient().newBuilder() + .writeTimeout(1, TimeUnit.MINUTES) + .readTimeout(1, TimeUnit.MINUTES) + .connectTimeout(1, TimeUnit.MINUTES) + .build(); + MediaType mediaType = MediaType.parse("text/plain"); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("loginHandler", loginHandler + "") + .addFormDataPart("channelId", channelId + "") + .build(); + Request request = new Request.Builder() + .url(attachTrafficDHUrl) + .method("POST", body) + .build(); + boolean result = false; + try { + okhttp3.Response response = client.newCall(request).execute(); + String resultBody = response.body().string().toString(); + try { + JSONObject bodyObject = JSONObject.parseObject(resultBody); + result = "200".equals(String.valueOf(bodyObject.get("code"))); + } catch (Exception e) { + // log.error(e.getMessage()); + result = resultBody.contains("true"); + } + } catch (IOException e) { + e.printStackTrace(); +// return Response.fail(e.getMessage()); + } + return result; + } + + /** + * 通过大华SDK布防订阅视频监控设备 + * + * @param videoIp 视频监控设备IP + * @param videoPort 视频监控设备端口号 + * @param videoAccount 视频监控设备登录用户账号 + * @param videoPass 视频监控设备登录密码 + * @param channelId 视频监控设备通道号 + * @return + */ + @Override + public Boolean attachAlarmChanDHByAccount(String videoIp, String videoPort, String videoAccount, String videoPass, String channelId) { + OkHttpClient client = new OkHttpClient().newBuilder() + .writeTimeout(1, TimeUnit.MINUTES) + .readTimeout(1, TimeUnit.MINUTES) + .connectTimeout(1, TimeUnit.MINUTES) + .build(); + MediaType mediaType = MediaType.parse("text/plain"); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("videoIp", videoIp) + .addFormDataPart("videoPort", videoPort) + .addFormDataPart("videoAccount", videoAccount) + .addFormDataPart("videoPass", videoPass) + .addFormDataPart("channelId", channelId) + .build(); + Request request = new Request.Builder() + .url(attachAlarmChanDHByAccountUrl) + .method("POST", body) + .build(); + boolean result = false; + try { + okhttp3.Response response = client.newCall(request).execute(); + String resultBody = response.body().string().toString(); + try { + JSONObject bodyObject = JSONObject.parseObject(resultBody); + result = "200".equals(String.valueOf(bodyObject.get("code"))); + } catch (Exception e) { + // log.error(e.getMessage()); + result = resultBody.contains("true"); + } + } catch (IOException e) { + e.printStackTrace(); +// return Response.fail(e.getMessage()); + } + return result; + } + + /** + * 通过海康SDK布防订阅视频监控设备 + * + * @param videoIp 视频监控设备IP + * @param videoPort 视频监控设备端口号 + * @param videoAccount 视频监控设备登录用户账号 + * @param videoPass 视频监控设备登录密码 + * @return + */ + @Override + public Boolean attachAlarmChanHKByAccount(String videoIp, String videoPort, String videoAccount, String videoPass) { + OkHttpClient client = new OkHttpClient().newBuilder() + .writeTimeout(1, TimeUnit.MINUTES) + .readTimeout(1, TimeUnit.MINUTES) + .connectTimeout(1, TimeUnit.MINUTES) + .build(); + MediaType mediaType = MediaType.parse("text/plain"); + RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM) + .addFormDataPart("videoIp", videoIp) + .addFormDataPart("videoPort", videoPort) + .addFormDataPart("videoAccount", videoAccount) + .addFormDataPart("videoPass", videoPass) + .build(); + Request request = new Request.Builder() + .url(attachAlarmChanHKByAccountUrl) + .method("POST", body) + .build(); + boolean result = false; + try { + okhttp3.Response response = client.newCall(request).execute(); + String resultBody = response.body().string().toString(); + try { + JSONObject bodyObject = JSONObject.parseObject(resultBody); + result = "200".equals(String.valueOf(bodyObject.get("code"))); + } catch (Exception e) { + // log.error(e.getMessage()); + result = resultBody.contains("true"); + } + } catch (IOException e) { + e.printStackTrace(); +// return Response.fail(e.getMessage()); + } + return result; + } + + @Override + public IPage selectByPage(VideoCamera videoCamera) { + return null; + } + + @Async +// @PostConstruct +// @Scheduled(cron = "0 0 * * * *") + public void setAlarmChanTask() { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.eq(VideoCamera::getIsSdkControl, 1); + List list = list(lambdaQueryWrapper); + if (CollectionUtils.isEmpty(list)) { + return; + } + List dhList = list.stream().filter(f -> GlobalConstant.SOURCE_TYPE_NAME_DH.equals(f.getSourceType())).collect(Collectors.toList()); + List hkList = list.stream().filter(f -> GlobalConstant.SOURCE_TYPE_NAME_HK.equals(f.getSourceType())).collect(Collectors.toList()); + dhList.stream().forEach(f -> { + try { + String videoIp = f.getVideosIp(); + String videoPort = f.getVideosPort(); + String videoPass = f.getVideosPass(); + String videoAccount = f.getVideosAccount(); + attachAlarmChanDHByAccount(videoIp, videoPort, videoAccount, videoPass, "0"); + Thread.sleep(500); + } catch (Exception e) { + // log.error(e.getMessage()); + } + }); + hkList.stream().forEach(f -> { + try { + String videoIp = f.getVideosIp(); + String videoPort = f.getVideosPort(); + String videoPass = f.getVideosPass(); + String videoAccount = f.getVideosAccount(); + attachAlarmChanHKByAccount(videoIp, videoPort, videoAccount, videoPass); + Thread.sleep(500); + } catch (Exception e) { + // log.error(e.getMessage()); + } + }); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoIdentificationServiceImpl.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoIdentificationServiceImpl.java new file mode 100644 index 0000000..84857bb --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/service/impl/VideoIdentificationServiceImpl.java @@ -0,0 +1,148 @@ +package com.ltgk.smartFishingPort.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ltgk.smartFishingPort.common.utils.MybatisUtil; +import com.ltgk.smartFishingPort.domain.dto.VideoIdentificationDto; +import com.ltgk.smartFishingPort.domain.entity.VideoCamera; +import com.ltgk.smartFishingPort.domain.entity.VideoIdentification; +import com.ltgk.smartFishingPort.mapper.VideoIdentificationMapper; +import com.ltgk.smartFishingPort.service.IVideoCameraService; +import com.ltgk.smartFishingPort.service.IVideoIdentificationService; +import com.ltgk.smartFishingPort.utils.CameraDegreesUtil; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + *

+ * 监控识别记录表 服务实现类 + *

+ * + * @author zhou + * @since 2024-12-10 + */ +@Service +public class VideoIdentificationServiceImpl extends ServiceImpl implements IVideoIdentificationService { + + @Value("${url.picFile}") + private String picUrl; + @Autowired + IVideoCameraService videoCameraService; + + /** + * 分页查询渔船识别 + * + * @param videoIdentificationDto + * @return + */ + @Override + public IPage findByPage(VideoIdentificationDto videoIdentificationDto) { + // TODO:::: + Integer pageNo = videoIdentificationDto.getPageNo(); + Integer pageSize = videoIdentificationDto.getPageSize(); + if (Objects.isNull(pageNo)) { + pageNo = 1; + } + if (Objects.isNull(pageSize)) { + pageSize = 15; + } + IPage pageParam = new Page<>(pageNo, pageSize); + VideoIdentification videoIdentification = new VideoIdentification(); + BeanUtils.copyProperties(videoIdentificationDto, videoIdentification); + QueryWrapper queryWrapper = MybatisUtil.notNullField(videoIdentification); + if (!StringUtils.isEmpty(videoIdentificationDto.getBeginTime())) { + queryWrapper.ge("take_time", videoIdentificationDto.getBeginTime()); + } + if (!StringUtils.isEmpty(videoIdentificationDto.getEndTime())) { + queryWrapper.le("take_time", videoIdentificationDto.getEndTime()); + } + queryWrapper.orderByDesc("take_time"); + IPage pageResult = baseMapper.selectPage(pageParam, queryWrapper); + List videoIdentifications = pageResult.getRecords(); + videoIdentifications = videoIdentifications.stream().map(m -> { + String sourcePicPath = m.getSourcePicPath(); + String trackerPicPath = m.getTrackerPicPath(); + String boatCodePicPath = m.getBoatCodePath(); + if (!StringUtils.isEmpty(sourcePicPath) && !sourcePicPath.startsWith("output/") && "卡口".equals(m.getTakeType())) { + sourcePicPath = Arrays.asList(sourcePicPath.split(",")).stream() + .map(pic -> picUrl + "/pic/" + pic) + .collect(Collectors.joining(",")); + } + if (!StringUtils.isEmpty(sourcePicPath) && sourcePicPath.startsWith("output/")) { + sourcePicPath = Arrays.asList(sourcePicPath.split(",")).stream() + .map(pic -> pic.replaceAll("output/", picUrl + "/pic/")) + .collect(Collectors.joining(",")); + } + if (!StringUtils.isEmpty(trackerPicPath) && !trackerPicPath.startsWith("output/") && "卡口".equals(m.getTakeType())) { + trackerPicPath = Arrays.asList(trackerPicPath.split(",")).stream() + .map(pic -> picUrl + "/pic/" + pic) + .collect(Collectors.joining(",")); + } + if (!StringUtils.isEmpty(trackerPicPath) && trackerPicPath.startsWith("output/")) { + trackerPicPath = Arrays.asList(trackerPicPath.split(",")).stream() + .map(pic -> pic.replaceAll("output/", picUrl + "/pic/")) + .collect(Collectors.joining(",")); + } + if (!StringUtils.isEmpty(boatCodePicPath) && !boatCodePicPath.startsWith("output/") && "卡口".equals(m.getTakeType())) { + boatCodePicPath = Arrays.asList(boatCodePicPath.split(",")).stream() + .map(pic -> picUrl + "/pic/" + pic) + .collect(Collectors.joining(",")); + } + if (!StringUtils.isEmpty(boatCodePicPath) && boatCodePicPath.startsWith("output/")) { + boatCodePicPath = Arrays.asList(boatCodePicPath.split(",")).stream() + .map(pic -> pic.replaceAll("output/", picUrl + "/pic/")) + .collect(Collectors.joining(",")); + } + m.setSourcePicPath(sourcePicPath); + m.setTrackerPicPath(trackerPicPath); + m.setBoatCodePath(boatCodePicPath); + if (StringUtils.isEmpty(m.getHeight()) && !StringUtils.isEmpty(m.getHeightRange())) { + m.setHeight(new BigDecimal(m.getHeightRange().split("-")[0])); + } + String videoName = m.getVideoName(); + VideoCamera videoCamera = null; + if (!StringUtils.isEmpty(videoName)) { + LambdaQueryWrapper videoCameraQueryWrapper = new LambdaQueryWrapper<>(); + videoCameraQueryWrapper.eq(VideoCamera::getVideoName, videoName); + videoCameraQueryWrapper.last("limit 1"); + videoCamera = videoCameraService.getOne(videoCameraQueryWrapper); + if (!Objects.isNull(videoCamera)) { + m.setVideoCode(videoCamera.getVideoCode()); + } + } + if (!StringUtils.isEmpty(m.getVideoName()) + && !Objects.isNull(m.getLatitude()) && !Objects.isNull(m.getLongitude())) { + if (Objects.isNull(videoCamera)) { + m.setDistance(BigDecimal.ZERO); + } else if (Objects.isNull(videoCamera.getLatitude()) || Objects.isNull(videoCamera.getLongitude())) { + m.setDistance(BigDecimal.ZERO); + } else { + BigDecimal distance = CameraDegreesUtil.getDistance1(videoCamera.getLongitude().doubleValue() + , videoCamera.getLatitude().doubleValue(), m.getLongitude().doubleValue(), m.getLatitude().doubleValue()); + m.setDistance(distance); + } + } + if (!Objects.isNull(videoCamera) && !StringUtils.isEmpty(videoCamera.getVideoName())) { + m.setVideoName(videoCamera.getVideoBelong() + videoCamera.getVideoName()); + } + if (!Objects.isNull(m.getSpeed())) { + m.setSpeed(m.getSpeed().divide(new BigDecimal(0.5144444), 2, BigDecimal.ROUND_HALF_UP)); + } + return m; + }).collect(Collectors.toList()); + pageResult.setRecords(videoIdentifications); + return pageResult; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ArtemisPostUtil.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ArtemisPostUtil.java new file mode 100644 index 0000000..e2d4c1d --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ArtemisPostUtil.java @@ -0,0 +1,1173 @@ +package com.ltgk.smartFishingPort.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; +import com.ltgk.smartFishingPort.common.constant.Constants; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 海康开放api调用 + * + * @author limap + */ +@Component +public class ArtemisPostUtil { + + private static final Logger logger = LoggerFactory.getLogger(ArtemisPostUtil.class); + + // private static final String SERVER_IP = "123.234.88.13"; + private static final String SERVER_IP = "180.142.131.39"; + + private static final String SERVER_PORT = "10011"; + private static final String SERVER_PORT2 = "10012"; + + private static final String REAL_NAME = "www.gd-jintu.com/lhsygjjq"; + + private static final String CONTEXT_PATH = "/yhyg"; + private static final String CONTEXT_WEB_PATH = "/yhygweb"; + + /** + * 请根据自己的appKey和appSecret更换static静态块中的三个参数. [1 host] + * 如果你选择的是和现场环境对接,host要修改为现场环境的ip,https端口默认为443,http端口默认为80.例如10.33.25.22:443 或者10.33.25.22:80 + * appKey和appSecret请按照或得到的appKey和appSecret更改. + * TODO 调用前先要清楚接口传入的是什么,是传入json就用doPostStringArtemis方法,下载图片doPostStringImgArtemis方法 + */ + /** + * 根据API文档可以看出来,这是一个POST请求的Rest接口,而且传入的参数值为一个json + * ArtemisHttpUtil工具类提供了doPostStringArtemis这个函数,一共六个参数在文档里写明其中的意思,因为接口是https, + * 所以第一个参数path是一个hashmap类型,请put一个key-value,query为传入的参数,body为传入的json数据 + * 传入的contentType为application/json,accept不指定为null + * header没有额外参数可不传,指定为null + * + */ + static { + // 代理API网关nginx服务器ip端口 +// ArtemisConfig.host = "192.168.1.3"; + ArtemisConfig.host = "5b7ab0e8.r30.cpolar.top"; + // 秘钥appkey + ArtemisConfig.appKey = "25069656"; + // 秘钥appSecret + ArtemisConfig.appSecret = "4FzVroHJDllSkUwHEx2u"; + + // 玉环--代理API网关nginx服务器ip端口 +// ArtemisConfig.host = "39.175.75.233:10443"; +// // 秘钥appkey +// ArtemisConfig.appKey = "28273161"; +// // 秘钥appSecret +// ArtemisConfig.appSecret = "pvQSichVMqtLGh4Ltedo"; + } + + /** + * 能力开放平台的网站路径 + * 路径不用修改,就是/artemis + */ + private static final String ARTEMIS_PATH = "/artemis"; + + /** + * post请求application/json类型参数 + */ + private static final String CONTENT_TYPE = "application/json"; + + /** + * TODO 根据现场环境部署确认是http还是https + */ + + private static final String HTTPS_TYPE = "https://"; + + private static final String HTTP_TYPE = "http://"; + /** + * 分页获取监控点资源API + */ + private static final String GET_MONITOR_POINT_URL = "/api/resource/v1/cameras"; + + /** + * 获取监控点预览取流API + */ + private static final String GET_PREVIEW_URL = "/api/video/v2/cameras/previewURLs"; + + /** + * 订阅事件API + */ + private static final String SIGN_INTERFACE = "/api/eventService/v1/eventSubscriptionByEventTypes"; + + /** + * 查询订阅事件API + */ + private static final String GET_SIGN_INFO = "/api/eventService/v1/eventSubscriptionView"; + + /** + * 图片下载API + */ + private static final String GET_IMG_URL = "/api/video/v1/events/picture"; + /** + * 云台操作API + */ + private static final String CONTROL_URL = "/api/video/v1/ptzs/controlling"; + /** + * 3D放大API + */ + private static final String SEL_ZOOM_URL = "/api/video/v1/ptzs/selZoom"; + + /** + * 设置预置点信息API + */ + private static final String PRESETS_ADDITION_URL = "/api/video/v1/presets/addition"; + /** + * 查询预置点信息API + */ + private static final String PRESETS_SEARCHES_URL = "/api/video/v1/presets/searches"; + /** + * 删除预置点信息API + */ + private static final String PRESETS_DELETION_URL = "/api/video/v1/presets/deletion"; + + /** + * 手动抓图API + */ + private static final String MANUAL_CAPTURE_URL = "/api/video/v1/manualCapture"; + + /** + * 录像锁定与解锁API + */ + private static final String LOCK_URL = "/api/video/v1/record/lock"; + + /** + * 开始手动录像API + */ + private static final String START_RECORD_URL = "/api/video/v1/manualRecord/start"; + + /** + * 停止手动录像API + */ + private static final String STOP_RECORD_URL = "/api/video/v1/manualRecord/stop"; + + /** + * 获取监控点回放取流API + */ + private static final String PLAY_BACK_URL = "/api/video/v2/cameras/playbackURLs"; + + /** + * 根据广播分区获取广播点 + */ + private static final String FETCH_AUDIO_AREA_PAGE_URL = "/api/ibas/audioArea/v1/fetchAudioAreaPage"; + + /** + * 根据广播分区获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_BY_AREA_URL = "/api/ibas/audioArea/v1/fetchAudioChannelByArea"; + + /** + * 分页查询媒体文件 + */ + private static final String FETCH_MEDIA_PAGE_URL = "/api/ibas/media/v1/fetchMediaPage"; + + /** + * 分页获取广播媒体库目录接口 + */ + private static final String FETCH_MEDIA_LIBRARY_URL = "/api/ibas/media/v1/fetchMediaLibrary"; + + /** + * 根据指定标识获取广播媒体库文件 + */ + private static final String FETCH_MEDIA_BY_INDEX_CODE_URL = "/api/ibas/media/v1/fetchMediaByIndexCode"; + + /** + * 分页获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_URL = "/api/ibas/resource/v1/fetchAudioChannel"; + + /** + * 分页获取广播设备列表 + */ + private static final String FETCH_AUDIO_DEVICE_URL = "/api/ibas/resource/v1/fetchAudioDevice"; + + /** + * 根据设备信息获取广播点 + */ + private static final String FETCH_AUDIO_CHANNEL_BY_DEVICE_URL = "/api/ibas/resource/v1/fetchAudioChannelByDevice"; + + /** + * 分页查询定时任务 + */ + private static final String FETCH_AUDIO_TASK_PAGE_URL = "/api/ibas/audioTask/v1/fetchAudioTaskPage"; + + /** + * 分页获取广播预案接口 + */ + private static final String FETCH_AUDIO_PLAN_URL = "/api/ibas/audioPlan/v1/fetchAudioPlanPage"; + + /** + * 广播设备自定义播放或停止 + */ + private static final String CUSTOM_BROAD_CAST_URL = "/api/ibas/v1/customBroadcast"; + + /** + * 获取H5实时广播URL + */ + private static final String BROAD_CAST_URL = "/api/ibas/media/v1/broadcastURLs"; + + /** + * 设置广播点音量 + */ + private static final String SET_AUDIO_VOLUME_PPARAM_URL = "/api/ibas/resource/v1/setAudioVolumeParam"; + + static final String onLineURLsApi = ARTEMIS_PATH + "/api/nms/v1/online/camera/get"; + + static final String cameraURLsApi = ARTEMIS_PATH + "/api/resource/v1/cameras/indexCode"; + + + + /** + * 根据广播分区获取广播点 + * @param param + * @return + */ + public static Object fetchAudioAreaPage(Object param) { + + final String fetchAudioAreaPage = ARTEMIS_PATH + FETCH_AUDIO_AREA_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioAreaPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据广播分区获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannelByArea(Object param) { + + final String fetchAudioChannelByArea = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_BY_AREA_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannelByArea); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页查询媒体文件 + * @param param + * @return + */ + public static Object fetchMediaPage(Object param) { + + final String fetchMediaPage = ARTEMIS_PATH + FETCH_MEDIA_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播媒体库目录接口 + * @param param + * @return + */ + public static Object fetchMediaLibrary(Object param) { + + final String fetchMediaLibrary = ARTEMIS_PATH + FETCH_MEDIA_LIBRARY_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaLibrary); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据指定标识获取广播媒体库文件 + * @param param + * @return + */ + public static Object fetchMediaByIndexCode(Object param) { + + final String fetchMediaByIndexCode = ARTEMIS_PATH + FETCH_MEDIA_BY_INDEX_CODE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchMediaByIndexCode); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannel(Object param) { + + final String fetchAudioChannel = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannel); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播设备列表 + * @param param + * @return + */ + public static Object fetchAudioDevice(Object param) { + + final String fetchAudioDevice = ARTEMIS_PATH + FETCH_AUDIO_DEVICE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioDevice); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 根据设备信息获取广播点 + * @param param + * @return + */ + public static Object fetchAudioChannelByDevice(Object param) { + + final String fetchAudioChannelByDevice = ARTEMIS_PATH + FETCH_AUDIO_CHANNEL_BY_DEVICE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioChannelByDevice); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页查询定时任务 + * @param param + * @return + */ + public static Object fetchAudioTaskPage(Object param) { + + final String fetchAudioTaskPage = ARTEMIS_PATH + FETCH_AUDIO_TASK_PAGE_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioTaskPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取广播预案接口 + * @param param + * @return + */ + public static Object fetchAudioPlanPage(Object param) { + + final String fetchAudioPlanPage = ARTEMIS_PATH + FETCH_AUDIO_PLAN_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, fetchAudioPlanPage); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 广播设备自定义播放或停止 + * @param param + * @return + */ + public static Object customBroadcast(Object param) { + + final String customBroadcast = ARTEMIS_PATH + CUSTOM_BROAD_CAST_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, customBroadcast); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 获取H5实时广播URL + * @param param + * @return + */ + public static Object broadcastURLs(Object param) { + + final String broadcastURLs = ARTEMIS_PATH + BROAD_CAST_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, broadcastURLs); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 设置广播点音量 + * @param param + * @return + */ + public static Object setAudioVolumeParam(Object param) { + + final String setAudioVolumeParam = ARTEMIS_PATH + SET_AUDIO_VOLUME_PPARAM_URL; + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, setAudioVolumeParam); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, JSONObject.toJSONString(param), null, null, CONTENT_TYPE, null); + } + + /** + * 分页获取监控点资源 + * + * @return 调用结果 + */ + public static String callPostStringApi() { + + final String getCamsApi = ARTEMIS_PATH + GET_MONITOR_POINT_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + jsonBody.put("pageNo", 1); + jsonBody.put("pageSize", 200); + jsonBody.put("treeCode", null); + String body = jsonBody.toJSONString(); + // post请求application/json类型参数 + return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + } + + /** + * 获取监控点预览取流URLv2 + * + * @param code 监控点唯一标识 + * @return 调用结果 + */ + public static String getPreviewUrl(String code) { + final String getCamsApi = ARTEMIS_PATH + GET_PREVIEW_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + // 码流类型,0:主码流 1:子码流 2:第三码流 参数不填,默认为主码流 + Integer streamType = 0; + // 取流协议(应用层协议), + // “hik”:HIK私有协议,使用视频SDK进行播放时,传入此类型; + // “rtsp”:RTSP协议; + // “rtmp”:RTMP协议(RTMP协议只支持海康SDK协议、EHOME协议、ONVIF协议接入的设备;只支持H264视频编码和AAC音频编码); + // “hls”:HLS协议(HLS协议只支持海康SDK协议、EHOME协议、ONVIF协议接入的设备;只支持H264视频编码和AAC音频编码); + // “ws”:Websocket协议(一般用于H5视频播放器取流播放)。 + String protocol = "rtsp"; + // 传输协议(传输层协议),0:UDP 1:TCP 默认是TCP 注:GB28181 2011及以前版本只支持UDP传输 + Integer transmode = 1; + // 转码标志,不携带此字段或传0表示不转码,传1或2表示转码。0 不转码 1组件转码 2设备转码,仅支持分辨率、比特率、帧率转码参数进行转码 + String expand = "transcode=0"; + // 输出码流转封装格式,“ps”:PS封装格式、“rtp”:RTP封装协议。当protocol=rtsp时生效,且不传值时默认为RTP封装协议。 + String streamform = "rtp"; + + jsonBody.put("cameraIndexCode", code); + jsonBody.put("streamType", streamType); + jsonBody.put("protocol", protocol); + jsonBody.put("transmode", transmode); + jsonBody.put("expand", expand); + jsonBody.put("streamform", streamform); + + String body = jsonBody.toJSONString(); + + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + JSONObject resultObject = JSONObject.parseObject(result); + JSONObject data = resultObject.getJSONObject("data"); + return data.getString("url"); + } + + /** + * 订阅事件(事件注册) + * + * @return 调用结果 + */ +// public static String signAreaInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Integer.parseInt(Constants.AREA_WARN_CODE)); +// eventTypes.add(Integer.parseInt(Constants.IDENTIFY_CODE)); +// jsonBody.put("eventTypes", eventTypes); +// JSONArray eventLvl = new JSONArray(); +// eventLvl.add(2); +// jsonBody.put("eventLvl", eventLvl); +// jsonBody.put("subType", 0); +// // TODO 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT2 + CONTEXT_WEB_PATH + "/rest/videoWarning/listenAreaWarn"); +//// jsonBody.put("eventDest", HTTPS_TYPE + REAL_NAME + CONTEXT_PATH + "/rest/videoWarning/listenAreaWarn"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signFireSmokeInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.FIRE_SMOKE_WARN_CODE); +// eventTypes.add(Constants.FIRE_POINT_WARN_CODE); +// eventTypes.add(Constants.SMOKE_WARN_CODE); +// jsonBody.put("eventTypes", eventTypes); +// // TODO 回调接口 +// // jsonBody.put("eventDest", "http://60.212.191.109:4001/wdyc/rest/videoMonitorAlarm/listen"); +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/smokeFireCallBack"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅车辆报警事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signVehicleInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.VEHICLE_BLACKLIST_WARN_CODE); +// eventTypes.add(Constants.VEHICLE_SPEED_WARN_CODE); +// eventTypes.add(Constants.VEHICLE_RETROGRADE_WARN_CODE); +// eventTypes.add(Constants.ILLEGALLY_PARK_WARN_CODE); +// jsonBody.put("eventTypes", eventTypes); +// // 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/vehicleCallBack"); +// +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + +// /** +// * 订阅重点人员识别报警事件(事件注册) +// * +// * @return 调用结果 +// */ +// public static String signMainPersonInterface() { +// final String getCamsApi = ARTEMIS_PATH + SIGN_INTERFACE; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, getCamsApi); +// +// JSONObject jsonBody = new JSONObject(); +// +// JSONArray eventTypes = new JSONArray(); +// eventTypes.add(Constants.MAIN_PERSON_WARN_CODE); +// +// jsonBody.put("eventTypes", eventTypes); +// // 回调接口 +// jsonBody.put("eventDest", HTTP_TYPE + SERVER_IP + ":" + SERVER_PORT + CONTEXT_PATH + "/rest/secureCenter/mainFaceCallBack"); +// String body = jsonBody.toJSONString(); +// +// return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// } + + /** + * 获取报警截图 + * + * @param svrIndexCode 设备唯一标识 + * @param captureId url + * @return 调用结果 + */ + public static String imgUrl(String svrIndexCode, String captureId) throws Exception { + final String getCamsApi = ARTEMIS_PATH + GET_IMG_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + JSONObject jsonBody = new JSONObject(); + + jsonBody.put("svrIndexCode", svrIndexCode); + jsonBody.put("picUri", captureId); + + jsonBody.put("netProtocol", "http"); + + String body = jsonBody.toJSONString(); + + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + JSONObject resultObject = JSONObject.parseObject(result); + JSONObject data = resultObject.getJSONObject("data"); + // TODO 待确认如何替换 + result = data.getString("picUrl").replaceAll("https:", "http:").replaceAll(":6113", ":6040"); + return result; + } + + /** + * 查询订阅信息 + * + * @return 调用结果 + */ + public static String signInfo() { + final String getCamsApi = ARTEMIS_PATH + GET_SIGN_INFO; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getCamsApi); + + return ArtemisHttpUtil.doPostStringArtemis(path, null, null, null, CONTENT_TYPE, null); + } + + + /** + * 查询预置点信息 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ + public static JSONObject presetsSearch(String cameraIndexCode) { + final String presetsSearchApi = ARTEMIS_PATH + PRESETS_SEARCHES_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, presetsSearchApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("查询监控点上的预置点请求参数:{} ," + + "\n查询监控点上的预置点的响应信息:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + + /** + * 云台跳转到指定预置点 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param speed 台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 调用结果 + */ + public static JSONObject goToPreset(String cameraIndexCode, Integer speed, String presetIndex) { + final String goToPresetApi = ARTEMIS_PATH + CONTROL_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, goToPresetApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("action", 0); + jsonBody.put("command", "GOTO_PRESET"); + if (speed == null) { + speed = 50; + } + jsonBody.put("speed", speed); + jsonBody.put("presetIndex", presetIndex); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("跳转到监控点请求参数:{} ," + + "\n跳转到监控点响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + + /** + * 手动抓图 + * 该接口用于手动触发设备抓图,返回图片的地址,抓图前请确保平台上已配置图片存储信息。抓图时间为触发手动抓图命令的时间 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject catchImage(String cameraIndexCode) { +// final String catchImageApi = ARTEMIS_PATH + MANUAL_CAPTURE_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, catchImageApi); +// JSONObject jsonBody = new JSONObject(); +// +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("手动抓图请求参数:{} ," + +// "\n手动抓图响应结果:{}", body, response); +// response = response.replaceAll("https:", "http:").replaceAll(":6113", ":6040"); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 手动录像 + * 通过向中心存储接入服务下发锁定/解锁指定编码器,指定时间段的录像。 + * 进行录像锁定/解锁操作的用户需要配置相应监控点的录像回放权限,本接口会根据合作方的userId进行权限过滤。 + * 仅支持中心存储,暂不支持设备存储。 + * 综合安防管理平台iSecure Center V1.4及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param start 录像时长,单位秒 + * @param end 结束 + * @return 调用结果 + */ +// public static JSONObject lockVideo(String cameraIndexCode, Date start, Date end) { +// final String lockVideoApi = ARTEMIS_PATH + LOCK_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, lockVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) +// jsonBody.put("startTime", DateFormatUtils.format(start, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// jsonBody.put("endTime", DateFormatUtils.format(end, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); +// //锁定时长,单位:秒,为0时表示解锁,取值范围:0-1576800000 +// jsonBody.put("lockTime", (end.getTime() - start.getTime()) / 1000); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("锁定录像请求参数:{} ," + +// "\n锁定录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 开始手动录像 + * 1.该接口用于向存储接入服务下发开始手动录像请求,将前端实时流存储到存储设备上,支持中心存储和设备存储两种存储模式。萤石设备不支持手动录像功能。 + * 2.由于开始手动录像命令需要先下发到sac再到存储,实际录像开始时间与调用接口时间会稍有延迟。 + * 综合安防管理平台iSecure Center V1.3及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ +// public static JSONObject startCatchVideo(String cameraIndexCode) { +// final String startCatchVideoApi = ARTEMIS_PATH + START_RECORD_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, startCatchVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// //报警触发或移动侦测 +// jsonBody.put("recordType", 3); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("开始手动录像请求参数:{} ," + +// "\n开始手动录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// result.put("taskID", result.getJSONObject("data").getString("taskID")); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 停止手动录像 + * 1.该接口用于根据手动录像任务ID,向存储接入服务下发停止手动录像请求, 支持中心存储和设备存储两种存储模式。萤石设备不支持手动录像功能。 + * 2.由于停止手动录像命令需要先下发到sac再到存储,实际录像结束时间与调用接口时间会稍有延迟。 + * 综合安防管理平台iSecure Center V1.5及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param taskId 录像任务id + * @return 调用结果 + */ +// public static JSONObject stopCatchVideo(String cameraIndexCode, String taskId) { +// final String stopCatchVideoApi = ARTEMIS_PATH + STOP_RECORD_URL; +// // 根据现场环境部署确认是http还是https +// Map path = Maps.newHashMap(); +// path.put(HTTPS_TYPE, stopCatchVideoApi); +// +// JSONObject jsonBody = new JSONObject(); +// jsonBody.put("cameraIndexCode", cameraIndexCode); +// //下发的存储类型。0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 +// jsonBody.put("type", 0); +// jsonBody.put("taskID", taskId); +// String body = jsonBody.toJSONString(); +// String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); +// logger.debug("停止手动录像请求参数:{} ," + +// "\n停止手动录像响应结果:{}", body, response); +// JSONObject result = JSON.parseObject(response); +// if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { +// result.put("success", true); +// return result; +// } +// result.put("success", false); +// return result; +// } + + + /** + * 录像回放 + * + * @param cameraIndexCode 监控点唯一标识 + * @param start 查询开始时间 + * @param end 查询结束时间 + * @return 调用结果 + */ + public static JSONObject getHistoryVideoURL(String cameraIndexCode, Date start, Date end) { + final String getHistoryVideoURLApi = ARTEMIS_PATH + PLAY_BACK_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, getHistoryVideoURLApi); + + String contentType = "application/json"; + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) + jsonBody.put("beginTime", DateFormatUtils.format(start, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); + //开始时间(IOS8601格式:yyyy-MM-dd’T’HH:mm:ss.SSSzzz +当前时区,例如北京时间:2018-07-26T15:00:00.000+08:00) + jsonBody.put("endTime", DateFormatUtils.format(end, "yyyy-MM-dd'T'HH:mm:ss.SSSZZ")); + //0-中心存储,1-设备存储。如果不传入,默认为0-中心存储 + jsonBody.put("recordLocation", 0); + //hik,rtsp,rtmp-beginTime=20190902T100303&endTime=20190902T100400,hls + jsonBody.put("protocol", "rtsp"); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + logger.debug("获取手动录像Url请求参数:{} ," + + "\n获取手动录像Url响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 云台操作 + * 根据监控点编号进行云台操作接口 + * 综合安防管理平台iSecure Center V1.0及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param action 0-开始 ,1-停止 注:GOTO_PRESET命令下填任意值均可转到预置点,建议填0即可 + * @param command 不区分大小写,说明: + * LEFT 左转 + * RIGHT右转 + * UP 上转 + * DOWN 下转 + * ZOOM_IN 焦距变大 + * ZOOM_OUT 焦距变小 + * LEFT_UP 左上 + * LEFT_DOWN 左下 + * RIGHT_UP 右上 + * RIGHT_DOWN 右下 + * FOCUS_NEAR 焦点前移 + * FOCUS_FAR 焦点后移 + * IRIS_ENLARGE 光圈扩大 + * IRIS_REDUCE 光圈缩小 + * WIPER_SWITCH 接通雨刷开关 + * START_RECORD_TRACK 开始记录轨迹 + * STOP_RECORD_TRACK 停止记录轨迹 + * START_TRACK 开始轨迹 + * STOP_TRACK 停止轨迹; + * 以下命令presetIndex不可为空: + * GOTO_PRESET到预置点 + * @param speed 云台速度,取值范围为1-100,默认50 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return 查询结果 + */ + public static JSONObject controlling(String cameraIndexCode, Integer action, String command, Integer speed, Integer presetIndex) { + final String catchImageApi = ARTEMIS_PATH + CONTROL_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("action", action); + jsonBody.put("command", command); + if (speed != null) { + jsonBody.put("speed", speed); + } + if (presetIndex != null) { + jsonBody.put("presetIndex", presetIndex); + } + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("云台操作请求参数:{} ," + + "\n云台操作响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 3D放大 + * 该接口用于控制监控点进行3D电子放大。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param startX 开始放大的X坐标,范围:0-255。由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕X坐标/屏幕宽 * 255,即该坐标位X坐标占总屏幕宽的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param startY 开始放大的Y坐标,范围:0-255,由于设备比例限制,以及实际场景屏幕比例大小不同,请按照如下坐标位计算方式计算入参:屏幕Y坐标/屏幕高 * 255,即该坐标位Y坐标占总屏幕高的比例*255。监控点会对startX、startY、endX 、endY四点围成的区域进行放大。 + * @param endX 结束放大的X坐标,范围以及计算方式同startX + * @param endY 结束放大的Y坐标,范围以及计算方式同startY + * @return 查询结果 + */ + public static JSONObject selZoom(String cameraIndexCode, Integer startX, Integer startY, Integer endX, Integer endY) { + final String catchImageApi = ARTEMIS_PATH + SEL_ZOOM_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("startX", startX); + jsonBody.put("startY", startY); + jsonBody.put("endX", endX); + jsonBody.put("endY", endY); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("3D放大请求参数:{} ," + + "\n3D放大响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 设置预置点信息 + * 该接口用于设置监控点的预置点信息,若参数传已经存在的预置点编号,则可修改预置点信息 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param presetName 预置点名称 + * @param presetIndex 预置点编号(1 - 300) + * @return 调用结果 + * @throws Exception 抛出异常 + */ + public static JSONObject presetsAddition(String cameraIndexCode, String presetName, Integer presetIndex) { + final String catchImageApi = ARTEMIS_PATH + PRESETS_ADDITION_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("presetName", presetName); + jsonBody.put("presetIndex", presetIndex); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("设置预置点信息请求参数:{} ," + + "\n设置预置点信息响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 查询预置点信息 + * 该接口用于查询监控点的预置点信息。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @return 调用结果 + */ + public static JSONObject presetsSearches(String cameraIndexCode) { + final String catchImageApi = ARTEMIS_PATH + PRESETS_SEARCHES_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("查询预置点信息请求参数:{} ," + + "\n查询预置点信息响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + /** + * 删除预置点信息 + * 该接口用于删除监控点的预置点信息。 + * 综合安防管理平台iSecure Center V1.2及以上版本 + * + * @param cameraIndexCode 监控点唯一标识 + * @param presetIndex 预置点编号 + * @return 调用结果 + */ + public static JSONObject presetsDeletion(String cameraIndexCode, Integer presetIndex) { + final String catchImageApi = ARTEMIS_PATH + PRESETS_DELETION_URL; + // 根据现场环境部署确认是http还是https + Map path = Maps.newHashMap(); + path.put(HTTPS_TYPE, catchImageApi); + + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("presetIndex", presetIndex); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, CONTENT_TYPE, null); + logger.debug("删除预置点信息请求参数:{} ," + + "\n删除预置点信息响应结果:{}", body, response); + JSONObject result = JSON.parseObject(response); + if (Constants.SUCCESS_CODE.equals(result.getString(Constants.CODE))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + +// /** +// * 获取监控点在线状态接口 +// * @param camerasList +// * @param size +// * @return +// */ +// public static List getCameraStatus(String[] camerasList,int size){ +// Map onlinePath = new HashMap(2) { +// { +// put("https://", onLineURLsApi);//根据现场环境部署确认是http还是https +// } +// }; +// JSONObject onLineParam = new JSONObject(); +// onLineParam.put("pageNo",1); +// onLineParam.put("pageSize",size); +// onLineParam.put("indexCodes",camerasList); +// +// String result2 = ArtemisHttpUtil.doPostStringArtemis(onlinePath, onLineParam.toString(), null, null, CONTENT_TYPE , null); +// JSONObject result2Json = JSON.parseObject(result2); +// +// JSONObject data2Json = result2Json.getJSONObject("data"); +// JSONArray list2 = data2Json.getJSONArray("list"); +// List onlineBeans = list2.toJavaList(OnlineBean.class); +// +// return onlineBeans; +// } + + public static String getCameraInfo(String cameraIndexCode){ + Map onlinePath = new HashMap(2) { + { + put("https://", cameraURLsApi);//根据现场环境部署确认是http还是https + } + }; + JSONObject onLineParam = new JSONObject(); + onLineParam.put("cameraIndexCode",cameraIndexCode); + + String result2 = ArtemisHttpUtil.doPostStringArtemis(onlinePath, onLineParam.toString(), null, null, CONTENT_TYPE , null); + JSONObject result2Json = JSON.parseObject(result2); + + JSONObject data2Json = result2Json.getJSONObject("data"); + + return JSON.toJSONString(data2Json); + } + + /** + * 云台跳转 + * 综合安防管理平台iSecure Center V1.0及以上版本 + *

https://open.hikvision.com/docs/8530061f19534a9993e2afeb70e7c96a#e30b9484

+ * @param cameraIndexCode 监控点唯一标识 + * @param speed 台速度,取值范围为1-100,默认50 + * @param cameraIndexCode 监控点编号 + * @param presetIndex 预置点编号,可通过查询预置点信息接口获取整数,通常在300以内 + * @return + * @throws Exception + */ + public static JSONObject videoController(String cameraIndexCode,String command,Integer speed,String presetIndex,Integer action) { + final String goToPresetApi = ARTEMIS_PATH +"/api/video/v1/ptzs/controlling"; + Map path = new HashMap(2) { + { + put("https://", goToPresetApi); + } + }; + + String contentType = "application/json"; + JSONObject jsonBody = new JSONObject(); + jsonBody.put("cameraIndexCode", cameraIndexCode); + jsonBody.put("action", action); + jsonBody.put("command", command); + if(speed==null) { + speed = 50; + } + jsonBody.put("speed", speed); + jsonBody.put("presetIndex", presetIndex); + String body = jsonBody.toJSONString(); + String response = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// + logger.debug("跳转到监控点请求参数:\t" + body + "\n跳转到监控点响应结果:\t" + response); + JSONObject result = JSON.parseObject(response); + if("0".equals(result.getString("code"))) { + result.put("success", true); + return result; + } + result.put("success", false); + return result; + } + + + public static void main(String[] args) { + // System.out.println(callPostStringApi()); + // System.out.println("===:"+getCameraInfo("5dadcc624c454be1a280c39fc18f043a")); + + // String StringeResult = signInfo(); +// String imageUrl = "http://192.168.100.22:6120/pic?=d08ie912iace=o90-bp511az8e*fs2i6493428660e2=t1i9m*dp=*3pdi=*1sdi=*5b2i36bee5757d=a0--872e67*l194od1-651025d8"; +// String picUrl = "/" + imageUrl.split("/")[3]; +// System.out.println(picUrl); +// String StringeResult = imgUrl("64bba8f5-c381-48b3-9b23-749f28885909", +// "/pic?=d08ie912iace=o90-bp511az8e*fs2i6493428660e2=t1i9m*dp=*3pdi=*1sdi=*5b2i36bee5757d=a0--872e67*l194od1-651025d8"); +// System.out.println("StringeResult结果示例: "+StringeResult); + // callPostImgStringApi(); + // String jsonstr = "{\"code\":\"0\",\"msg\":\"success\",\"data\":{\"total\":26,\"pageNo\":1,\"pageSize\":100,\"list\":[{\"altitude\":null,\"cameraIndexCode\":\"1c14df35daa449bf8a34c28d0e1ffabd\",\"cameraName\":\"蓝湾test\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,remote_vss,event_vss,vss,record,ptz,net,maintenance,status\",\"capabilitySetName\":\"IO能力,视频设备远程获取能力,视频事件能力,视频能力,录像能力,云台能力,网络参数配置能力,设备维护能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-21T11:43:49.672+08:00\",\"encodeDevIndexCode\":\"835163c8ba454b7cb9cd2544bc1ee39a\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000026\",\"installLocation\":\"\",\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":null,\"recordLocationName\":null,\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-21T14:46:53.107+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"9f471a45013e4e06873f58b8539a0347\",\"cameraName\":\"test\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,remote_vss,event_vss,vss,record,ptz,net,maintenance,status\",\"capabilitySetName\":\"IO能力,视频设备远程获取能力,视频事件能力,视频能力,录像能力,云台能力,网络参数配置能力,设备维护能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-19T12:23:33.703+08:00\",\"encodeDevIndexCode\":\"a529d4b439b648dba9dcd438861abffc\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000025\",\"installLocation\":\"\",\"keyBoardCode\":null,\"latitude\":\"\",\"longitude\":\"\",\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":null,\"recordLocationName\":null,\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-21T14:47:24.797+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"da7c22239c97411282570849c9fc4c74\",\"cameraName\":\"岭前头村\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T15:48:06.610+08:00\",\"encodeDevIndexCode\":\"0d88a7eeada846698537318abddcd46f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000024\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.215+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"66a1232da34e4767a167c923c1dc59fb\",\"cameraName\":\"万达维湾东南\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:11:23.389+08:00\",\"encodeDevIndexCode\":\"6146a7c85f24440198752a1f26d1a996\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000023\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.456+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2fc59c6955e34a10a322935773381084\",\"cameraName\":\"张托村\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:48.409+08:00\",\"encodeDevIndexCode\":\"071813d4b72d4bcaa74709fdca8a42b6\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000022\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.593+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2befe46315a843d39141a127f906a909\",\"cameraName\":\"陈家贡大桥 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:08:50.645+08:00\",\"encodeDevIndexCode\":\"71d980f084214e688d98d0801ce0a05f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000021\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.975+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"ebf3f1e476d641e69f7528ef5152ef40\",\"cameraName\":\"陈家贡大桥02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:08:50.645+08:00\",\"encodeDevIndexCode\":\"71d980f084214e688d98d0801ce0a05f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000020\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.012+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"b2eb5b869d354db5979c47a589d803dd\",\"cameraName\":\"积米崖 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:06:01.488+08:00\",\"encodeDevIndexCode\":\"de57ebfabf204c18b0ae9fe443b60073\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000019\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.565+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"6d69d98d3fd746518e6d41db3c53d33a\",\"cameraName\":\"积米崖 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:06:01.490+08:00\",\"encodeDevIndexCode\":\"de57ebfabf204c18b0ae9fe443b60073\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000018\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.637+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2c2bb022b76941cd89a77017d746b004\",\"cameraName\":\"西杨家洼 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:07.693+08:00\",\"encodeDevIndexCode\":\"89277e1ff5464a608c1f22a349067898\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000017\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.693+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"5e8d65c89e5645ea89369c2993ec96e1\",\"cameraName\":\"西杨家洼 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:10:07.695+08:00\",\"encodeDevIndexCode\":\"89277e1ff5464a608c1f22a349067898\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000016\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.726+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"f20b9a15035c458eb41b8a9a9cb1da35\",\"cameraName\":\"跨海大桥\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:12:04.354+08:00\",\"encodeDevIndexCode\":\"d0628f35db8d4c0b9f75d0ba35524d21\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000015\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.344+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"52f8edd67f00492399be1fc289eef7da\",\"cameraName\":\"胡家山 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:02.222+08:00\",\"encodeDevIndexCode\":\"9b3eb53f22d9458a83c3885f0a23c459\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000014\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.361+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"2b068286a653476f9fb1dfeaef11e109\",\"cameraName\":\"胡家山 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:02.224+08:00\",\"encodeDevIndexCode\":\"9b3eb53f22d9458a83c3885f0a23c459\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000013\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.430+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"63950ef4abbf46dd8b8646111b6cf3ed\",\"cameraName\":\"上戏东 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:40.749+08:00\",\"encodeDevIndexCode\":\"cdeb9164940f4a3c81d45b5cc9c1e6d9\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000012\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.159+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"a65565df7c6c4556bd365d8adaa5dd83\",\"cameraName\":\"上戏东 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,event_rule,gis,event_heat,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,热成像事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:07:40.803+08:00\",\"encodeDevIndexCode\":\"cdeb9164940f4a3c81d45b5cc9c1e6d9\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000011\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.224+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"328c9d58b31a405a8ce189cc61fe4fc6\",\"cameraName\":\"爱琴海 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:09:18.941+08:00\",\"encodeDevIndexCode\":\"d0e4c74338454a9b99c324643c119d05\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000010\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.838+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"dca7c29cfc9e43f1b5f40c6b92405b27\",\"cameraName\":\"爱琴海 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_face,event_gis,event_rule,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"IO能力,人脸事件能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-12T11:09:18.943+08:00\",\"encodeDevIndexCode\":\"d0e4c74338454a9b99c324643c119d05\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000009\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:01.868+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"11902fe0bc43431eb07530903460e7db\",\"cameraName\":\"琴岛之眼\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:18:57.498+08:00\",\"encodeDevIndexCode\":\"f9018b010d5140b4ac1ae1fa76f06d93\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000008\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.853+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"4637b2e263a2409a9682a35e9df77c81\",\"cameraName\":\"王台铲尖村东北\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:20:16.450+08:00\",\"encodeDevIndexCode\":\"51a66e215c4f49cea6e65a9b72f38618\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000007\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.753+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"a411dd3c829047b6b49d70d65428e439\",\"cameraName\":\"欢乐海湾 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_gis,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_face,event_rule\",\"capabilitySetName\":\"IO能力,可视域事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,人脸事件能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:17:57.610+08:00\",\"encodeDevIndexCode\":\"13881aa4a2a24e328033f19dd7323f1c\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000006\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:02.965+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"8c1954b15bfd4b00a4de219ad7afb1dc\",\"cameraName\":\"欢乐海湾 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"io,event_gis,gis,event_ias,face,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_face,event_rule\",\"capabilitySetName\":\"IO能力,可视域事件能力,可视域能力,入侵报警事件能力,人脸识别能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,人脸事件能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T15:17:57.612+08:00\",\"encodeDevIndexCode\":\"13881aa4a2a24e328033f19dd7323f1c\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000005\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.000+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"08e707b1446d4dafa83a23cf2b682ddf\",\"cameraName\":\"保利海上罗兰南\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,event_rule,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,行为分析事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:55:02.064+08:00\",\"encodeDevIndexCode\":\"5843ee94013d446ab4be58afe2df951f\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000004\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.106+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"295fbd04c7494a85b01214a612de8782\",\"cameraName\":\"星光岛一号桥\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"event_audio,motiontrack,io,event_gis,gis,event_ias,event_vss,record,vss,ptz,event_io,net,maintenance,event_device,status,event_rule\",\"capabilitySetName\":\"音频事件能力,自动跟踪能力,IO能力,可视域事件能力,可视域能力,入侵报警事件能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:44:26.978+08:00\",\"encodeDevIndexCode\":\"28817e4d0abb4a8e8a42ad1c4d3f0856\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000003\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.221+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"4030e6e41dae44c1a56abcb018046d56\",\"cameraName\":\"望海宾馆 01\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,gis,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status,event_rule,event_heat\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,可视域能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力,热成像事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"1\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:41:29.690+08:00\",\"encodeDevIndexCode\":\"d60de69b808742308e2314a2967fcbfe\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000002\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.375+08:00\"},{\"altitude\":null,\"cameraIndexCode\":\"cb6511ef7eb04c37948ab7de7f2925d1\",\"cameraName\":\"望海宾馆 02\",\"cameraType\":0,\"cameraTypeName\":\"枪机\",\"capabilitySet\":\"manualtrack,event_audio,io,event_gis,gis,event_vss,record,vss,ptz,event_io,net,event_real_time_thermometry,maintenance,event_device,status,event_rule,event_heat\",\"capabilitySetName\":\"手动跟踪能力,音频事件能力,IO能力,可视域事件能力,可视域能力,视频事件能力,录像能力,视频能力,云台能力,IO事件能力,网络参数配置能力,实时测温事件能力,设备维护能力,设备事件能力,状态能力,行为分析事件能力,热成像事件能力\",\"intelligentSet\":null,\"intelligentSetName\":null,\"channelNo\":\"2\",\"channelType\":\"analog\",\"channelTypeName\":\"模拟通道\",\"createTime\":\"2020-10-09T14:41:29.698+08:00\",\"encodeDevIndexCode\":\"d60de69b808742308e2314a2967fcbfe\",\"encodeDevResourceType\":null,\"encodeDevResourceTypeName\":null,\"gbIndexCode\":\"37021110581314000001\",\"installLocation\":null,\"keyBoardCode\":null,\"latitude\":null,\"longitude\":null,\"pixel\":null,\"ptz\":null,\"ptzName\":null,\"ptzController\":null,\"ptzControllerName\":null,\"recordLocation\":\"0\",\"recordLocationName\":\"中心存储\",\"regionIndexCode\":\"a07e9a2c-58c5-4d2d-9d41-94c21bbc9645\",\"status\":null,\"statusName\":null,\"transType\":1,\"transTypeName\":\"TCP\",\"treatyType\":null,\"treatyTypeName\":null,\"viewshed\":null,\"updateTime\":\"2020-10-22T00:00:03.445+08:00\"}]}}"; + // JSONObject json = JSONObject.parseObject(jsonstr); + System.out.println(callPostStringApi()); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CameraDegreesUtil.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CameraDegreesUtil.java new file mode 100644 index 0000000..cffe90f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CameraDegreesUtil.java @@ -0,0 +1,343 @@ +package com.ltgk.smartFishingPort.utils; + +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * @Auther: zhouyaoyao + * @Date: 2021/10/26 09:08 + * @Description: 摄像角度调整工具类 + */ +@Slf4j +public class CameraDegreesUtil { + +// static Log log = LogFactory.get(CameraDegreesUtil.class); + + /** + * 根据摄像和目标的经纬度位置,计算摄像需要旋转的角度 + * 在北半球、摄像复位正北的情况下 + * + * @param lon1 摄像经度 + * @param lat1 摄像纬度 + * @param lon2 目标经度 + * @param lat2 目标纬度 + * @param rotateT -1: 旋转角度大于零,顺时针右侧旋转 旋转角度小于零,逆时针左侧旋转 + * 1: 旋转角度大于零,逆时针右侧旋转 旋转角度小于零,顺时针左侧旋转 + * @return + */ + public static BigDecimal rotateForNorthByLR(double lon1, double lat1, double lon2, double lat2, int rotateT) { +// // log.info("[摄像角度调整]左右调整角度,摄像位置({},{}),目标位置({},{})",lon1,lat1,lon2,lat2); + BigDecimal latitude1 = new BigDecimal(lat1); + BigDecimal latitude2 = new BigDecimal(lat2); + BigDecimal longitude1 = new BigDecimal(lon1); + BigDecimal longitude2 = new BigDecimal(lon2); + + // lonVal = longitude1 - longitude2 + BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP); + // latVal = latitude1 - latitude2 + BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP); + // zeroVal = 0.0000 + BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP); + + // 1: lonVal > 0 -1: lonVal < 0 0: lonVal = 0 + int lonJudge = lonVal.compareTo(zeroVal); + // 1: latVal > 0 -1: latVal < 0 0: latVal = 0 + int latJudge = latVal.compareTo(zeroVal); + + if (lonJudge != 0 && latJudge != 0) { + // 顺逆时针旋转 rotateT + // -1: 旋转角度大于零,顺时针右侧旋转 旋转角度小于零,逆时针左侧旋转 + // 1: 旋转角度大于零,逆时针右侧旋转 旋转角度小于零,顺时针左侧旋转 + double k1 = lonJudge*rotateT; + double k2 = latJudge; + // lonTolat = |latVal/lonVal| + BigDecimal latToLon = latVal.divide(lonVal,10,RoundingMode.HALF_UP).abs(); + // π/2 + k2*arctan(|latVal/lonVal| * Cos(longitude1 * π / 180)) +// // log.info("[摄像角度调整]当前1纬度=111km,1经度={}km",new BigDecimal(111*Math.cos(latitude1.doubleValue()*Math.PI/180)).setScale(4,RoundingMode.HALF_UP)); + double atanVal = Math.PI/2 + k2*Math.atan(latToLon.doubleValue()/Math.cos(latitude1.doubleValue()*Math.PI/180)); + // // log.info("[摄像角度调整]计算斜率对应的孤独:π/2 + {}*arctan(|{}/{}| * Cos({} * π / 180)) = {}",k2,latVal,lonVal,latitude1.setScale(4,RoundingMode.HALF_UP),atanVal); +// // log.info("[摄像角度调整]计算斜率对应的孤独:{}",atanVal); + double degreesVal = k1*Math.toDegrees(atanVal); + BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP); +// // log.info("[摄像角度调整]计算孤独对应的角度:{}",degrees); +// // log.info("[摄像角度调整]摄像应【{}】时针旋转:{}°",degreesVal*rotateT > 0 ? "逆" : "顺",degrees.abs()); + return degrees; + } else { + if (lonJudge == 0 && (latJudge == -1 || latJudge == 0)) { +// // log.info("[摄像角度调整]目标在摄像正北方向,摄像旋转:0°"); + return BigDecimal.ZERO; + } else if (lonJudge == 0 && latJudge == 1) { +// // log.info("[摄像角度调整]目标在摄像正南方向,摄像顺时针旋转:180°"); + return new BigDecimal("180"); + } else if (latJudge == 0 && lonJudge == 1) { +// // log.info("[摄像角度调整]目标在摄像正西方向,摄像逆时针旋转:90°"); + return new BigDecimal("-90"); + } else if (latJudge == 0 && lonJudge == -1) { +// // log.info("[摄像角度调整]目标在摄像正东方向,摄像顺时针旋转:90°"); + return new BigDecimal("90"); + } else { + return BigDecimal.ZERO; + } + } + } + + /** + * 根据摄像和目标的经纬度位置,计算摄像需要旋转的角度 + * 在北半球、摄像复位正南的情况下 + * 大于零:顺时针右侧旋转 小于零:逆时针左侧旋转 + * @param lon1 摄像经度 + * @param lat1 摄像纬度 + * @param lon2 目标经度 + * @param lat2 目标纬度 + * @return + */ + public static BigDecimal rotateForSouthByLR(double lon1, double lat1, double lon2, double lat2) { +// // log.info("[摄像角度调整]左右调整角度,摄像位置({},{}),目标位置({},{})",lon1,lat1,lon2,lat2); + BigDecimal latitude1 = new BigDecimal(lat1); + BigDecimal latitude2 = new BigDecimal(lat2); + BigDecimal longitude1 = new BigDecimal(lon1); + BigDecimal longitude2 = new BigDecimal(lon2); + + // lonVal = longitude1 - longitude2 + BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP); + // latVal = latitude1 - latitude2 + BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP); + // zeroVal = 0.0000 + BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP); + + // 1: lonVal > 0 -1: lonVal < 0 0: lonVal = 0 + int lonJudge = lonVal.compareTo(zeroVal); + // 1: latVal > 0 -1: latVal < 0 0: latVal = 0 + int latJudge = latVal.compareTo(zeroVal); + + if (lonJudge != 0 && latJudge != 0) { + // 顺逆时针旋转 1:顺时针右侧旋转 -1:逆时针左侧旋转 + double k1 = lonJudge; + double k2 = latJudge*(-1); + // lonTolat = |latVal/lonVal| + BigDecimal latToLon = latVal.divide(lonVal,10,RoundingMode.HALF_UP).abs(); + // π/2 + k2*arctan(|latVal/lonVal| * Cos(longitude1 * π / 180)) +// // log.info("[摄像角度调整]当前1纬度=111km,1经度={}km",new BigDecimal(111*Math.cos(latitude1.doubleValue()*Math.PI/180)).setScale(4,RoundingMode.HALF_UP)); + double atanVal = Math.PI/2 + k2*Math.atan(latToLon.doubleValue()/Math.cos(latitude1.doubleValue()*Math.PI/180)); + // // log.info("[摄像角度调整]计算斜率对应的孤独:π/2 + {}*arctan(|{}/{}| * Cos({} * π / 180)) = {}",k2,latVal,lonVal,latitude1.setScale(4,RoundingMode.HALF_UP),atanVal); +// // log.info("[摄像角度调整]计算斜率对应的孤独:{}",atanVal); + double degreesVal = k1*Math.toDegrees(atanVal); + BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP); +// // log.info("[摄像角度调整]计算孤独对应的角度:{}",degrees); +// // log.info("[摄像角度调整]摄像应【{}】时针{}旋转:{}°" +// ,degreesVal < 0 ? "逆" : "顺" +// ,degreesVal < 0 ? "左侧" : "右侧" +// ,degrees.abs()); + return degrees; + } else { + if (lonJudge == 0 && (latJudge == -1 || latJudge == 0)) { +// // log.info("[摄像角度调整]目标在摄像正北方向,摄像旋转:180°"); + return new BigDecimal("180"); + } else if (lonJudge == 0 && latJudge == 1) { +// // log.info("[摄像角度调整]目标在摄像正南方向,摄像顺时针右侧旋转:0°"); + return BigDecimal.ZERO; + } else if (latJudge == 0 && lonJudge == 1) { +// // log.info("[摄像角度调整]目标在摄像正西方向,摄像顺时针右侧旋转:90°"); + return new BigDecimal("90"); + } else if (latJudge == 0 && lonJudge == -1) { +// // log.info("[摄像角度调整]目标在摄像正东方向,摄像逆时针左侧旋转:90°"); + return new BigDecimal("-90"); + } else { + return BigDecimal.ZERO; + } + } + } + + /** + * 根据摄像的高度high和距离目标的长度distance,计算摄像需要下调的角度 + * 在摄像复位水平的情况下 + * @param lon1 摄像经度 + * @param lat1 摄像纬度 + * @param lon2 目标经度 + * @param lat2 目标纬度 + * @param high 千米 + * @return + */ + public static BigDecimal rotateByUD(double high,double lon1, double lat1, double lon2, double lat2) { + double distance = 0d; + BigDecimal latitude1 = new BigDecimal(lat1); + BigDecimal latitude2 = new BigDecimal(lat2); + BigDecimal longitude1 = new BigDecimal(lon1); + BigDecimal longitude2 = new BigDecimal(lon2); + + // lonVal = longitude1 - longitude2 + BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP); + // latVal = latitude1 - latitude2 + BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP); + // zeroVal = 0.0000 + BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP); + + // 1: lonVal > 0 -1: lonVal < 0 0: lonVal = 0 + int lonJudge = lonVal.compareTo(zeroVal); + // 1: latVal > 0 -1: latVal < 0 0: latVal = 0 + int latJudge = latVal.compareTo(zeroVal); + + if (lonJudge == 0 || latJudge == 0) { + if (latJudge != 0) { + return latVal.abs(); + } else if (lonJudge != 0) { + return lonVal.abs(); + } + return BigDecimal.ZERO; + } else { + double lonPow = Math.pow(lonVal.doubleValue(),2) * 111 * Math.cos(latitude1.doubleValue()*Math.PI/180); + double latPow = Math.pow(latVal.doubleValue(),2) * 111; + distance = Math.sqrt(Math.pow(lonPow,2) + Math.pow(latPow,2)); + } +// // log.info("[摄像角度调整]上下调整角度,摄像位置高{},距离目标位置{}",high,distance); +// BigDecimal distanceVal = new BigDecimal(distance); + BigDecimal distanceVal = getDistance1( lon1, lat1, lon2, lat2); + BigDecimal highVal = new BigDecimal(high); + + BigDecimal hToD = highVal.divide(distanceVal,4,RoundingMode.HALF_UP); + double degreesVal = Math.toDegrees(Math.atan(hToD.doubleValue())); + BigDecimal degrees = new BigDecimal(degreesVal).setScale(4,RoundingMode.HALF_UP); +// // log.info("[摄像角度调整]摄像下调角度{}°",degrees); + return degrees; + } + + + /** + * 赤道半径(单位:米) + */ + private static final double EQUATOR_RADIUS = 6378137; + + /** + * 方法一:(反余弦计算方式) + * + * @param longitude1 第一个点的经度 + * @param latitude1 第一个点的纬度 + * @param longitude2 第二个点的经度 + * @param latitude2 第二个点的纬度 + * @return 返回距离,单位m + */ + public static BigDecimal getDistance1(double longitude1, double latitude1, double longitude2, double latitude2) { + // 纬度 + double lat1 = Math.toRadians(latitude1); + double lat2 = Math.toRadians(latitude2); + // 经度 + double lon1 = Math.toRadians(longitude1); + double lon2 = Math.toRadians(longitude2); + // 纬度之差 + double a = lat1 - lat2; + // 经度之差 + double b = lon1 - lon2; + // 计算两点距离的公式 + double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2))); + // 弧长乘赤道半径, 返回单位: 米 + s = s * EQUATOR_RADIUS; +// // log.info("距离目标位置{}",s/1000); + return new BigDecimal(s/1000); + } + + /** + * 计算摄像距离目标的长度distance + * 在摄像复位水平的情况下 + * @param lon1 摄像经度 + * @param lat1 摄像纬度 + * @param lon2 目标经度 + * @param lat2 目标纬度 + * @return + */ + public static BigDecimal distanceByUD(double lon1, double lat1, double lon2, double lat2) { + double distance = 0d; + BigDecimal latitude1 = new BigDecimal(lat1); + BigDecimal latitude2 = new BigDecimal(lat2); + BigDecimal longitude1 = new BigDecimal(lon1); + BigDecimal longitude2 = new BigDecimal(lon2); + + // lonVal = longitude1 - longitude2 + BigDecimal lonVal = longitude1.subtract(longitude2).setScale(10, RoundingMode.HALF_UP); + // latVal = latitude1 - latitude2 + BigDecimal latVal = latitude1.subtract(latitude2).setScale(10, RoundingMode.HALF_UP); + // zeroVal = 0.0000 + BigDecimal zeroVal = BigDecimal.ZERO.setScale(10,RoundingMode.HALF_UP); + + // 1: lonVal > 0 -1: lonVal < 0 0: lonVal = 0 + int lonJudge = lonVal.compareTo(zeroVal); + // 1: latVal > 0 -1: latVal < 0 0: latVal = 0 + int latJudge = latVal.compareTo(zeroVal); + + if (lonJudge == 0 || latJudge == 0) { + if (latJudge != 0) { + return latVal.abs(); + } else if (lonJudge != 0) { + return lonVal.abs(); + } + return BigDecimal.ZERO; + } else { + double lonPow = Math.pow(lonVal.doubleValue(),2) * 111 * Math.cos(latitude1.doubleValue()*Math.PI/180); + double latPow = Math.pow(latVal.doubleValue(),2) * 111; + distance = Math.sqrt(Math.pow(lonPow,2) + Math.pow(latPow,2)); + } +// // log.info("[摄像distance],距离目标位置{}",distance); + BigDecimal distanceVal = new BigDecimal(distance); + return distanceVal; + } + + public static void main(String[] args) { + System.out.println("摄像复位正南,摄像位置(121.4576,37.153002),目标位置(119.4581,38.004037),摄像旋转【"+ + rotateForNorthByLR(122.98386589,39.25478846,122.938824,39.194066,1) + +"】度"); + +// System.out.println("摄像复位正南,摄像位置(121.4576,37.281),目标位置(119.4553,36.576),摄像旋转【"+ +// rotateForSouthByLR(121.4576,37.281,119.4553,36.576) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4504,37.153),目标位置(123.4504,38.281),摄像旋转【"+ +// rotateForSouthByLR(121.4504,37.153,123.4504,38.281) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4581,36),目标位置(123.4576,35.004),摄像旋转【"+ +// rotateForSouthByLR(121.4581,36,123.476,35.004) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4553,37.281),目标位置(121.4553,38.576),摄像旋转【"+ +// rotateForSouthByLR(121.4553,37.281,121.4553,38.576) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4553,37.281),目标位置(119.4581,37.283),摄像旋转【"+ +// rotateForSouthByLR(121.4553,37.283,119.4581,37.283) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4583,37.281),目标位置(121.4583,36.004),摄像旋转【"+ +// rotateForSouthByLR(121.4583,37.281,121.4583,36.004) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4581,37.104),目标位置(123.4504,37.104),摄像旋转【"+ +// rotateForSouthByLR(121.4581,37.104,123.4504,37.104) +// +"】度"); +// +// System.out.println("摄像复位正南,摄像位置(121.4581,37.576),目标位置(121.4581,37.576),摄像旋转【"+ +// rotateForSouthByLR(121.4581,37.576,121.4581,37.576) +// +"】度"); +// +// System.out.println("摄像位置高:20.153m,摄像向下调整【"+ +// rotateByUD(20.153,121.4581,37.576,119.4581,38.004037) +// +"】度"); + + } + + /** + * 方法一:(反余弦计算方式) + */ + public static BigDecimal getDistance(double longitude1, double latitude1, double longitude2, double latitude2) { + double lat1 = Math.toRadians(latitude1); + double lat2 = Math.toRadians(latitude2); + double lon1 = Math.toRadians(longitude1); + double lon2 = Math.toRadians(longitude2); + double a = lat1 - lat2; + double b = lon1 - lon2; + double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2))); + s = s * EQUATOR_RADIUS; + return new BigDecimal(s/1000); + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CustomException.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CustomException.java new file mode 100644 index 0000000..27592b4 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/CustomException.java @@ -0,0 +1,37 @@ +package com.ltgk.smartFishingPort.utils; + +/** + * 自定义异常 + * + * @author liuchunzhe + */ +public class CustomException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private Integer code; + + private String message; + + public CustomException(String message) { + this.message = message; + } + + public CustomException(String message, Integer code) { + this.message = message; + this.code = code; + } + + public CustomException(String message, Throwable e) { + super(message, e); + this.message = message; + } + + @Override + public String getMessage() { + return message; + } + + public Integer getCode() { + return code; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/DateTimeConverter.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/DateTimeConverter.java new file mode 100644 index 0000000..8f64e4e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/DateTimeConverter.java @@ -0,0 +1,42 @@ +package com.ltgk.smartFishingPort.utils; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @version 1.0 + * @since 2023-02-08 16:41:55 + **/ +public class DateTimeConverter implements Converter { + + private static final String PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Date convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception { + return null; + } + + @Override + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_YYYY_MM_DD_HH_MM_SS); + String dateValue = sdf.format(value); + return new CellData<>(dateValue); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ExcelUtil.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ExcelUtil.java new file mode 100644 index 0000000..c0551f9 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/ExcelUtil.java @@ -0,0 +1,116 @@ +package com.ltgk.smartFishingPort.utils; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.google.common.base.Charsets; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.List; + +/** + * Excel相关处理 + * + * @author zhou + */ +public class ExcelUtil { + + /** + * 实体对象 + */ + public Class clazz; + + public ExcelUtil(Class clazz) { + this.clazz = clazz; + } + + + public List importExcel(MultipartFile file, AnalysisEventListener listener, String sheetName) { + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(file.getInputStream()); + ExcelReaderSheetBuilder builder = EasyExcel.read(inputStream, clazz, listener).sheet(sheetName); + return builder.doReadSync(); + } catch (IOException exception) { + exception.printStackTrace(); + throw new CustomException("导入失败!"); + } + } + + + public List importExcel(MultipartFile file, String sheetName) { + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(file.getInputStream()); + ExcelReaderSheetBuilder builder = EasyExcel.read(inputStream).sheet(sheetName); + return builder.doReadSync(); + } catch (IOException exception) { + exception.printStackTrace(); + throw new CustomException("导入失败!"); + } + } + + + public void exportExcel(HttpServletResponse response, String fileName, String sheetName, List list) { + ServletOutputStream outputStream = null; + try { + outputStream = response.getOutputStream(); + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding(Charsets.UTF_8.name()); + fileName = URLEncoder.encode(fileName, Charsets.UTF_8.name()); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + EasyExcel.write(outputStream, clazz).sheet(sheetName).doWrite(list); + } catch (IOException exception) { + exception.printStackTrace(); + throw new CustomException("导出失败!"); + } finally { + try { + if (outputStream != null) { + outputStream.close(); + } + } catch (IOException exception) { + exception.printStackTrace(); + } + } + } + + public void exportExcelWithTemplate(HttpServletResponse response, String fileName, String templatePath, List list) { + ServletOutputStream outputStream = null; + InputStream in = null; + try { + outputStream = response.getOutputStream(); + in = new FileInputStream(templatePath); + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding(Charsets.UTF_8.name()); + fileName = URLEncoder.encode(fileName, Charsets.UTF_8.name()); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(in).build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + excelWriter.fill(list, writeSheet); + excelWriter.finish(); + } catch (IOException exception) { + exception.printStackTrace(); + throw new CustomException("导出失败!"); + } finally { + try { + if (outputStream != null) { + outputStream.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException exception) { + exception.printStackTrace(); + } + } + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/GeoUtils.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/GeoUtils.java new file mode 100644 index 0000000..1af8b2d --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/utils/GeoUtils.java @@ -0,0 +1,78 @@ +package com.ltgk.smartFishingPort.utils; + +import java.awt.geom.Point2D; +import java.util.List; + +/** + * GeoUtils 静态工具类 + */ +public class GeoUtils { + /** + * 判断点是否在多边形内 + * + * @param point 测试点 + * @param pts 多边形的点 + * @return boolean + * @Title: IsPointInPoly + * @Description: + */ + public static boolean isInPolygon(Point2D.Double point, List pts) { + int num = pts.size(); + // 交叉点数量 + int intersectCount = 0; + // 浮点类型计算时候与0比较时候的容差 + double precision = 2e-10; + // 临近顶点 + Point2D.Double p1, p2; + p1 = pts.get(0); + for (int i = 1; i <= num; ++i) { + if (point.equals(p1)) { + return true; + } + + p2 = pts.get(i % num); + if (point.x < Math.min(p1.x, p2.x) || point.x > Math.max(p1.x, p2.x)) { + p1 = p2; + continue; + } + + //射线穿过算法 + if (point.x > Math.min(p1.x, p2.x) && point.x < Math.max(p1.x, p2.x)) { + if (point.y <= Math.max(p1.y, p2.y)) { + if (p1.x == p2.x && point.y >= Math.min(p1.y, p2.y)) { + return true; + } + + if (p1.y == p2.y) { + if (p1.y == point.y) { + return true; + } else { + ++intersectCount; + } + } else { + double xinters = (point.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y; + if (Math.abs(point.y - xinters) < precision) { + return true; + } + + if (point.y < xinters) { + ++intersectCount; + } + } + } + } else { + if (point.x == p2.x && point.y <= p2.y) { + Point2D.Double p3 = pts.get((i + 1) % num); + if (point.x >= Math.min(p1.x, p3.x) && point.x <= Math.max(p1.x, p3.x)) { + ++intersectCount; + } else { + intersectCount += 2; + } + } + } + p1 = p2; + } + // 偶数在多边形外, 奇数在多边形内 + return intersectCount % 2 != 0; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSClient.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSClient.java new file mode 100644 index 0000000..911c30f --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSClient.java @@ -0,0 +1,72 @@ +package com.ltgk.smartFishingPort.websocket.WsClient; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.ContainerProvider; +import javax.websocket.Session; +import javax.websocket.WebSocketContainer; +import java.net.URI; +import java.util.concurrent.ConcurrentHashMap; + +@Component +@Slf4j +public class WSClient { + + public static Session session; + + public static String realPlayValue; + + /** + * 存放每个客户端对应的WebSocket对象,根据设备realPlayHandler建立session + */ + public static ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + public static ConcurrentHashMap sessionsWithHandleKey = new ConcurrentHashMap<>(); + + + public static void startWS(String realPlayHandle) { + try { +// String url = "ws://10.110.1.12:6450/dhsdk/" + realPlayHandle; + String url = "ws://localhost:6002/pm-quartz/SowWs/" + realPlayHandle; + WebSocketContainer container = ContainerProvider.getWebSocketContainer(); + //设置消息大小最大为10M + container.setDefaultMaxBinaryMessageBufferSize(10*1024*1024); + container.setDefaultMaxTextMessageBufferSize(10*1024*1024); + // 客户端,开启服务端websocket。 + Session session = container.connectToServer(WSHandler.class, URI.create(url)); + if (sessions.containsKey(session)) { + sessions.put(session, realPlayHandle); + sessionsWithHandleKey.put(realPlayHandle, session); + } else { + sessions.put(session, realPlayHandle); + sessionsWithHandleKey.put(realPlayHandle, session); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void stopWS(String realPlayHandle){ + try{ + Session session = sessionsWithHandleKey.get(realPlayHandle); + sessions.remove(session); + sessionsWithHandleKey.remove(realPlayHandle); + session.close(); + }catch (Exception e){ + e.printStackTrace(); + } + } + + public static void stopWS(Session session){ + try{ + String realPlayHandle = sessions.get(session); + sessions.remove(session); + sessionsWithHandleKey.remove(realPlayHandle); + session.close(); + }catch (Exception e){ + e.printStackTrace(); + } + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSHandler.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSHandler.java new file mode 100644 index 0000000..a2fbabc --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/WsClient/WSHandler.java @@ -0,0 +1,75 @@ +package com.ltgk.smartFishingPort.websocket.WsClient; + +import com.ltgk.smartFishingPort.websocket.work.NotifyManager; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import java.nio.ByteBuffer; +import java.util.Objects; + + +@ClientEndpoint +@Slf4j +@Component +public class WSHandler { + + @OnOpen + public void onOpen(Session session) { + WSClient.session = session; + } + + @OnMessage + public void processMessage(ByteBuffer message, Session session) { + log.info("websocketRecive接收推送消息"); + + if(WSClient.sessions.containsKey(session)){ + String reaPlayValue = WSClient.sessions.get(session); + NotifyManager.sendMsgOne(message, reaPlayValue); + } + + } + + @OnError + public void processError(Throwable t) { + WSClient.session = null; + String realPlayHandle = WSClient.realPlayValue; + try { + Thread.sleep(5000); + WSClient.startWS(realPlayHandle); + } catch (InterruptedException e) { + log.error("---websocket processError InterruptedException---", e); + } + log.error("---websocket processError error---", t); + } + + @OnClose + public void processClose(Session session, CloseReason closeReason) { + if(session != null){ + try { + if(WSClient.sessions.containsKey(session)){ + String realPlayHandler = WSClient.sessions.get(session); + NotifyManager.closeByRealPlay(realPlayHandler); + WSClient.stopWS(session); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void send(String sessionId, String message) { + try { + log.info("send Msg:" + message); + if (Objects.nonNull(WSClient.session)) { + WSClient.session.getBasicRemote().sendText(message); + } else { + log.info("---websocket error----"); + } + + } catch (Exception e) { + log.error("---websocket send error---", e); + } + + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/config/WebSocketConfig.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/config/WebSocketConfig.java new file mode 100644 index 0000000..e41c8ac --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/config/WebSocketConfig.java @@ -0,0 +1,16 @@ +package com.ltgk.smartFishingPort.websocket.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +@Slf4j +@Configuration +public class WebSocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotiListener.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotiListener.java new file mode 100644 index 0000000..fa9a168 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotiListener.java @@ -0,0 +1,56 @@ +package com.ltgk.smartFishingPort.websocket.work; + +import java.nio.ByteBuffer; + +/** + * @author chxiaofang + */ +public interface NotiListener { + +// void onNoti(List ctAlarmInfoDTOList); + + + /** + * 发送消息 + * + * @param res + */ + void sendMessage(Object res); + + /** + * 渔船报警消息推送 + * + * @param res + */ + void sendMsgShip(Object res); + + + /** + * 无人机轨迹数据推送至PC端 + * + * @param res + */ + void sendUavTrajectoryData(Object res); + + /** + * 应急救援报警数据推送至PC端 + * + * @param res + */ + void sendEmergencyRescue(Object res); + + /** + * 单个发送二进制消息 + * @param byteBuffer 二进制数据 + * @param realPlayHandler 预览句柄 + */ + void sendMsgOne(ByteBuffer byteBuffer, String realPlayHandler); + + /** + * 通过预览句柄关闭连接 + * @param realPlayHandler 预览句柄 + */ + void closeByRealPlay(String realPlayHandler); + + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotifyManager.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotifyManager.java new file mode 100644 index 0000000..00d6b46 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/NotifyManager.java @@ -0,0 +1,105 @@ +package com.ltgk.smartFishingPort.websocket.work; + + +import org.springframework.stereotype.Component; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author chxiaofang + */ +@Component +public final class NotifyManager { + + + private static List consumers = new ArrayList<>(); + + public static List onOpenCtUnitIds = new ArrayList<>(); + + public static int liveCarNum = 0; + + public static Map sessionMap = new HashMap<>(); + + public void registConsumer(NotiListener listener) { + this.consumers.add(listener); + } + + public void registConsumer(NotiListener listener, String realPlayHandler) { + this.sessionMap.put(realPlayHandler, listener); + } + + public void logoutConsumer(String realPlayHandler) { + this.sessionMap.remove(realPlayHandler); + } + + /** + * 渔船报警消息推送 + * + * @param res + */ + public static void sendMsgShip(Object res) { + for (NotiListener consumer : consumers) { + consumer.sendMsgShip(res); + } + } + + /** + * 发送心跳 + * + * @param res + */ + public static void sendMsgHeartbeat(Object res) { + for (NotiListener consumer : consumers) { + consumer.sendMessage(res); + } + } + + + /** + * 无人机轨迹数据推送至PC端 + * + * @param res + */ + public static void sendUavTrajectoryData(Object res) { + for (NotiListener consumer : consumers) { + consumer.sendUavTrajectoryData(res); + } + } + + + /** + * 应急救援报警数据推送至PC端 + * + * @param res + */ + public static void sendEmergencyRescue(Object res) { + for (NotiListener consumer : consumers) { + consumer.sendEmergencyRescue(res); + } + } + + /** + * 发送码流数据 + * @param byteBuffer + * @param realPlayHandler + */ + public static void sendMsgOne(ByteBuffer byteBuffer, String realPlayHandler){ + NotiListener consumer = sessionMap.get(realPlayHandler); + consumer.sendMsgOne(byteBuffer, realPlayHandler); +// sendMsgOne(byteBuffer, realPlayHandler); + } + + /** + * 通过预览句柄断开连接 + * @param realPlayHandler 预览句柄 + */ + public static void closeByRealPlay(String realPlayHandler){ + NotiListener consumer = sessionMap.get(realPlayHandler); + consumer.closeByRealPlay(realPlayHandler); + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/SowWs.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/SowWs.java new file mode 100644 index 0000000..6842539 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/SowWs.java @@ -0,0 +1,266 @@ +package com.ltgk.smartFishingPort.websocket.work; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import com.ltgk.smartFishingPort.websocket.work.entity.Key; +import com.ltgk.smartFishingPort.websocket.work.entity.WsRes; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.Principal; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Author: zhouyaoyao + * @Date 2025/10/21 14:00 + * Description: + */ +@Slf4j +@ServerEndpoint(value = "/SowWs/{realPlayHandler}") +@Component +public class SowWs implements NotiListener { + + + /** + * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 + */ + private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); + + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + private Session session; + + private static ApplicationContext applicationContext; + +// private ISysUserService userService; + + private NotifyManager notifyManager; + + /** + * 存放每个客户端对应的WebSocket对象,根据设备realPlayHandler建立session + */ + private static ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + + public static void setApplicationContext(ApplicationContext applicationContext) { + SowWs.applicationContext = applicationContext; + } + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session, @PathParam("realPlayHandler") String realPlayHandler) { + this.session = session; +// userService = applicationContext.getBean(ISysUserService.class); + + notifyManager = applicationContext.getBean(NotifyManager.class); + notifyManager.registConsumer(this); + + if(!"0".equals(realPlayHandler)){ + if (sessions.containsKey(realPlayHandler)) { + sessions.put(realPlayHandler, session); + } else { + sessions.put(realPlayHandler, session); + } + notifyManager.registConsumer(this, realPlayHandler); +// WSClient.startWS(realPlayHandler); + } + + + webSocketSet.add(this); + log.info("新连接加入,当前在线客户端数量:" + webSocketSet.size()); + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose(Session session, @PathParam("realPlayHandler") String realPlayHandler) { + if(!"0".equals(realPlayHandler)){ + log.info("断开预览:" + realPlayHandler); + if (sessions.containsKey(realPlayHandler)) { + sessions.remove(realPlayHandler); +// WSClient.stopWS(realPlayHandler); + } + notifyManager.logoutConsumer(realPlayHandler); + } + webSocketSet.remove(this); + log.info("连接断开,当前在线客户端数量:" + webSocketSet.size()); + } + + /** + * 收到客户端消息后调用的方法 + * 客户端发送的message统一按WsRes格式进行封装 + * + * @param message + */ + @OnMessage + public void onMessage(String message, Session session) { + log.info(message); + WsRes msg = null; + try { + msg = JSON.parseObject(message, WsRes.class); + } catch (Exception e) { + log.warn("WebSocket连接已被客户端关闭: {}", session.getId(), e); + return; + } + String msType = msg.getType(); + Object data = msg.getData(); + String target = msg.getTarget(); + switch (msType) { + case Key.BASE_USERTOKEN: +// String token = String.valueOf(data); +// setUser(token, msg); + break; + case Key.DUTY_ORG_INFO: + Long oid = Long.valueOf(target); + backStation(oid, msg); + break; + + default: + break; + } + } + + /** + * 发生错误时调用 + */ + @OnError + public void onError(Session session, Throwable error) { + Principal principal = session.getUserPrincipal(); + log.info(principal == null ? "" : session.getUserPrincipal().getName() + "发生错误", error.getMessage()); + error.printStackTrace(); + } + + /** + * 渔船报警消息推送 + * + * @param res + */ + @Override + public void sendMsgShip(Object res) { + /*if(this.userInfo == null){ + this.onClose(session); + return; + }*/ + sendMessage(res); + } + + // 服务器定时向客户端发送心跳 + @Scheduled(fixedRate = 30000) // 每30秒一次 + public void sendHeartbeat() { + for (Map.Entry entry : sessions.entrySet()) { // sessionMap存储活跃连接 + if (entry.getValue().isOpen()) { + try { + Map map = Maps.newHashMap(); + map.put("data","ping"); + map.put("target",entry.getKey()); + map.put("type","heart"); + entry.getValue().getBasicRemote().sendText(JSONObject.toJSONString(map)); + } catch (IOException e) { + log.warn("发送心跳失败,连接可能已断开: {}", entry.getValue().getId()); + } + } + } + } + + /** + * 发送信息 + * + * @param res + */ + @Override + public void sendMessage(Object res) { +// System.out.println("发送消息."); + for (Map.Entry entry : sessions.entrySet()) { // sessionMap存储活跃连接 + Session session1 = entry.getValue(); + if (session1 != null&&session1.isOpen()) { + synchronized (session1) { + try { + session1.getBasicRemote().sendText(JSON.toJSONString(res)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + } + + + /** + * 无人机轨迹数据推送至PC端 + * + * @param res + */ + @Override + public void sendUavTrajectoryData(Object res) { + sendMessage(res); + } + + /** + * 应急救援报警数据推送至PC端 + * + * @param res + */ + @Override + public void sendEmergencyRescue(Object res) { + sendMessage(res); + } + + @Override + public void sendMsgOne(ByteBuffer byteBuffer, String realPlayHandler) { +//登录句柄无效 + if ("0".equals(realPlayHandler)) { + log.error("loginHandler is invalid.please check.", this); + return; + } + Session session = sessions.get(realPlayHandler); + if (session != null) { + synchronized (session) { + try { + session.getBasicRemote().sendBinary(byteBuffer); + byte[] bytes=new byte[byteBuffer.limit()]; + byteBuffer.get(bytes); + } catch (IOException e) { + e.printStackTrace(); + } + } + } else { + //log.error("session is null.please check.", this); + } + } + + /** + * 通过预览句柄关闭连接 + * @param realPlayHandler 预览句柄 + */ + @Override + public void closeByRealPlay(String realPlayHandler) { + Session session = sessions.get(realPlayHandler); + if(session != null){ + sessions.remove(realPlayHandler); + try { + session.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + + private void backStation(Long oid, WsRes req) { + sendMessage(req); + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Action.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Action.java new file mode 100644 index 0000000..172c66b --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Action.java @@ -0,0 +1,66 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @author chxiaofang + */ +public class Action { + + /** + * 时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date time; + + /** + * 事件 + */ + private String thing; + + /** + * 相关人员 + */ + private String user; + + /** + * 相关对象 + */ + private String object; + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public String getThing() { + return thing; + } + + public void setThing(String thing) { + this.thing = thing; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Key.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Key.java new file mode 100644 index 0000000..3f904e5 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/Key.java @@ -0,0 +1,50 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + +/** + * @author chxiaofang + */ +public class Key { + + /** + * 配置socket用户信息 + * 输入 token + * 输出data “用户XX成功建立连接” + */ + public final static String BASE_USERTOKEN = "BASE_USERTOKEN"; + + /** + * 查询站点值班事务 + * 输入 target:oid + * 输出data stationduty + */ + public final static String DUTY_ORG_INFO = "DUTY_ORG_INFO"; + + /** + * 交班 + * 输入 target:duty_record_id data:userName + * 输出data stationduty + */ + public final static String DUTY_ORG_CHANGE = "DUTY_ORG_CHANGE"; + + /** + * 下班 + * 输入 target:duty_record_id + * 输出data stationduty + */ + public final static String DUTY_ORG_OFF = "DUTY_ORG_OFF"; + + /** + * 上班 + * 输入 target:oid + * 输出data stationduty + */ + public final static String DUTY_ORG_ON = "DUTY_ORG_ON"; + + /** + * 值班日志 + * 输入 target:oid data:log + * 输出data stationduty + */ + public final static String DUTY_LOG = "DUTY_LOG"; + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/StoragePlan.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/StoragePlan.java new file mode 100644 index 0000000..a4cb302 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/StoragePlan.java @@ -0,0 +1,102 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +public class StoragePlan { + + @ApiModelProperty(value = "录像计划名称",example = "test1") + private String name; + + @ApiModelProperty(value = "码流类型: 1-主码流,2-辅码流1,3-辅码流2",example = "1") + private String streamType; + + @ApiModelProperty(value = "通道编码",example = "[\n" + + "\"1000000$1$0$0\",\n" + + "\"1000000$1$0$1\"\n" + + "]") + private List channelIds; + + @ApiModelProperty(value = "时间模板ID",example = "1") + private String timeTemplateId; + + @ApiModelProperty(value = "录像计划描述信息",example = "test") + private String description; + + @ApiModelProperty(value = "存储位置: 1-存储在中心服务器,3-存储在设备",example = "1") + private String position; + + @ApiModelProperty(value = "启停状态: 0-关闭,1-开启",example = "1") + private String status; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStreamType() { + return streamType; + } + + public void setStreamType(String streamType) { + this.streamType = streamType; + } + + public List getChannelIds() { + return channelIds; + } + + public void setChannelIds(List channelIds) { + this.channelIds = channelIds; + } + + public String getTimeTemplateId() { + return timeTemplateId; + } + + public void setTimeTemplateId(String timeTemplateId) { + this.timeTemplateId = timeTemplateId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + @Override + public String toString() { + return "{" + + "name=\"" + name + '\"' + + ", streamType=\"" + streamType + '\"' + + ", channelIds=" + channelIds + + ", timeTemplateId=\"" + timeTemplateId + '\"' + + ", description=\"" + description + '\"' + + ", position=\"" + position + '\"' + + ", status=\"" + status + '\"' + + '}'; + } + +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplate.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplate.java new file mode 100644 index 0000000..7fab6a6 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplate.java @@ -0,0 +1,147 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(description = "时间模板实体类") +public class TimeTemplate { + + @ApiModelProperty(value = "时间模板名称",example = "test") + private String timeTemplateName; + + @ApiModelProperty(value = "星期一时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List monPeriods; + + @ApiModelProperty(value = "星期二时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List tuePeriods; + + @ApiModelProperty(value = "星期三时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List wedPeriods; + + @ApiModelProperty(value = "星期四时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List thuPeriods; + + @ApiModelProperty(value = "星期五时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List friPeriods; + + @ApiModelProperty(value = "星期六时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List satPeriods; + + @ApiModelProperty(value = "星期天时间段",example = "[\n" + + "{\n" + + "\"beginTime\": \"10:00:00\",\n" + + "\"endTime\": \"18:00:00\"\n" + + "}\n" + + "]") + private List sunPeriods; + + public String getTimeTemplateName() { + return timeTemplateName; + } + + public void setTimeTemplateName(String timeTemplateName) { + this.timeTemplateName = timeTemplateName; + } + + public List getMonPeriods() { + return monPeriods; + } + + public void setMonPeriods(List monPeriods) { + this.monPeriods = monPeriods; + } + + public List getTuePeriods() { + return tuePeriods; + } + + public void setTuePeriods(List tuePeriods) { + this.tuePeriods = tuePeriods; + } + + public List getWedPeriods() { + return wedPeriods; + } + + public void setWedPeriods(List wedPeriods) { + this.wedPeriods = wedPeriods; + } + + public List getThuPeriods() { + return thuPeriods; + } + + public void setThuPeriods(List thuPeriods) { + this.thuPeriods = thuPeriods; + } + + public List getFriPeriods() { + return friPeriods; + } + + public void setFriPeriods(List friPeriods) { + this.friPeriods = friPeriods; + } + + public List getSatPeriods() { + return satPeriods; + } + + public void setSatPeriods(List satPeriods) { + this.satPeriods = satPeriods; + } + + public List getSunPeriods() { + return sunPeriods; + } + + public void setSunPeriods(List sunPeriods) { + this.sunPeriods = sunPeriods; + } + + @Override + public String toString() { + return "{" + + "timeTemplateName=\"" + timeTemplateName + '\"' + + ", monPeriods=" + monPeriods + + ", tuePeriods=" + tuePeriods + + ", wedPeriods=" + wedPeriods + + ", thuPeriods=" + thuPeriods + + ", friPeriods=" + friPeriods + + ", satPeriods=" + satPeriods + + ", sunPeriods=" + sunPeriods + + '}'; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplateTime.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplateTime.java new file mode 100644 index 0000000..e51013d --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/TimeTemplateTime.java @@ -0,0 +1,44 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(description = "时间模板时间实体类") +public class TimeTemplateTime { + + /** + * 开始时间 + */ + @ApiModelProperty(value = "开始时间",example = "10:00:00") + private String beginTime; + + /** + * 结束时间 + */ + @ApiModelProperty(value = "结束时间",example = "18:00:00") + private String endTime; + + public String getBeginTime() { + return beginTime; + } + + public void setBeginTime(String beginTime) { + this.beginTime = beginTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + @Override + public String toString() { + return "{" + + "beginTime=\"" + beginTime + '\"' + + ", endTime=\"" + endTime + '\"' + + '}'; + } +} diff --git a/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/WsRes.java b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/WsRes.java new file mode 100644 index 0000000..abf585e --- /dev/null +++ b/smartFishingPort-kechuang/src/main/java/com/ltgk/smartFishingPort/websocket/work/entity/WsRes.java @@ -0,0 +1,147 @@ +package com.ltgk.smartFishingPort.websocket.work.entity; + + +import java.util.HashMap; + +/** + * @author chxiaofang + */ +public class WsRes { + + /** + * 消息类型 + */ + private String type; + /** + * 消息对象 + */ + private String target; + private String reason; + private Boolean success; + private String message; + private String dealwith; + private String progress; + private Object data; + + public WsRes() { + //默认处理失败 + this.success = false; + this.reason = ""; + this.dealwith = ""; + this.progress = ""; + this.data = new HashMap(); + } + + public WsRes(String type, Object data, Boolean success) { + //默认处理失败 + this.success = success; + this.reason = ""; + this.dealwith = ""; + this.progress = ""; + this.data = data; + this.type = type; + } + + public static String DEAL_LXYW = "请将错误信息提供给联系运维人员"; + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean succcess) { + this.success = succcess; + } + + public String getDealwith() { + return dealwith; + } + + public void setDealwith(String dealwith) { + this.dealwith = dealwith; + } + + public String getProgress() { + return progress; + } + + public void setProgress(String progress) { + this.progress = progress; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public WsRes success() { + this.success = true; + return this; + } + + public WsRes reason(String reason) { + this.reason += reason; + return this; + } + + public WsRes isSuccess(boolean success) { + this.success = success; + return this; + } + + public WsRes dealwith(String dealwith) { + this.dealwith += dealwith; + return this; + } + + public WsRes progress(String progress) { + this.progress += progress; + return this; + } + + + public WsRes data(Object data) { + this.data = data; + return this; + } + + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public WsRes type(String resType) { + this.type = resType; + return this; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } +} diff --git a/smartFishingPort-kechuang/src/main/resources/mapper/DsVideoMapper.xml b/smartFishingPort-kechuang/src/main/resources/mapper/DsVideoMapper.xml new file mode 100644 index 0000000..6b20c95 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/resources/mapper/DsVideoMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartFishingPort-kechuang/src/main/resources/mapper/VideoIdentificationMapper.xml b/smartFishingPort-kechuang/src/main/resources/mapper/VideoIdentificationMapper.xml new file mode 100644 index 0000000..9a2e0e6 --- /dev/null +++ b/smartFishingPort-kechuang/src/main/resources/mapper/VideoIdentificationMapper.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, identification_type, boat_name, video_name, entey_out, picture_url, boat_code_picture, video_url, take_time, create_by, create_at, update_by, update_at, del_flag, hk_result, sys_ship_name, sys_update_name, system_result, ship_type + + + diff --git a/smartFishingPort-solr/pom.xml b/smartFishingPort-solr/pom.xml index ca01af8..f2a66e0 100644 --- a/smartFishingPort-solr/pom.xml +++ b/smartFishingPort-solr/pom.xml @@ -22,6 +22,13 @@ com.ltgk.smartFishingPort smartFishingPort-common + + + + org.springframework.boot + spring-boot-starter-data-solr + 2.2.0.RELEASE + \ No newline at end of file diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/common/SolrCommon.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/common/SolrCommon.java new file mode 100644 index 0000000..bd71bc8 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/common/SolrCommon.java @@ -0,0 +1,131 @@ +package com.ltgk.smartFishingPort.common; + +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.solr.core.SolrTemplate; +import org.springframework.data.solr.core.query.Query; +import org.springframework.data.solr.core.query.SimpleQuery; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; + +import static javafx.scene.input.KeyCode.T; + +/** + * @Author: wan kun + * @Description: solr 操作类 + * @Date: 2024/9/23 9:22 + * @Version: 1.0 + */ +@Slf4j +@Component +public class SolrCommon { + @Autowired + private SolrTemplate solrTemplate; + + private static SolrCommon solrCommon; + + @PostConstruct + public void init() { + solrCommon = this; + solrCommon.solrTemplate = this.solrTemplate; + } + + /** + * 基础查询 + * + * @param solrController 文档名 + * @param solrQuery 查询条件 + * @param object 返回内容实体类 + * @return + */ + public static Page solrSearchAll(String solrController, String solrQuery, Class object) { + Query queryObject = new SimpleQuery(solrQuery); + Page query = solrCommon.solrTemplate.query(solrController, queryObject, object); + return query; + } + + /** + * 基础查询 + * + * @param solrController + * @param solrQuery + * @param object + * @return + */ + public static Page solrSearchByQuery(String solrController, Query solrQuery, Class object) { + Page query = solrCommon.solrTemplate.query(solrController, solrQuery, object); + return query; + } + + /** + * 创建数据 + * + * @param solrController 文档名 + * @param T 创建内容 + * @return + */ + public static Boolean solrCreate(String solrController, Object T) { + try { + solrCommon.solrTemplate.saveBean(solrController, T); + solrCommon.solrTemplate.commit(solrController); + return true; + } catch (Exception ex) { + log.error("SolrCommon:solrCreate -- solr插入数据失败,请求参数{},失败原因{}", JSONObject.toJSONString(T), ex.getMessage()); + return false; + } + } + + /** + * 删除数据 + * + * @param solrController 文档名 + * @param solrQuery 请求参数 + * @return + */ + public static Boolean solrDelete(String solrController, String solrQuery) { + Query queryObject = new SimpleQuery(solrQuery); + try { + solrCommon.solrTemplate.delete(solrController, queryObject); + solrCommon.solrTemplate.commit(solrController); + return true; + } catch (Exception ex) { + log.error("SolrCommon:solrDelete -- solr删除数据失败,请求参数{},失败原因{}", solrQuery, ex.getMessage()); + return false; + } + } + + public static Boolean solrCreateByList(String solrController, List object) { + try { + solrCommon.solrTemplate.saveBeans(solrController, object); + solrCommon.solrTemplate.commit(solrController); + return true; + } catch (Exception ex) { + log.error("SolrCommon:solrCreateByList -- solr插入数据失败,请求参数{},失败原因{}", JSONObject.toJSONString(T), ex.getMessage()); + return false; + } + } + + public static Boolean solrCreateByList(String solrController, ConcurrentLinkedQueue object) { + try { + solrCommon.solrTemplate.saveBeans(solrController, object); + solrCommon.solrTemplate.commit(solrController); + return true; + } catch (Exception ex) { + log.error("SolrCommon:solrCreateByList -- solr插入数据失败,请求参数{},失败原因{}", JSONObject.toJSONString(T), ex.getMessage()); + return false; + } + } + + public static String getSolrQuerySql(HashMap map) { + if (ObjectUtils.isEmpty(map)) + return null; + return ""; + } +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/config/SolrConfig.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/config/SolrConfig.java new file mode 100644 index 0000000..8826a84 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/config/SolrConfig.java @@ -0,0 +1,21 @@ +package com.ltgk.smartFishingPort.config; + +import org.apache.solr.client.solrj.SolrClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.solr.core.SolrTemplate; + +/** + * @Author: wan kun + * @Description: solr配置类 + * @Date: 2024/9/20 17:40 + * @Version: 1.0 + */ +@Configuration +public class SolrConfig { + + @Bean + public SolrTemplate solrTemplate(SolrClient solrClient) { + return new SolrTemplate(solrClient); + } +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/constant/DataKeyConstant.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/constant/DataKeyConstant.java new file mode 100644 index 0000000..148e14d --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/constant/DataKeyConstant.java @@ -0,0 +1,14 @@ +package com.ltgk.smartFishingPort.constant; + + +/** + * 常量集合 + * + * @author Qi ChengBin + * @date 2025/12/22 + */ +public class DataKeyConstant { + + // solr 集合 + public static final String SOLR_AIS_POINT = "ais_point"; +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/controller/AisSolrController.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/controller/AisSolrController.java new file mode 100644 index 0000000..3c452f0 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/controller/AisSolrController.java @@ -0,0 +1,36 @@ +package com.ltgk.smartFishingPort.controller; + + +import com.ltgk.smartFishingPort.common.core.controller.BaseController; +import com.ltgk.smartFishingPort.common.core.domain.AjaxResult; +import com.ltgk.smartFishingPort.service.ISolrService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * Ais solr 查询数据 + * + * @author Qi ChengBin + * @date 2025/12/25 + */ +@Api(tags = {"solr 中AIS数据查询模块"}) +@RestController +@RequestMapping("/aisSolr") +public class AisSolrController extends BaseController { + + @Resource + ISolrService solrService; + + @ApiOperation(value = "根据mmsi获取 24H 轨迹信息") + @PostMapping("/findAISPointPositionByMmsi") + public AjaxResult findAISPointPositionByMmsi(@ApiParam("mmsi") @RequestParam("mmsi") String mmsi) { + return AjaxResult.success(solrService.findAISPointPositionByMmsi(mmsi)); + } +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/domain/entity/AisSolrEntity.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/domain/entity/AisSolrEntity.java new file mode 100644 index 0000000..7798633 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/domain/entity/AisSolrEntity.java @@ -0,0 +1,103 @@ +package com.ltgk.smartFishingPort.domain.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ltgk.smartFishingPort.constant.DataKeyConstant; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.data.annotation.Id; +import org.springframework.data.solr.core.mapping.Indexed; +import org.springframework.data.solr.core.mapping.SolrDocument; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * 船舶实时动态实体类 + */ +@Data +@SolrDocument(collection = DataKeyConstant.SOLR_AIS_POINT) +@Accessors(chain = true) +public class AisSolrEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @Indexed(name = "id", type = "String") + @ApiModelProperty("主键") + private String id; + + @Indexed(name = "storeLocation", type = "location") + @ApiModelProperty(value = "点位数据存储 latitude,longitude 28.201514412386377,121.12529333335621") + private String storeLocation; + + @Indexed(name = "storeLocation_rpt", type = "location_rpt") + @ApiModelProperty(value = "点位数据存储 latitude,longitude 28.201514412386377,121.12529333335621;用来进行范围查询") + private String storeLocationRpt; + + @ApiModelProperty("当前系统时间,格式:yyyy-MM-dd hh:mm:ss.ms") + @Indexed(name = "time", type = "string") + public String time; + + @ApiModelProperty("uuid") + @Indexed(name = "uuid", type = "string") + private String uuid; + + @ApiModelProperty("设备类型") + @Indexed(name = "deviceType", type = "string") + private String deviceType; + + @ApiModelProperty("终端号码") + @Indexed(name = "terminalCode", type = "string") + private String terminalCode; + + @ApiModelProperty("船名") + @Indexed(name = "boatName", type = "string") + private String boatName; + + @ApiModelProperty("船名英文") + @Indexed(name = "boatNameEn", type = "string") + private String boatNameEn; + + @ApiModelProperty("经度") + @Indexed(name = "longitude", type = "double") + private Double longitude; + + @ApiModelProperty("纬度") + @Indexed(name = "latitude", type = "double") + private Double latitude; + + @ApiModelProperty("船速") + @Indexed(name = "sog", type = "string") + private String sog; + + @ApiModelProperty("航向") + @Indexed(name = "cog", type = "string") + private String cog; + + @ApiModelProperty("船艏向") + @Indexed(name = "heading", type = "string") + private String heading; + + @ApiModelProperty("来源") + @Indexed(name = "dataSource", type = "string") + private String dataSource; + + @ApiModelProperty("报文内容") + @Indexed(name = "msgContent", type = "string") + private String msgContent; + + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty("定位时间") + @Indexed(name = "gpsTime", type = "date") + private Date gpsTime; + + @ApiModelProperty("船长") + @Indexed(name = "boatLength", type = "double") + private Double boatLength; + +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/ISolrService.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/ISolrService.java new file mode 100644 index 0000000..d67e695 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/ISolrService.java @@ -0,0 +1,25 @@ +package com.ltgk.smartFishingPort.service; + +import com.ltgk.smartFishingPort.domain.entity.AisSolrEntity; + +import java.util.List; +import java.util.Map; + +/** + * Solr对应服务 + * + * @author Qi ChengBin + * @date 2025/12/23 + */ +public interface ISolrService { + + /** + * 根据 mmsi 获取AIS 船舶轨迹信息 + * + * @param mmsi: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/23 + */ + Map> findAISPointPositionByMmsi(String mmsi); +} diff --git a/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/impl/SolrServiceImpl.java b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/impl/SolrServiceImpl.java new file mode 100644 index 0000000..51a3a05 --- /dev/null +++ b/smartFishingPort-solr/src/main/java/com/ltgk/smartFishingPort/service/impl/SolrServiceImpl.java @@ -0,0 +1,68 @@ +package com.ltgk.smartFishingPort.service.impl; + + +import cn.hutool.core.date.DateUtil; +import com.ltgk.smartFishingPort.common.SolrCommon; +import com.ltgk.smartFishingPort.common.utils.DateUtils; +import com.ltgk.smartFishingPort.constant.DataKeyConstant; +import com.ltgk.smartFishingPort.domain.entity.AisSolrEntity; +import com.ltgk.smartFishingPort.service.ISolrService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Sort; +import org.springframework.data.solr.core.query.Criteria; +import org.springframework.data.solr.core.query.SimpleQuery; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Solr 服务实现 + * + * @author Qi ChengBin + * @date 2025/12/23 + */ +@Slf4j +@Service +public class SolrServiceImpl implements ISolrService { + + /** + * 根据 mmsi 获取AIS 船舶轨迹信息 + * + * @param mmsi: + * @return ltgk.pm.video.base.Response + * @author Qi ChengBin + * @date 2025/12/23 + */ + @Override + public Map> findAISPointPositionByMmsi(String mmsi) { + Date nowDate = new Date(); + // 查询 24H 内的 mmsi 的数据 + String now = DateUtil.formatDateTime(nowDate); + // 24小时之前的时间 before24HStr + String before24HStr = DateUtil.offsetHour(nowDate, -24).toString("yyyy-MM-dd HH:mm:ss"); + + // 查询 solr 获取相关的轨迹 + Criteria criteria = new Criteria("terminalCode") + .is(mmsi) + .and("gpsTime") + .between(DateUtils.toDate(before24HStr), DateUtils.toDate(now)); + SimpleQuery query = new SimpleQuery(criteria); + query.addSort(Sort.by(Sort.Direction.DESC, "gpsTime")); + query.setRows(100000); + Page page = SolrCommon.solrSearchByQuery(DataKeyConstant.SOLR_AIS_POINT, query, AisSolrEntity.class); + + // key 为 目标id value 为 尾迹的数据 resAisSolrList + List resAisSolrList = new ArrayList<>(); + for (Object item : page.getContent()) { + resAisSolrList.add((AisSolrEntity) item); + } + + return resAisSolrList.stream() + .collect(Collectors.groupingBy(AisSolrEntity::getTerminalCode)); + } +}