diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml index 81341e37..5fa9cd10 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml @@ -49,7 +49,7 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) - url: jdbc:mysql://192.168.110.126:3306/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mysql://192.168.110.119:3306/xinnengyuan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 123456 # # 从库数据源 @@ -273,5 +273,8 @@ weather: dxf2GeoJson: file-name: main.exe ys7: - app-key: "f01490bd5d5241b7809d8fc5fe84f7f8" - app-secret: "d468f270699de855fd85fe7fd6f9595f" + app-key: 3acf9f1a43dc4209841e0893003db0a2 + app-secret: 4bbf3e9394f55d3af6e3af27b2d3db36 +#ys7: +# app-key: f01490bd5d5241b7809d8fc5fe84f7f8 +# app-secret: d468f270699de855fd85fe7fd6f9595f diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml index 9f07d5aa..567c2a2e 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml @@ -275,5 +275,5 @@ weather: dxf2GeoJson: file-name: main ys7: - app-key: "f01490bd5d5241b7809d8fc5fe84f7f8" - app-secret: "d468f270699de855fd85fe7fd6f9595f" + app-key: xx + app-secret: xx diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml index 96c7c3c0..ddf45424 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml @@ -120,6 +120,8 @@ security: - /*/api-docs - /*/api-docs/** - /warm-flow-ui/token-name + - /other/ys7Device/webhook + - /other/ys7Device/test # 多租户配置 tenant: diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java new file mode 100644 index 00000000..8df18a5e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java @@ -0,0 +1,40 @@ +package org.dromara.job.cycle; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.dromara.manager.ys7manager.Ys7Manager; +import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; +import org.dromara.other.service.IOthYs7DeviceService; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author lcj + * @date 2025/6/17 9:33 + */ +@Slf4j +@Component +public class IncSyncYs7DeviceData { + + @Resource + private Ys7Manager ys7Manager; + + @Resource + private IOthYs7DeviceService ys7DeviceService; + + // 每 5 分钟执行一次 + @Scheduled(cron = "0 */5 * * * ?") + public void run() { + log.info("定时同步摄像头设备数据"); + List ys7QueryDeviceList = ys7Manager.queryAllDeviceList(); + Boolean result = ys7DeviceService.saveOrUpdateByDeviceList(ys7QueryDeviceList); + if (result) { + log.info("定时同步摄像头设备数据成功"); + } else { + log.info("没有需要定时同步的设备"); + } + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java index 449062d7..c4a0de42 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java @@ -15,7 +15,7 @@ import java.util.List; * @date 2025/6/13 11:08 */ @Slf4j -//@Component +@Component public class FullSyncYs7DeviceData implements CommandLineRunner { @Resource diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java index 7720c052..65548b13 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java @@ -16,6 +16,11 @@ public interface Ys7Constant { */ Integer MAX_PAGE_SIZE = 50; + /** + * 设备在线状态类型 + */ + String ON_OFF_LINE_TOPIC_TYPE = "ys.onoffline"; + /** * 获取 token 请求地址 Post */ @@ -30,4 +35,19 @@ public interface Ys7Constant { * 修改设备名称请求地址 Post */ String updateDeviceNameUrlByPost = "https://open.ys7.com/api/lapp/device/name/update"; + + /** + * 添加设备预置点请求地址 Post + */ + String addDevicePresetUrlByPost = "https://open.ys7.com/api/lapp/device/preset/add"; + + /** + * 调用设备预置点请求地址 Post + */ + String moveDevicePresetUrlByPost = "https://open.ys7.com/api/lapp/device/preset/move"; + + /** + * 清除设备预置点请求地址 Post + */ + String deleteDevicePresetUrlByPost = "https://open.ys7.com/api/lapp/device/preset/clear"; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java index 3d9af76d..8ad95d51 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java @@ -65,4 +65,50 @@ public class Ys7Manager { stringRedisTemplate.opsForValue().set(tokenRedisKey, newToken, 6, TimeUnit.DAYS); return newToken; } + + /** + * 更新设备名称 + * + * @param deviceSerial 设备序列号 + * @param deviceName 设备名称 + * @return 是否成功 + */ + public Boolean updateDeviceName(String deviceSerial, String deviceName) { + return Ys7RequestUtils.updateDeviceName(getToken(), deviceSerial, deviceName); + } + + /** + * 添加设备预置点 + * + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @return 预置点编号 + */ + public Integer addDevicePreset(String deviceSerial, int channelNo) { + return Ys7RequestUtils.addDevicePreset(getToken(), deviceSerial, channelNo); + } + + /** + * 移动设备预置点 + * + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @param index 预置点编号 + * @return 是否成功 + */ + public Boolean moveDevicePreset(String deviceSerial, int channelNo, int index) { + return Ys7RequestUtils.moveDevicePreset(getToken(), deviceSerial, channelNo, index); + } + + /** + * 删除设备预置点 + * + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @param index 预置点编号 + * @return 是否成功 + */ + public Boolean deleteDevicePreset(String deviceSerial, int channelNo, int index) { + return Ys7RequestUtils.deleteDevicePreset(getToken(), deviceSerial, channelNo, index); + } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java index ecb10533..a6015e34 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java @@ -1,6 +1,5 @@ package org.dromara.manager.ys7manager; -import cn.hutool.core.lang.Validator; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.json.JSONObject; @@ -75,7 +74,7 @@ public class Ys7RequestUtils { paramMap.put("accessToken", accessToken); paramMap.put("pageStart", pageStart); paramMap.put("pageSize", pageSize); - String errorMsg = String.format("Ys7 分页查询设备列表 第%s页大小%s 请求失败", (pageStart + 1), pageSize); + String errorMsg = String.format("Ys7 分页查询设备列表 第%s页大小%s 请求失败", pageStart, pageSize); try (HttpResponse response = HttpRequest.post(Ys7Constant.queryDevicePageUrlByPost) .form(paramMap) .execute()) { @@ -89,7 +88,8 @@ public class Ys7RequestUtils { log.error("{}:{}", errorMsg, responseVo.getMsg()); throw new ServiceException(errorMsg + responseVo.getMsg()); } - log.info("Ys7 分页查询设备列表 第{}页大小{} 请求成功:{}", (pageStart + 1), pageSize, body); + log.info("Ys7 分页查询设备列表 第{}页大小{} 响应数据:{}", pageStart, pageSize, responseVo.getData()); + log.info("Ys7 分页查询设备列表 第{}页大小{} 请求成功:{}", pageStart, pageSize, responseVo.getPage()); return JSONUtil.toList(responseVo.getData(), Ys7QueryDeviceResponseVo.class); } } @@ -110,9 +110,6 @@ public class Ys7RequestUtils { if (deviceName.length() > 50) { throw new ServiceException("设备名称长度不能超过50个字符", HttpStatus.BAD_REQUEST); } - if (!Validator.isGeneralWithChinese(deviceName)) { - throw new ServiceException("设备名称不能包含特殊字符", HttpStatus.BAD_REQUEST); - } // 组合请求体 HashMap paramMap = new HashMap<>(); paramMap.put("accessToken", accessToken); @@ -138,4 +135,118 @@ public class Ys7RequestUtils { } } + /** + * 添加设备预置位 + * + * @param accessToken accessToken + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @return 预置点序号 + */ + public static int addDevicePreset(String accessToken, String deviceSerial, int channelNo) { + if (StringUtils.isAnyBlank(accessToken, deviceSerial)) { + throw new ServiceException("添加设备预置位参数为空", HttpStatus.BAD_REQUEST); + } + HashMap paramMap = new HashMap<>(); + paramMap.put("accessToken", accessToken); + paramMap.put("deviceSerial", deviceSerial); + paramMap.put("channelNo", channelNo); + String errorMsg = "添加设备预置位请求失败"; + try (HttpResponse response = HttpRequest.post(Ys7Constant.addDevicePresetUrlByPost) + .form(paramMap) + .execute()) { + if (!response.isOk()) { + log.error("{}:{}", errorMsg, response.getStatus()); + throw new ServiceException(errorMsg + response.getStatus()); + } + String body = response.body(); + Ys7ResponseVo responseVo = JSONUtil.toBean(body, Ys7ResponseVo.class); + if (!responseVo.getCode().equals("200")) { + log.error("{}:{}", errorMsg, responseVo.getMsg()); + throw new ServiceException(errorMsg + responseVo.getMsg()); + } + // 获取 data 中的 index + String data = responseVo.getData(); + // 解析为 JSONObject + JSONObject jsonObject = JSONUtil.parseObj(data); + Integer index = jsonObject.getInt("index"); + log.info("添加设备预置位请求成功,设备 {} 添加预置点成功,通道:{},序号 {}", deviceSerial, channelNo, index); + return index; + } + } + + /** + * 调用设备预置点 + * + * @param accessToken accessToken + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @param index 预置点序号 + * @return 是否调用成功 + */ + public static Boolean moveDevicePreset(String accessToken, String deviceSerial, int channelNo, int index) { + if (StringUtils.isAnyBlank(accessToken, deviceSerial)) { + throw new ServiceException("调用设备预置点参数为空", HttpStatus.BAD_REQUEST); + } + HashMap paramMap = new HashMap<>(); + paramMap.put("accessToken", accessToken); + paramMap.put("deviceSerial", deviceSerial); + paramMap.put("channelNo", channelNo); + paramMap.put("index", index); + String errorMsg = "调用设备预置点请求失败"; + try (HttpResponse response = HttpRequest.post(Ys7Constant.moveDevicePresetUrlByPost) + .form(paramMap) + .execute()) { + if (!response.isOk()) { + log.error("{}:{}", errorMsg, response.getStatus()); + throw new ServiceException(errorMsg + response.getStatus()); + } + String body = response.body(); + Ys7NoDataResponseVo responseVo = JSONUtil.toBean(body, Ys7NoDataResponseVo.class); + if (!responseVo.getCode().equals("200")) { + log.error("{}:{}", errorMsg, responseVo.getMsg()); + throw new ServiceException(errorMsg + responseVo.getMsg()); + } + log.info("调用设备预置点请求成功,设备 {} 调用预置点成功,通道:{},序号 {}", deviceSerial, channelNo, index); + return true; + } + } + + /** + * 删除设备预置点 + * + * @param accessToken accessToken + * @param deviceSerial 设备序列号 + * @param channelNo 通道号 + * @param index 预置点序号 + * @return 是否删除成功 + */ + public static Boolean deleteDevicePreset(String accessToken, String deviceSerial, int channelNo, int index) { + if (StringUtils.isAnyBlank(accessToken, deviceSerial)) { + throw new ServiceException("删除设备预置点参数为空", HttpStatus.BAD_REQUEST); + } + HashMap paramMap = new HashMap<>(); + paramMap.put("accessToken", accessToken); + paramMap.put("deviceSerial", deviceSerial); + paramMap.put("channelNo", channelNo); + paramMap.put("index", index); + String errorMsg = "删除设备预置点请求失败"; + try (HttpResponse response = HttpRequest.post(Ys7Constant.deleteDevicePresetUrlByPost) + .form(paramMap) + .execute()) { + if (!response.isOk()) { + log.error("{}:{}", errorMsg, response.getStatus()); + throw new ServiceException(errorMsg + response.getStatus()); + } + String body = response.body(); + Ys7NoDataResponseVo responseVo = JSONUtil.toBean(body, Ys7NoDataResponseVo.class); + if (!responseVo.getCode().equals("200")) { + log.error("{}:{}", errorMsg, responseVo.getMsg()); + throw new ServiceException(errorMsg + responseVo.getMsg()); + } + log.info("删除设备预置点请求成功,设备 {} 删除预置点成功,通道:{},序号 {}", deviceSerial, channelNo, index); + return true; + } + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/enums/DeviceOnOffLineEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/enums/DeviceOnOffLineEnum.java new file mode 100644 index 00000000..44c2bad1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/enums/DeviceOnOffLineEnum.java @@ -0,0 +1,24 @@ +package org.dromara.manager.ys7manager.enums; + +import lombok.Getter; + +/** + * @author lcj + * @date 2025/6/17 15:36 + */ +@Getter +public enum DeviceOnOffLineEnum { + + ONLINE("设备上线消息", "ONLINE"), + OFFLINE("设备离线消息", "OFFLINE"); + + private final String text; + + private final String value; + + DeviceOnOffLineEnum(String text, String value) { + this.text = text; + this.value = value; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java index c00c28d6..69865e1d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java @@ -3,7 +3,6 @@ package org.dromara.other.controller; import cn.dev33.satoken.annotation.SaCheckPermission; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.AddGroup; @@ -93,16 +92,29 @@ public class OthDevicePresetController extends BaseController { return toAjax(othDevicePresetService.updateByBo(req)); } + /** + * 调用摄像头预置位 + * + * @param id 主键 + */ + @SaCheckPermission("other:devicePreset:edit") + @Log(title = "摄像头预置位", businessType = BusinessType.UPDATE) + @PutMapping("/move/{id}") + public R move(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return toAjax(othDevicePresetService.moveById(id)); + } + /** * 删除摄像头预置位 * - * @param ids 主键串 + * @param id 主键串 */ @SaCheckPermission("other:devicePreset:remove") @Log(title = "摄像头预置位", businessType = BusinessType.DELETE) - @DeleteMapping("/{ids}") - public R remove(@NotEmpty(message = "主键不能为空") - @PathVariable Long[] ids) { - return toAjax(othDevicePresetService.deleteWithValidByIds(List.of(ids), true)); + @DeleteMapping("/{id}") + public R remove(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return toAjax(othDevicePresetService.deleteById(id)); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java index c90b7413..8151ca2c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java @@ -1,10 +1,12 @@ package org.dromara.other.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.json.JSONUtil; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.validate.EditGroup; import org.dromara.common.excel.utils.ExcelUtil; @@ -15,16 +17,17 @@ import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.web.core.BaseController; import org.dromara.manager.ys7manager.Ys7Manager; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceQueryReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateEncryptedReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceWithProjectReq; +import org.dromara.other.domain.dto.ys7device.*; import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo; import org.dromara.other.service.IOthYs7DeviceService; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 萤石摄像头 @@ -32,6 +35,7 @@ import java.util.List; * @author lcj * @date 2025-06-13 */ +@Slf4j @Validated @RestController @RequestMapping("/other/ys7Device") @@ -127,6 +131,29 @@ public class OthYs7DeviceController extends BaseController { @SaCheckPermission("other:ys7Device:query") @GetMapping("/get/token") public R getToken() { - return R.ok(ys7Manager.getToken()); + return R.ok("操作成功", ys7Manager.getToken()); + } + + @RequestMapping(value = "/webhook") + public ResponseEntity webhook(@RequestHeader HttpHeaders header, @RequestBody String body) { + WebhookMessage receiveMessage; + log.info("消息获取时间:{}, 请求头:{},请求体:{}", System.currentTimeMillis(), JSONUtil.toJsonStr(header), body); + System.out.println("收到的消息:" + body); + receiveMessage = JSONUtil.toBean(body, WebhookMessage.class); + // todo:对收到的消息进行处理,最好发送到其他中间件,或者写到数据库中,不要影响回调地址的处理 + othYs7DeviceService.webhook(receiveMessage); + // 必须进行返回 + Map result = new HashMap<>(1); + assert receiveMessage != null; + String messageId = receiveMessage.getHeader().getMessageId(); + result.put("messageId", messageId); + final ResponseEntity resp = ResponseEntity.ok(JSONUtil.toJsonStr(result)); + log.info("返回的信息:{}", JSONUtil.toJsonStr(result)); + return resp; + } + + @RequestMapping(value = "/test") + public R test() { + return R.ok("操作成功", "测试成功"); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java index f174f87e..77ba9ad2 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java @@ -35,17 +35,17 @@ public class OthDevicePreset implements Serializable { /** * 通道号 */ - private Long channelNo; + private Integer channelNo; /** * 预置点序号 */ - private Long index; + private Integer presetIndex; /** * 预置点 */ - private String name; + private String presetName; /** * 创建时间 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java index 2301924f..6d80a6c0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java @@ -1,7 +1,6 @@ package org.dromara.other.domain; import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -103,15 +102,4 @@ public class OthYs7Device implements Serializable { */ private Date updateTime; - /** - * 删除时间 - */ - private Date deletedAt; - - /** - * 是否删除(0正常 1删除) - */ - @TableLogic - private Integer isDelete; - } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java index 8eacc89b..45e0ebb6 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java @@ -25,16 +25,11 @@ public class OthDevicePresetCreateReq implements Serializable { /** * 通道号 */ - private Long channelNo; - - /** - * 预置点序号 - */ - private Long index; + private Integer channelNo; /** * 预置点 */ - private String name; + private String presetName; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java index 68400147..834d9207 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java @@ -25,16 +25,16 @@ public class OthDevicePresetQueryReq implements Serializable { /** * 通道号 */ - private Long channelNo; + private Integer channelNo; /** * 预置点序号 */ - private Long index; + private Integer presetIndex; /** * 预置点 */ - private String name; + private String presetName; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java index 7184e911..16f3120c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java @@ -22,19 +22,10 @@ public class OthDevicePresetUpdateReq implements Serializable { @NotNull(message = "主键id不能为空") private Long id; - /** - * 通道号 - */ - private Long channelNo; - - /** - * 预置点序号 - */ - private Long index; - /** * 预置点 */ - private String name; + @NotNull(message = "预置点名称不能为空") + private String presetName; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java index c95fcfe9..f176b9e0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java @@ -20,11 +20,6 @@ public class OthYs7DeviceUpdateReq implements Serializable { */ private Long id; - /** - * 项目id - */ - private Long projectId; - /** * 设备名称 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java index dc2c913e..e7e6411f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java @@ -5,6 +5,7 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; +import java.util.List; /** * @author lcj @@ -20,7 +21,7 @@ public class OthYs7DeviceWithProjectReq implements Serializable { * 主键 */ @NotNull(message = "主键不能为空") - private Long id; + private List id; /** * 项目id diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/WebhookMessage.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/WebhookMessage.java new file mode 100644 index 00000000..90013fc4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/WebhookMessage.java @@ -0,0 +1,63 @@ +package org.dromara.other.domain.dto.ys7device; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/17 11:30 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WebhookMessage implements Serializable { + + @Serial + private static final long serialVersionUID = -3462174422247941389L; + + /** + * 消息头 + */ + private WebhookMessageHeader header; + + /** + * 消息体 + */ + private Object body; + + @Data + @NoArgsConstructor + public static class WebhookMessageHeader { + + /** + * 消息id + */ + private String messageId; + + /** + * 设备序列号 + */ + private String deviceId; + + /** + * 消息类型,需向消息管道服务申请 + */ + private String type; + + /** + * 通道号 + */ + private Integer channelNo; + + /** + * 消息推送时间 + */ + private Long messageTime; + + } +} + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthDeviceStatusEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthDeviceStatusEnum.java new file mode 100644 index 00000000..275280f4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthDeviceStatusEnum.java @@ -0,0 +1,34 @@ +package org.dromara.other.domain.enums; + +import lombok.Getter; + +/** + * @author lcj + * @date 2025/6/17 10:54 + */ +@Getter +public enum OthDeviceStatusEnum { + + ONLINE("在线", 1), + OFFLINE("离线", 0); + + private final String text; + + private final int value; + + OthDeviceStatusEnum(String text, int value) { + this.text = text; + this.value = value; + } + + // 根据 value 获取对应的 text + public static String getTextByValue(int value) { + for (OthDeviceStatusEnum type : values()) { + if (type.getValue() == value) { + return type.getText(); + } + } + return null; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java index 32083b91..477fef0b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java @@ -40,18 +40,18 @@ public class OthDevicePresetVo implements Serializable { * 通道号 */ @ExcelProperty(value = "通道号") - private Long channelNo; + private Integer channelNo; /** * 预置点序号 */ @ExcelProperty(value = "预置点序号") - private Long index; + private Integer presetIndex; /** * 预置点 */ @ExcelProperty(value = "预置点") - private String name; + private String presetName; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java index baca7d36..c7ff50b7 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java @@ -11,7 +11,6 @@ import org.dromara.other.domain.dto.devicepreset.OthDevicePresetQueryReq; import org.dromara.other.domain.dto.devicepreset.OthDevicePresetUpdateReq; import org.dromara.other.domain.vo.devicepreset.OthDevicePresetVo; -import java.util.Collection; import java.util.List; /** @@ -63,14 +62,21 @@ public interface IOthDevicePresetService extends IService { */ Boolean updateByBo(OthDevicePresetUpdateReq req); + /** + * 调用摄像头预置位 + * + * @param id 摄像头预置位id + * @return 是否调用成功 + */ + Boolean moveById(Long id); + /** * 校验并批量删除摄像头预置位信息 * - * @param ids 待删除的主键集合 - * @param isValid 是否进行有效性校验 + * @param id 待删除的主键 * @return 是否删除成功 */ - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + Boolean deleteById(Long id); /** * 获取摄像头预置位视图 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java index 2dd67fb3..0a3d8713 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java @@ -7,10 +7,7 @@ import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; import org.dromara.other.domain.OthYs7Device; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceQueryReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateEncryptedReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceWithProjectReq; +import org.dromara.other.domain.dto.ys7device.*; import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo; import java.util.Collection; @@ -130,4 +127,10 @@ public interface IOthYs7DeviceService extends IService { */ Boolean saveOrUpdateByDeviceList(List deviceResponseVoList); + /** + * 萤石摄像头webhook + * + * @param receiveMessage 接收消息 + */ + void webhook(WebhookMessage receiveMessage); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java index c670f163..3cfcfe20 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java @@ -11,19 +11,22 @@ import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.manager.ys7manager.Ys7Manager; import org.dromara.other.domain.OthDevicePreset; import org.dromara.other.domain.OthYs7Device; import org.dromara.other.domain.dto.devicepreset.OthDevicePresetCreateReq; import org.dromara.other.domain.dto.devicepreset.OthDevicePresetQueryReq; import org.dromara.other.domain.dto.devicepreset.OthDevicePresetUpdateReq; +import org.dromara.other.domain.enums.OthDeviceStatusEnum; import org.dromara.other.domain.vo.devicepreset.OthDevicePresetVo; import org.dromara.other.mapper.OthDevicePresetMapper; import org.dromara.other.service.IOthDevicePresetService; import org.dromara.other.service.IOthYs7DeviceService; +import org.dromara.project.service.IBusProjectService; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; -import java.util.Collection; import java.util.List; /** @@ -39,6 +42,12 @@ public class OthDevicePresetServiceImpl extends ServiceImpl ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 + public Boolean deleteById(Long id) { + Long userId = LoginHelper.getUserId(); + OthDevicePreset devicePreset = this.getById(id); + String deviceSerial = devicePreset.getDeviceSerial(); + OthYs7Device device = othYs7DeviceService.lambdaQuery() + .eq(OthYs7Device::getDeviceSerial, deviceSerial) + .one(); + if (device == null) { + throw new ServiceException("设备不存在", HttpStatus.BAD_REQUEST); } - return baseMapper.deleteByIds(ids) > 0; + Long projectId = device.getProjectId(); + if (projectId != 0) { + projectService.validAuth(projectId, userId); + } + Boolean result = ys7Manager.deleteDevicePreset( + deviceSerial, + devicePreset.getChannelNo(), + devicePreset.getPresetIndex()); + if (!result) { + throw new ServiceException("删除摄像头预置位信息失败", HttpStatus.ERROR); + } + return this.removeById(id); } /** @@ -181,13 +249,13 @@ public class OthDevicePresetServiceImpl extends ServiceImpl buildQueryWrapper(OthDevicePresetQueryReq req) { LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); String deviceSerial = req.getDeviceSerial(); - Long channelNo = req.getChannelNo(); - Long index = req.getIndex(); - String name = req.getName(); + Integer channelNo = req.getChannelNo(); + Integer index = req.getPresetIndex(); + String name = req.getPresetName(); lqw.eq(StringUtils.isNotBlank(deviceSerial), OthDevicePreset::getDeviceSerial, deviceSerial); lqw.eq(ObjectUtils.isNotEmpty(channelNo), OthDevicePreset::getChannelNo, channelNo); - lqw.eq(ObjectUtils.isNotEmpty(index), OthDevicePreset::getIndex, index); - lqw.like(StringUtils.isNotBlank(name), OthDevicePreset::getName, name); + lqw.eq(ObjectUtils.isNotEmpty(index), OthDevicePreset::getPresetIndex, index); + lqw.like(StringUtils.isNotBlank(name), OthDevicePreset::getPresetName, name); return lqw; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java index 32eb1807..9dbdf7a8 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java @@ -1,6 +1,8 @@ package org.dromara.other.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -13,14 +15,13 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.manager.ys7manager.Ys7Constant; import org.dromara.manager.ys7manager.Ys7Manager; -import org.dromara.manager.ys7manager.Ys7RequestUtils; +import org.dromara.manager.ys7manager.enums.DeviceOnOffLineEnum; import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; import org.dromara.other.domain.OthYs7Device; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceQueryReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateEncryptedReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceUpdateReq; -import org.dromara.other.domain.dto.ys7device.OthYs7DeviceWithProjectReq; +import org.dromara.other.domain.dto.ys7device.*; +import org.dromara.other.domain.enums.OthDeviceStatusEnum; import org.dromara.other.domain.enums.OthVideoEncryptedEnum; import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo; import org.dromara.other.mapper.OthYs7DeviceMapper; @@ -109,7 +110,6 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl 0) { throw new ServiceException("已存在同名萤石摄像头", HttpStatus.CONFLICT); } - String token = ys7Manager.getToken(); - Boolean result = Ys7RequestUtils.updateDeviceName(token, oldYs7Device.getDeviceSerial(), deviceName); + Boolean result = ys7Manager.updateDeviceName(oldYs7Device.getDeviceSerial(), deviceName); if (!result) { throw new ServiceException("更新云端萤石摄像头名称异常", HttpStatus.ERROR); } @@ -140,14 +139,14 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl ids = req.getId(); Long projectId = req.getProjectId(); // 参数校验 - if (id == null || projectId == null) { + if (CollUtil.isEmpty(ids) || projectId == null) { throw new ServiceException("参数为空", HttpStatus.BAD_REQUEST); } - OthYs7Device ys7Device = this.getById(id); - if (ys7Device == null) { + List ys7DeviceList = this.listByIds(ids); + if (CollUtil.isEmpty(ys7DeviceList)) { throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND); } BusProject project = projectService.getById(projectId); @@ -159,7 +158,7 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl ids, Boolean isValid) { + Long userId = LoginHelper.getUserId(); + List deviceList = this.listByIds(ids); if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 + // TODO 做一些业务上的校验,判断是否需要校验 + List projectIds = deviceList.stream() + .map(OthYs7Device::getProjectId) + .filter(id -> id != 0) + .distinct() + .toList(); + if (CollUtil.isNotEmpty(projectIds)) { + projectService.validAuth(projectIds, userId); + } } - return baseMapper.deleteByIds(ids) > 0; + return this.removeBatchByIds(ids); } /** @@ -268,15 +265,17 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl w + .eq(OthYs7Device::getProjectId, projectId) .or() - .eq(OthYs7Device::getProjectId, 0L); + .eq(OthYs7Device::getProjectId, 0L)); lqw.eq(ObjectUtils.isNotEmpty(status), OthYs7Device::getStatus, status); lqw.like(StringUtils.isNotBlank(deviceName), OthYs7Device::getDeviceName, deviceName); lqw.like(StringUtils.isNotBlank(deviceType), OthYs7Device::getDeviceType, deviceType); lqw.like(StringUtils.isNotBlank(deviceSerial), OthYs7Device::getDeviceSerial, deviceSerial); lqw.like(StringUtils.isNotBlank(deviceVersion), OthYs7Device::getDeviceVersion, deviceVersion); lqw.orderByDesc(OthYs7Device::getProjectId); + lqw.orderByDesc(OthYs7Device::getStatus); return lqw; } @@ -336,7 +335,6 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl deviceList = this.getEntityList(deviceResponseVoList); + if (CollUtil.isEmpty(deviceList)) { + return false; + } // 查询数据库中的数据并构建 Map Map entityMap = this.list().stream() .collect(Collectors.toMap( @@ -381,6 +382,11 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl resultList = deviceList.stream() + .filter(device -> { + OthYs7Device existing = entityMap.get(device.getDeviceSerial()); + // 若已有记录且未发生变化,则过滤掉 + return existing == null || !validDeviceUpdate(existing, device); + }) .peek(device -> { OthYs7Device existing = entityMap.get(device.getDeviceSerial()); if (existing != null) { @@ -399,9 +405,59 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl