From 784c7c0783cf794c0f6639d68ef134ec4f17745e Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Fri, 13 Jun 2025 18:28:31 +0800 Subject: [PATCH] =?UTF-8?q?[add]=20=E6=8E=A5=E5=85=A5=E8=90=A4=E7=9F=B3?= =?UTF-8?q?=E6=91=84=E5=83=8F=E5=A4=B4=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=AD=90?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=92=8C=E6=91=84=E5=83=8F=E5=A4=B4=E9=A2=84?= =?UTF-8?q?=E7=BD=AE=E4=BD=8D=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91=20[updat?= =?UTF-8?q?e]=20=E4=BF=AE=E6=94=B9geojson=E4=B8=AD=E6=96=B9=E9=98=B5?= =?UTF-8?q?=E7=AD=89=E9=87=8D=E6=96=B0=E4=B8=8A=E4=BC=A0=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 11 +- .../src/main/resources/application-prod.yml | 7 +- .../src/main/resources/application.yml | 6 +- .../test/java/org/dromara/test/Ys7Test.java | 29 ++ .../web/handler/GlobalExceptionHandler.java | 16 +- .../constant/FacRedisKeyConstant.java | 73 +++- .../domain/dto/geojson/FacFeatureByLine.java | 22 - .../domain/dto/geojson/FacFeatureByPlane.java | 8 +- .../domain/dto/geojson/FacGeoJsonByLine.java | 25 -- .../domain/dto/geojson/FacGeometryByLine.java | 24 -- .../dto/geojson/FacGeometryByPlane.java | 7 +- ...acPhotovoltaicPanelCreateByGeoJsonReq.java | 15 + .../vo/matrix/FacMatrixBySubProjectVo.java | 28 ++ .../impl/FacBoxTransformerServiceImpl.java | 4 +- .../service/impl/FacInverterServiceImpl.java | 4 +- .../service/impl/FacMatrixServiceImpl.java | 41 +- .../FacPhotovoltaicPanelPartsServiceImpl.java | 40 +- .../impl/FacPhotovoltaicPanelServiceImpl.java | 364 +++++++++------- .../job/once/FullSyncYs7DeviceData.java | 38 ++ .../manager/ys7manager/Ys7Constant.java | 33 ++ .../manager/ys7manager/Ys7Manager.java | 68 +++ .../manager/ys7manager/Ys7Properties.java | 26 ++ .../manager/ys7manager/Ys7RequestUtils.java | 141 ++++++ .../ys7manager/vo/Ys7NoDataResponseVo.java | 22 + .../ys7manager/vo/Ys7PageResponseVo.java | 32 ++ .../vo/Ys7QueryDeviceResponseVo.java | 72 ++++ .../manager/ys7manager/vo/Ys7ResponseVo.java | 27 ++ .../controller/OthDevicePresetController.java | 108 +++++ .../controller/OthYs7DeviceController.java | 132 ++++++ .../dromara/other/domain/OthDevicePreset.java | 60 +++ .../dromara/other/domain/OthYs7Device.java | 117 +++++ .../OthDevicePresetCreateReq.java | 40 ++ .../devicepreset/OthDevicePresetQueryReq.java | 40 ++ .../OthDevicePresetUpdateReq.java | 40 ++ .../dto/ys7device/OthYs7DeviceQueryReq.java | 48 +++ .../OthYs7DeviceUpdateEncryptedReq.java | 28 ++ .../dto/ys7device/OthYs7DeviceUpdateReq.java | 48 +++ .../ys7device/OthYs7DeviceWithProjectReq.java | 31 ++ .../domain/enums/OthVideoEncryptedEnum.java | 34 ++ .../vo/devicepreset/OthDevicePresetVo.java | 57 +++ .../domain/vo/ys7device/OthYs7DeviceVo.java | 93 ++++ .../other/mapper/OthDevicePresetMapper.java | 15 + .../other/mapper/OthYs7DeviceMapper.java | 15 + .../service/IOthDevicePresetService.java | 98 +++++ .../other/service/IOthYs7DeviceService.java | 133 ++++++ .../impl/OthDevicePresetServiceImpl.java | 214 +++++++++ .../service/impl/OthYs7DeviceServiceImpl.java | 407 ++++++++++++++++++ .../constant/PgsProgressCategoryConstant.java | 5 + .../progress/domain/PgsProgressCategory.java | 18 +- .../PgsProgressCategoryMatrixVo.java | 5 + .../PgsProgressCategoryProjectVo.java | 5 + .../PgsProgressCategorySubProjectVo.java | 5 + .../service/IPgsProgressCategoryService.java | 8 +- .../impl/PgsProgressCategoryServiceImpl.java | 138 +++++- .../PgsProgressPlanDetailServiceImpl.java | 5 +- .../controller/BusProjectController.java | 10 + .../vo/project/BusSubProjectMatrixVo.java | 35 ++ .../project/service/IBusProjectService.java | 8 + .../service/impl/BusProjectServiceImpl.java | 73 +++- .../mapper/other/OthDevicePresetMapper.xml | 7 + .../mapper/other/OthYs7DeviceMapper.xml | 7 + xinnengyuan/script/sql/menuInitValue.sql | 40 ++ xinnengyuan/script/sql/xinnengyuan.sql | 103 +++-- 63 files changed, 3072 insertions(+), 341 deletions(-) create mode 100644 xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/Ys7Test.java delete mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByLine.java delete mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeoJsonByLine.java delete mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByLine.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/vo/matrix/FacMatrixBySubProjectVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Properties.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7NoDataResponseVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7PageResponseVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7QueryDeviceResponseVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7ResponseVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceQueryReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateEncryptedReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthVideoEncryptedEnum.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/ys7device/OthYs7DeviceVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthDevicePresetMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthYs7DeviceMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/project/BusSubProjectMatrixVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthDevicePresetMapper.xml create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthYs7DeviceMapper.xml diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml index e3ead3e8..81341e37 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-dev.yml @@ -98,13 +98,13 @@ spring: spring.data: redis: # 地址 - host: 192.168.110.126 + host: 192.168.110.2 # 端口,默认为6379 - port: 6379 + port: 9287 # 数据库索引 - database: 1 + database: 10 # redis 密码必须配置 - password: 123456 + password: syar23rdsaagdrsa # 连接超时时间 timeout: 10s # 是否开启ssl @@ -272,3 +272,6 @@ weather: # dxf转 geojson 执行文件名 dxf2GeoJson: file-name: main.exe +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 fac878eb..9f07d5aa 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-prod.yml @@ -103,9 +103,9 @@ spring.data: # 地址 host: 192.168.110.2 # 端口,默认为6379 - port: 6379 + port: 63079 # 数据库索引 - database: 1 + database: 5 # redis 密码必须配置 password: HMASKEbyhaASPZXB # 连接超时时间 @@ -274,3 +274,6 @@ weather: # dxf转 geojson 执行文件名 dxf2GeoJson: file-name: main +ys7: + app-key: "f01490bd5d5241b7809d8fc5fe84f7f8" + app-secret: "d468f270699de855fd85fe7fd6f9595f" diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml index 72dfa4ec..96c7c3c0 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml @@ -228,9 +228,11 @@ springdoc: packages-to-scan: org.dromara.facility - group: 9.进度模块 packages-to-scan: org.dromara.progress - - group: 10.代码生成模块 + - group: 10.其他模块 + packages-to-scan: org.dromara.other + - group: 11.代码生成模块 packages-to-scan: org.dromara.generator - - group: 11.工作流模块 + - group: 12.工作流模块 packages-to-scan: org.dromara.workflow # 防止XSS攻击 diff --git a/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/Ys7Test.java b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/Ys7Test.java new file mode 100644 index 00000000..00a5bc17 --- /dev/null +++ b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/Ys7Test.java @@ -0,0 +1,29 @@ +package org.dromara.test; + +import jakarta.annotation.Resource; +import org.dromara.manager.ys7manager.Ys7Manager; +import org.dromara.manager.ys7manager.Ys7RequestUtils; +import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +/** + * @author lcj + * @date 2025/6/12 17:06 + */ +@SpringBootTest +public class Ys7Test { + + @Resource + private Ys7Manager ys7Manager; + + @Test + void test() { + String token = ys7Manager.getToken(); + List ys7QueryDeviceResponseVos = Ys7RequestUtils.queryDeviceVoList(token, 1, 20); + System.out.println(ys7QueryDeviceResponseVos); + } + +} diff --git a/xinnengyuan/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java b/xinnengyuan/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java index 0a60fbcc..d35df39a 100644 --- a/xinnengyuan/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java +++ b/xinnengyuan/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package org.dromara.common.web.handler; +import cn.hutool.core.text.AntPathMatcher; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpStatus; import jakarta.servlet.ServletException; @@ -14,6 +15,7 @@ import org.dromara.common.core.exception.base.BaseException; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.json.utils.JsonUtils; import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -40,7 +42,7 @@ public class GlobalExceptionHandler { */ @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public R handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, - HttpServletRequest request) { + HttpServletRequest request) { String requestURI = request.getRequestURI(); log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); return R.fail(HttpStatus.HTTP_BAD_METHOD, e.getMessage()); @@ -106,6 +108,18 @@ public class GlobalExceptionHandler { return R.fail(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue())); } + @ExceptionHandler(HttpMessageNotReadableException.class) + public R handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpServletRequest request) { + String path = request.getRequestURI(); + AntPathMatcher matcher = new AntPathMatcher(); + String pattern = "/facility/**/geoJson"; + log.error("请求:{},参数格式错误:{}", path, ex.getMessage()); + if (matcher.match(pattern, path)) { + return R.fail(HttpStatus.HTTP_BAD_REQUEST, "图层解析错误,请选择正确的设施或名称图层"); + } + return R.fail(HttpStatus.HTTP_BAD_REQUEST, "请求参数格式错误:" + ex.getMessage()); + } + /** * 找不到路由 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/constant/FacRedisKeyConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/constant/FacRedisKeyConstant.java index c8f2e88c..18d832ec 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/constant/FacRedisKeyConstant.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/constant/FacRedisKeyConstant.java @@ -1,15 +1,33 @@ package org.dromara.facility.constant; +import java.util.List; + /** * @author lcj * @date 2025/5/27 18:27 */ public interface FacRedisKeyConstant { - String FAC_REDIS_PREFIX = "fac:"; + /** + * 设施模块 Redis 缓存前缀 + */ + String FAC_REDIS_PREFIX = "fac:facility:"; + /** + * 设施模块正在操作任务 Redis 缓存前缀 + */ String FAC_IN_OPERATION_REDIS_KEY_PREFIX = FAC_REDIS_PREFIX + "inOperation:"; + /** + * 设施模块类型 - 坐标 + */ + String GEO_TYPE_LOCAL = "location"; + + /** + * 设施模块类型 - 名称 + */ + String GEO_TYPE_NAME = "name"; + /** * 批量上传桩点、支架、立柱 Redis 缓存 key * @@ -18,17 +36,62 @@ public interface FacRedisKeyConstant { * @return Redis 缓存 key */ static String getBatchUploadPartsRedisKey(String sessionId, int batchNum) { - return String.format("%s%s:%s:%s", FAC_REDIS_PREFIX, "panel:parts", sessionId, batchNum); + return String.format("%s%s:%s:%s", FAC_REDIS_PREFIX, "parts", sessionId, batchNum); } /** - * 当前项目是否正在操作 Redis 缓存 key + * 批量上传光伏板 Redis 缓存 key + * + * @param sessionId 唯一标识 + * @param batchNum 第几批数据 + * @param type 类型 + * @return Redis 缓存 key + */ + static String getBatchUploadPanelRedisKey(String sessionId, int batchNum, String type) { + return String.format("%s%s:%s:%s:%s", FAC_REDIS_PREFIX, "panel", sessionId, batchNum, type); + } + + /** + * 项目内进行中的任务 Redis 缓存 key 前缀 + * + * @param projectId 项目 ID + * @return Redis 缓存前缀 + */ + static String getInOperationByProjectRedisPrefix(Long projectId) { + return String.format("%s%s:%s:", FAC_IN_OPERATION_REDIS_KEY_PREFIX, "project", projectId); + } + + /** + * 当前项目下是否正在操作桩点、支架、立柱 Redis 缓存 key * * @param projectId 项目 ID * @return Redis 缓存 key */ - static String getInOperationByProjectRedisKey(Long projectId) { - return String.format("%s%s:%s", FAC_IN_OPERATION_REDIS_KEY_PREFIX, "project", projectId); + static String getPartsInOperationByProjectRedisKey(Long projectId) { + return String.format("%s%s", getInOperationByProjectRedisPrefix(projectId), "parts"); + } + + /** + * 当前项目下是否正在操作光伏板 Redis 缓存 key + * + * @param projectId 项目 ID + * @return Redis 缓存 key + */ + static String getPanelInOperationByProjectRedisKey(Long projectId) { + return String.format("%s%s", getInOperationByProjectRedisPrefix(projectId), "panel"); + } + + /** + * 获取操作的 Redis 缓存 key 列表 + * + * @param projectId 项目 ID + * @return Redis 缓存 key 列表 + */ + static List getInOperationRedisKeyList(Long projectId) { + return List.of( + getPartsInOperationByProjectRedisKey(projectId), + getPanelInOperationByProjectRedisKey(projectId) + ); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByLine.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByLine.java deleted file mode 100644 index e4fe443c..00000000 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByLine.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.dromara.facility.domain.dto.geojson; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * @author lcj - * @date 2025/4/24 10:40 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class FacFeatureByLine { - - private String type; - - private FacGeometryByLine geometry; - - private FacProperties properties; - -} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByPlane.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByPlane.java index 2854a382..3143c27c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByPlane.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacFeatureByPlane.java @@ -4,6 +4,9 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serial; +import java.io.Serializable; + /** * @author lcj * @date 2025/4/24 10:32 @@ -11,7 +14,10 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor -public class FacFeatureByPlane { +public class FacFeatureByPlane implements Serializable { + + @Serial + private static final long serialVersionUID = 6732054357362738399L; private String type; diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeoJsonByLine.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeoJsonByLine.java deleted file mode 100644 index abc79345..00000000 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeoJsonByLine.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dromara.facility.domain.dto.geojson; - -import lombok.Data; - -import java.io.Serial; -import java.io.Serializable; -import java.util.List; - -/** - * @author lcj - * @date 2025/4/24 10:38 - */ -@Data -public class FacGeoJsonByLine implements Serializable { - - @Serial - private static final long serialVersionUID = -1019429627483913266L; - - private String name; - - private String type; - - private List features; - -} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByLine.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByLine.java deleted file mode 100644 index 43b7f33a..00000000 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByLine.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.dromara.facility.domain.dto.geojson; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * @author lcj - * @date 2025/4/24 10:41 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class FacGeometryByLine { - - private String type; - - private List> coordinates; - - private Long id; - -} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByPlane.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByPlane.java index 966f9c54..ab3c1669 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByPlane.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/geojson/FacGeometryByPlane.java @@ -4,6 +4,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import java.io.Serial; +import java.io.Serializable; import java.util.List; /** @@ -13,7 +15,10 @@ import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor -public class FacGeometryByPlane { +public class FacGeometryByPlane implements Serializable { + + @Serial + private static final long serialVersionUID = -82255764789167107L; private String type; diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/photovoltaicpanel/FacPhotovoltaicPanelCreateByGeoJsonReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/photovoltaicpanel/FacPhotovoltaicPanelCreateByGeoJsonReq.java index 1fb1d9db..25d68ae1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/photovoltaicpanel/FacPhotovoltaicPanelCreateByGeoJsonReq.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/dto/photovoltaicpanel/FacPhotovoltaicPanelCreateByGeoJsonReq.java @@ -33,4 +33,19 @@ public class FacPhotovoltaicPanelCreateByGeoJsonReq implements Serializable { */ private List nameGeoJson; + /** + * 批次上传标识 + */ + private String sessionId; + + /** + * 当前批次 + */ + private int batchNum; + + /** + * 总批次 + */ + private int totalBatch; + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/vo/matrix/FacMatrixBySubProjectVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/vo/matrix/FacMatrixBySubProjectVo.java new file mode 100644 index 00000000..eb02e394 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/domain/vo/matrix/FacMatrixBySubProjectVo.java @@ -0,0 +1,28 @@ +package org.dromara.facility.domain.vo.matrix; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/10 15:09 + */ +@Data +public class FacMatrixBySubProjectVo implements Serializable { + + @Serial + private static final long serialVersionUID = -3427826315362519128L; + + /** + * 主键 + */ + private Long matrixId; + + /** + * 方阵名称 + */ + private String name; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacBoxTransformerServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacBoxTransformerServiceImpl.java index 01d2fb5f..4243375d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacBoxTransformerServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacBoxTransformerServiceImpl.java @@ -146,12 +146,14 @@ public class FacBoxTransformerServiceImpl extends ServiceImpl matrixList = matrixService.lambdaQuery() + .select(FacMatrix::getId, FacMatrix::getPositions) .eq(FacMatrix::getProjectId, projectId).list(); if (CollUtil.isEmpty(matrixList)) { throw new ServiceException("项目下无方阵数据,请先创建方阵信息后再添加箱变信息", HttpStatus.NOT_FOUND); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacInverterServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacInverterServiceImpl.java index a903db07..b06cc979 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacInverterServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacInverterServiceImpl.java @@ -146,12 +146,14 @@ public class FacInverterServiceImpl extends ServiceImpl matrixList = matrixService.lambdaQuery() + .select(FacMatrix::getId, FacMatrix::getPositions) .eq(FacMatrix::getProjectId, projectId).list(); if (CollUtil.isEmpty(matrixList)) { throw new ServiceException("项目下无方阵数据,请先创建方阵信息后再添加逆变器信息", HttpStatus.NOT_FOUND); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacMatrixServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacMatrixServiceImpl.java index 62216190..22ff7581 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacMatrixServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacMatrixServiceImpl.java @@ -35,6 +35,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Objects; /** * 设施-方阵Service业务层处理 @@ -257,19 +258,21 @@ public class FacMatrixServiceImpl extends ServiceImpl operationRedisKey = FacRedisKeyConstant.getInOperationRedisKeyList(projectId); + List list = redisTemplate.opsForValue().multiGet(operationRedisKey); + boolean hasValue = list != null && list.stream().anyMatch(Objects::nonNull); + if (hasValue) { + throw new ServiceException("项目下有设施数据正在处理中,请等待处理完毕后再操作", HttpStatus.BAD_REQUEST); } - Long projectId = geoJson.getProjectId(); if (projectService.getById(projectId) == null) { throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); } // 获取当前项目下方阵信息 List oldMatrixList = this.lambdaQuery() + .select(FacMatrix::getId) .eq(FacMatrix::getProjectId, projectId).list(); List matrixList = new ArrayList<>(); List locationGeoJsonList = geoJson.getLocationGeoJson(); @@ -303,33 +306,23 @@ public class FacMatrixServiceImpl extends ServiceImpl lqw = new LambdaQueryWrapper<>(); - lqw.eq(PgsProgressCategory::getProjectId, projectId) - .in(PgsProgressCategory::getMatrixId, oldMatrixList.stream().map(FacMatrix::getId).toList()); - List progressCategories = progressCategoryService.list(lqw); - if (CollUtil.isNotEmpty(progressCategories)) { - boolean remove = progressCategoryService.remove(lqw); - if (!remove) { - throw new ServiceException("删除老方阵进度分类失败,数据库异常", HttpStatus.ERROR); - } - } - } if (CollUtil.isNotEmpty(matrixList)) { boolean result = this.saveBatch(matrixList); if (!result) { throw new ServiceException("批量新增方阵失败,数据库异常", HttpStatus.ERROR); } - List matrixIdList = matrixList.stream().map(FacMatrix::getId).toList(); - Boolean save = progressCategoryService.insertByTemplate(projectId, matrixIdList); + Boolean save = progressCategoryService.insertByTemplate(projectId, matrixList,oldMatrixList); if (!save) { throw new ServiceException("批量新增方阵进度分类失败,数据库异常", HttpStatus.ERROR); } } + if (CollUtil.isNotEmpty(oldMatrixList)) { + List oldMatrixIds = oldMatrixList.stream().map(FacMatrix::getId).toList(); + boolean result = this.removeBatchByIds(oldMatrixIds); + if (!result) { + throw new ServiceException("删除老方阵失败,数据库异常", HttpStatus.ERROR); + } + } return true; } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java index 64fdd7c7..c61767f0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelPartsServiceImpl.java @@ -77,8 +77,8 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan @Resource private ScheduledExecutorService scheduledExecutorService; - @Resource @Lazy + @Resource private FacPhotovoltaicPanelPartsServiceImpl self; // 注入自己 /** @@ -89,24 +89,25 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan */ @Override public Boolean insertPartsByGeoJson(FacPhotovoltaicPanelPartsCreateByGeoJsonReq geoJson) { - // 设置 redis 防止多次操作 - String operationRedisKey = FacRedisKeyConstant.getInOperationByProjectRedisKey(geoJson.getProjectId()); + // Long projectId = geoJson.getProjectId(); + Long projectId = 1930896467736707073L; // 判断 redis key 是否存在,存在则返回 - Object object = redisTemplate.opsForValue().get(operationRedisKey); - if (object != null && (Boolean) object) { - throw new ServiceException("项目下桩点、立柱、支架数据正在处理中,请勿重复操作", HttpStatus.BAD_REQUEST); + List operationRedisKey = FacRedisKeyConstant.getInOperationRedisKeyList(projectId); + List list = redisTemplate.opsForValue().multiGet(operationRedisKey); + boolean hasValue = list != null && list.stream().anyMatch(Objects::nonNull); + if (hasValue) { + throw new ServiceException("项目下有设施数据正在处理中,请等待处理完毕后再操作", HttpStatus.BAD_REQUEST); } // 第一次接收请求,进行数据校验 int batchNum = geoJson.getBatchNum(); if (batchNum == 1) { - Long projectId = geoJson.getProjectId(); if (projectService.getById(projectId) == null) { throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); } // 查询项目下光伏板 - List photovoltaicPanelList = photovoltaicPanelService.lambdaQuery() - .eq(FacPhotovoltaicPanel::getProjectId, projectId).list(); - if (CollUtil.isEmpty(photovoltaicPanelList)) { + Long count = photovoltaicPanelService.lambdaQuery() + .eq(FacPhotovoltaicPanel::getProjectId, projectId).count(); + if (count <= 0) { throw new ServiceException("项目下无光伏板信息,请先创建光伏板信息后再添加桩点、立柱、支架信息", HttpStatus.NOT_FOUND); } } @@ -126,19 +127,22 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan List allData = new ArrayList<>(); for (int i = 1; i <= totalBatch; i++) { String batchKey = FacRedisKeyConstant.getBatchUploadPartsRedisKey(sessionId, i); - Object batch = redisTemplate.opsForValue().get(batchKey); - if (batch instanceof List) { - allData.addAll((List) batch); + Object batchObj = redisTemplate.opsForValue().get(batchKey); + if (batchObj instanceof List) { + @SuppressWarnings("unchecked") + List batch = (List) batchObj; + allData.addAll(batch); } } // 设置 redis key,防止多次操作 - redisTemplate.opsForValue().set(operationRedisKey, true); - messageDto.setMessage("桩点、立柱、支架数据上传完毕,数据处理中"); + String operationPartsRedisKey = FacRedisKeyConstant.getPartsInOperationByProjectRedisKey(projectId); + redisTemplate.opsForValue().set(operationPartsRedisKey, true); + messageDto.setMessage("桩点、立柱、支架数据上传完毕,正在处理中"); SseMessageUtils.publishMessage(messageDto); scheduledExecutorService.execute(() -> { try { // 合并后的数据处理,如入库 - this.saveBatch(geoJson.getProjectId(), allData, userId); + this.saveBatch(projectId, allData, userId); } catch (Exception e) { messageDto.setMessage("桩点、立柱、支架数据处理失败,请联系管理员处理"); SseMessageUtils.publishMessage(messageDto); @@ -150,7 +154,7 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan String batchKey = FacRedisKeyConstant.getBatchUploadPartsRedisKey(sessionId, i); redisTemplate.delete(batchKey); } - redisTemplate.delete(operationRedisKey); + redisTemplate.delete(operationPartsRedisKey); } messageDto.setMessage("桩点、立柱、支架数据处理完毕"); SseMessageUtils.publishMessage(messageDto); @@ -625,7 +629,7 @@ public class FacPhotovoltaicPanelPartsServiceImpl implements IFacPhotovoltaicPan }); long count = photovoltaicPanelPointService.count(pointWrapper); if (count <= 0) { - throw new ServiceException("光伏板桩点数据不存在,请导入数据后再进行操作`", HttpStatus.NOT_FOUND); + throw new ServiceException("光伏板桩点数据不存在,请导入数据后再进行操作", HttpStatus.NOT_FOUND); } pointWrapper.set(FacPhotovoltaicPanelPoint::getFinishDate, finishDate); pointWrapper.set(FacPhotovoltaicPanelPoint::getFinishType, FacFinishTypeEnum.HAND.getValue()); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java index 93a6646b..225b1e07 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/facility/service/impl/FacPhotovoltaicPanelServiceImpl.java @@ -14,6 +14,8 @@ 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.common.sse.dto.SseMessageDto; +import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.facility.constant.FacRedisKeyConstant; import org.dromara.facility.domain.FacMatrix; import org.dromara.facility.domain.FacPhotovoltaicPanel; @@ -36,7 +38,6 @@ import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.service.IPgsProgressCategoryService; import org.dromara.project.service.IBusProjectService; import org.dromara.utils.JSTUtil; -import org.springframework.aop.framework.AopContext; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.dao.DataAccessException; @@ -78,6 +79,13 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl redisTemplate; + @Resource + private ScheduledExecutorService scheduledExecutorService; + + @Lazy + @Resource + private FacPhotovoltaicPanelServiceImpl self; // 注入自己 + /** * 查询设施-光伏板 * @@ -162,166 +170,232 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl operationRedisKey = FacRedisKeyConstant.getInOperationRedisKeyList(projectId); + List list = redisTemplate.opsForValue().multiGet(operationRedisKey); + boolean hasValue = list != null && list.stream().anyMatch(Objects::nonNull); + if (hasValue) { + throw new ServiceException("项目下有设施数据正在处理中,请等待处理完毕后再操作", HttpStatus.BAD_REQUEST); } - Long projectId = geoJson.getProjectId(); if (projectService.getById(projectId) == null) { throw new ServiceException("项目不存在", HttpStatus.NOT_FOUND); } // 获取项目下方阵信息 List matrixList = matrixService.lambdaQuery() + .select(FacMatrix::getId, FacMatrix::getPositions) .eq(FacMatrix::getProjectId, projectId).list(); if (CollUtil.isEmpty(matrixList)) { throw new ServiceException("项目下无方阵数据,请先创建方阵信息后再添加光伏板信息", HttpStatus.NOT_FOUND); } - // 获取当下项目下光伏板的信息 - List oldPhotovoltaicPanelList = this.lambdaQuery() - .eq(FacPhotovoltaicPanel::getProjectId, projectId).list(); - Map photovoltaicPanelMap = oldPhotovoltaicPanelList.stream() - .collect(Collectors.toMap( - panel -> panel.getName() + "_" + panel.getProgressCategoryId(), - Function.identity(), - (existing, replacement) -> existing // 如果有重复,保留第一个 - )); - List locationGeoJsonList = geoJson.getLocationGeoJson(); - List locationFeatures = new ArrayList<>(); - for (FacGeoJsonByPlane geoJsonByPlane : locationGeoJsonList) { - locationFeatures.addAll(geoJsonByPlane.getFeatures()); + // 获取 redis key + String sessionId = geoJson.getSessionId(); + int batchNum = geoJson.getBatchNum(); + int totalBatch = geoJson.getTotalBatch(); + // 获取所有光伏板位置信息 + List locationGeoJsonBatchList = geoJson.getLocationGeoJson(); + if (CollUtil.isNotEmpty(locationGeoJsonBatchList)) { + List locationFeaturesBatch = new ArrayList<>(); + for (FacGeoJsonByPlane geoJsonByPlane : locationGeoJsonBatchList) { + locationFeaturesBatch.addAll(geoJsonByPlane.getFeatures()); + } + // 存储到 Redis,设置过期时间 30 分钟 + String redisKeyByLocation = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, batchNum, FacRedisKeyConstant.GEO_TYPE_LOCAL); + redisTemplate.opsForValue().set(redisKeyByLocation, locationFeaturesBatch, 1800, TimeUnit.SECONDS); } // 获取所有对应名称的点 - List nameGeoJsonList = geoJson.getNameGeoJson(); - List nameFeatures = new ArrayList<>(); - for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonList) { - nameFeatures.addAll(geoJsonByPoint.getFeatures()); - } - // 获取进度类别信息 - List progressCategoryList = progressCategoryService.lambdaQuery() - .in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE).list(); - Map> progressCategoryMap = progressCategoryList.stream() - .collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId)); - List allPanels = new ArrayList<>(); - List>> futures = new ArrayList<>(); - Long userId = LoginHelper.getUserId(); - // 构建光伏板实体集合 - try (ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())) { - for (FacFeatureByPoint nameFeature : nameFeatures) { - Future> future = executorService.submit(() -> { - List panelList = new ArrayList<>(); - // ① 找到该点对应的 polygon(优先包含,否则最近) - FacFeatureByPlane matchedPolygon = JSTUtil.findNearestOrContainingPolygon(nameFeature, locationFeatures); - if (matchedPolygon == null) return Collections.emptyList(); - // ② 获取 geometry 坐标 - List> coordinates = matchedPolygon.getGeometry().getCoordinates().getFirst(); - // ③ 判断所属方阵 - FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates); - if (matrix == null) return Collections.emptyList(); - Long matrixId = matrix.getId(); - // ④ 获取进度类别 - List progressCategoryListByMatrix = progressCategoryMap.get(matrixId); - if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList(); - // ⑤ 获取名称 - String name = nameFeature.getProperties() != null ? nameFeature.getProperties().getText() : null; - if (StringUtils.isBlank(name)) return Collections.emptyList(); - // ⑥ 构建面板数据 - for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) { - FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel(); - panel.setMatrixId(matrixId); - panel.setName(name); - panel.setProjectId(projectId); - panel.setPositions(JSONUtil.toJsonStr(coordinates)); - panel.setCreateBy(userId); - panel.setUpdateBy(userId); - String mapKey = name + "_" + progressCategory.getId(); - FacPhotovoltaicPanel oldPanel = photovoltaicPanelMap.get(mapKey); - if (oldPanel != null) { - panel.setStatus(oldPanel.getStatus()); - if (FacFinishStatusEnum.FINISH.getValue().equals(oldPanel.getStatus())) { - panel.setFinishType(oldPanel.getFinishType()); - panel.setFinishDate(oldPanel.getFinishDate()); - } - panel.setProgressCategoryId(oldPanel.getProgressCategoryId()); - panel.setProgressCategoryName(oldPanel.getProgressCategoryName()); - } else { - panel.setProgressCategoryId(progressCategory.getId()); - panel.setProgressCategoryName(progressCategory.getName()); - } - panelList.add(panel); - } - return panelList; - }); - futures.add(future); + List nameGeoJsonBatchList = geoJson.getNameGeoJson(); + if (CollUtil.isNotEmpty(nameGeoJsonBatchList)) { + List nameFeaturesBatch = new ArrayList<>(); + for (FacGeoJsonByPoint geoJsonByPoint : nameGeoJsonBatchList) { + nameFeaturesBatch.addAll(geoJsonByPoint.getFeatures()); } - // 等待所有结果 - for (Future> future : futures) { - try { - allPanels.addAll(future.get()); - } catch (Exception e) { - log.error("线程执行异常", e); + // 存储到 Redis,设置过期时间 30 分钟 + String redisKeyByName = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, batchNum, FacRedisKeyConstant.GEO_TYPE_NAME); + redisTemplate.opsForValue().set(redisKeyByName, nameFeaturesBatch, 1800, TimeUnit.SECONDS); + } + log.info("已接收第 {} 批数据,共 {} 批", batchNum, totalBatch); + Long userId = LoginHelper.getUserId(); + SseMessageDto messageDto = new SseMessageDto(); + messageDto.setUserIds(List.of(userId)); + // 如果是最后一批,开始合并 + if (batchNum == totalBatch) { + List locationFeatures = new ArrayList<>(); + List nameFeatures = new ArrayList<>(); + for (int i = 1; i <= totalBatch; i++) { + String batchKeyByLocation = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, i, FacRedisKeyConstant.GEO_TYPE_LOCAL); + String batchKeyByName = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, i, FacRedisKeyConstant.GEO_TYPE_NAME); + Object batchLocationObj = redisTemplate.opsForValue().get(batchKeyByLocation); + Object batchNameObj = redisTemplate.opsForValue().get(batchKeyByName); + if (batchLocationObj instanceof List) { + @SuppressWarnings("unchecked") + List batch = (List) batchLocationObj; + locationFeatures.addAll(batch); + } + if (batchNameObj instanceof List) { + @SuppressWarnings("unchecked") + List batch = (List) batchNameObj; + nameFeatures.addAll(batch); } } - } - // 自定义线程池(IO 密集型线程池) - ThreadPoolExecutor customExecutor = new ThreadPoolExecutor( - 20, // 核心线程数 - 50, // 最大线程数 - 60L, // 线程空闲存活时间 - TimeUnit.SECONDS, // 存活时间单位 - new LinkedBlockingQueue<>(10000), // 阻塞队列容量 - new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程处理任务 - ); - // 分批处理,避免长事务,每次处理 1000 条数据 - int batchSize = 1000; - // 保存所有批次任务 - List> deleteFutures = new ArrayList<>(); - int deleteSize = oldPhotovoltaicPanelList.size(); - for (int i = 0; i < deleteSize; i += batchSize) { - int endIndex = Math.min(i + batchSize, deleteSize); - List batchList = oldPhotovoltaicPanelList.subList(i, endIndex); - // 使用事务处理每批数据 - // 获取代理 - FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy(); - // 异步处理每批数据,将任务添加到异步任务列表 - CompletableFuture future = CompletableFuture.runAsync(() -> photovoltaicPanelService.deleteBatchInner(batchList), customExecutor); - deleteFutures.add(future); - } - // 等待所有批次完成操作 - CompletableFuture.allOf(deleteFutures.toArray(new CompletableFuture[0])).join(); - // 保存所有批次任务 - List> insertFutures = new ArrayList<>(); - int totalSize = allPanels.size(); - for (int i = 0; i < totalSize; i += batchSize) { - int endIndex = Math.min(i + batchSize, totalSize); - List batchList = allPanels.subList(i, endIndex); - // 使用事务处理每批数据 - // 获取代理 - FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = (FacPhotovoltaicPanelServiceImpl) AopContext.currentProxy(); - // 异步处理每批数据,将任务添加到异步任务列表 - CompletableFuture future = CompletableFuture.runAsync(() -> photovoltaicPanelService.insertBatchInner(batchList), customExecutor); - insertFutures.add(future); - } - // 等待所有批次完成操作 - CompletableFuture.allOf(insertFutures.toArray(new CompletableFuture[0])).join(); - // 关闭线程池 - customExecutor.shutdown(); - // 更新数量 - Map> countMap = allPanels - .stream().collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId)); - for (PgsProgressCategory progressCategory : progressCategoryList) { - Long progressCategoryId = progressCategory.getId(); - int total = 0; - if (countMap.containsKey(progressCategoryId)) { - total = countMap.get(progressCategoryId).size(); - } - progressCategory.setTotal(BigDecimal.valueOf(total)); - } - boolean result = progressCategoryService.updateBatchById(progressCategoryList); - if (!result) { - throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR); + // 设置 redis key,防止多次操作 + String operationPanelRedisKey = FacRedisKeyConstant.getPanelInOperationByProjectRedisKey(projectId); + redisTemplate.opsForValue().set(operationPanelRedisKey, true); + messageDto.setMessage("光伏板数据上传完毕,正在处理中"); + SseMessageUtils.publishMessage(messageDto); + scheduledExecutorService.execute(() -> { + try { + // 获取当下项目下光伏板的信息 + List oldPhotovoltaicPanelList = this.lambdaQuery() + .eq(FacPhotovoltaicPanel::getProjectId, projectId).list(); + Map photovoltaicPanelMap = oldPhotovoltaicPanelList.stream() + .collect(Collectors.toMap( + panel -> panel.getName() + "_" + panel.getProgressCategoryId(), + Function.identity(), + (existing, replacement) -> existing // 如果有重复,保留第一个 + )); + // 获取进度类别信息 + List progressCategoryList = progressCategoryService.lambdaQuery() + .in(PgsProgressCategory::getWorkType, PgsProgressCategoryConstant.PHOTOVOLTAIC_PANEL_PROGRESS_CATEGORY_WORK_TYPE).list(); + Map> progressCategoryMap = progressCategoryList.stream() + .collect(Collectors.groupingBy(PgsProgressCategory::getMatrixId)); + List allPanels = new ArrayList<>(); + List>> futures = new ArrayList<>(); + // 构建光伏板实体集合 + try (ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())) { + for (FacFeatureByPoint nameFeature : nameFeatures) { + Future> future = executorService.submit(() -> { + List panelList = new ArrayList<>(); + // ① 找到该点对应的 polygon(优先包含,否则最近) + FacFeatureByPlane matchedPolygon = JSTUtil.findNearestOrContainingPolygon(nameFeature, locationFeatures); + if (matchedPolygon == null) return Collections.emptyList(); + // ② 获取 geometry 坐标 + List> coordinates = matchedPolygon.getGeometry().getCoordinates().getFirst(); + // ③ 判断所属方阵 + FacMatrix matrix = matrixService.getMatrixIdBy2Coordinates(matrixList, coordinates); + if (matrix == null) return Collections.emptyList(); + Long matrixId = matrix.getId(); + // ④ 获取进度类别 + List progressCategoryListByMatrix = progressCategoryMap.get(matrixId); + if (CollUtil.isEmpty(progressCategoryListByMatrix)) return Collections.emptyList(); + // ⑤ 获取名称 + String name = nameFeature.getProperties() != null ? nameFeature.getProperties().getText() : null; + if (StringUtils.isBlank(name)) return Collections.emptyList(); + // ⑥ 构建面板数据 + for (PgsProgressCategory progressCategory : progressCategoryListByMatrix) { + FacPhotovoltaicPanel panel = new FacPhotovoltaicPanel(); + panel.setMatrixId(matrixId); + panel.setName(name); + panel.setProjectId(projectId); + panel.setPositions(JSONUtil.toJsonStr(coordinates)); + panel.setCreateBy(userId); + panel.setUpdateBy(userId); + String mapKey = name + "_" + progressCategory.getId(); + FacPhotovoltaicPanel oldPanel = photovoltaicPanelMap.get(mapKey); + if (oldPanel != null) { + panel.setStatus(oldPanel.getStatus()); + if (FacFinishStatusEnum.FINISH.getValue().equals(oldPanel.getStatus())) { + panel.setFinishType(oldPanel.getFinishType()); + panel.setFinishDate(oldPanel.getFinishDate()); + } + panel.setProgressCategoryId(oldPanel.getProgressCategoryId()); + panel.setProgressCategoryName(oldPanel.getProgressCategoryName()); + } else { + panel.setProgressCategoryId(progressCategory.getId()); + panel.setProgressCategoryName(progressCategory.getName()); + } + panelList.add(panel); + } + return panelList; + }); + futures.add(future); + } + // 等待所有结果 + for (Future> future : futures) { + try { + allPanels.addAll(future.get()); + } catch (Exception e) { + log.error("线程执行异常", e); + } + } + } + // 自定义线程池(IO 密集型线程池) + ThreadPoolExecutor customExecutor = new ThreadPoolExecutor( + 20, // 核心线程数 + 50, // 最大线程数 + 60L, // 线程空闲存活时间 + TimeUnit.SECONDS, // 存活时间单位 + new LinkedBlockingQueue<>(10000), // 阻塞队列容量 + new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程处理任务 + ); + // 分批处理,避免长事务,每次处理 1000 条数据 + int batchSize = 1000; + // 保存所有批次任务 + List> deleteFutures = new ArrayList<>(); + int deleteSize = oldPhotovoltaicPanelList.size(); + for (int i = 0; i < deleteSize; i += batchSize) { + int endIndex = Math.min(i + batchSize, deleteSize); + List batchList = oldPhotovoltaicPanelList.subList(i, endIndex); + // 使用事务处理每批数据 + // 获取代理 + FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = self; + // 异步处理每批数据,将任务添加到异步任务列表 + CompletableFuture future = CompletableFuture.runAsync(() -> photovoltaicPanelService.deleteBatchInner(batchList), customExecutor); + deleteFutures.add(future); + } + // 等待所有批次完成操作 + CompletableFuture.allOf(deleteFutures.toArray(new CompletableFuture[0])).join(); + // 保存所有批次任务 + List> insertFutures = new ArrayList<>(); + int totalSize = allPanels.size(); + for (int i = 0; i < totalSize; i += batchSize) { + int endIndex = Math.min(i + batchSize, totalSize); + List batchList = allPanels.subList(i, endIndex); + // 使用事务处理每批数据 + // 获取代理 + FacPhotovoltaicPanelServiceImpl photovoltaicPanelService = self; + // 异步处理每批数据,将任务添加到异步任务列表 + CompletableFuture future = CompletableFuture.runAsync(() -> photovoltaicPanelService.insertBatchInner(batchList), customExecutor); + insertFutures.add(future); + } + // 等待所有批次完成操作 + CompletableFuture.allOf(insertFutures.toArray(new CompletableFuture[0])).join(); + // 关闭线程池 + customExecutor.shutdown(); + // 更新数量 + Map> countMap = allPanels + .stream().collect(Collectors.groupingBy(FacPhotovoltaicPanel::getProgressCategoryId)); + for (PgsProgressCategory progressCategory : progressCategoryList) { + Long progressCategoryId = progressCategory.getId(); + int total = 0; + if (countMap.containsKey(progressCategoryId)) { + total = countMap.get(progressCategoryId).size(); + } + progressCategory.setTotal(BigDecimal.valueOf(total)); + } + boolean result = progressCategoryService.updateBatchById(progressCategoryList); + if (!result) { + throw new ServiceException("更新进度类别失败,数据库异常", HttpStatus.ERROR); + } + messageDto.setMessage("光伏板数据处理完毕"); + SseMessageUtils.publishMessage(messageDto); + } catch (Exception e) { + messageDto.setMessage("光伏板数据处理失败,请联系管理员处理"); + SseMessageUtils.publishMessage(messageDto); + log.error("光伏板数据处理失败", e); + throw new ServiceException("光伏板数据处理失败", HttpStatus.ERROR); + } finally { + // 清理缓存 + for (int i = 1; i <= totalBatch; i++) { + String batchKeyByLocation = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, i, FacRedisKeyConstant.GEO_TYPE_LOCAL); + String batchKeyByName = FacRedisKeyConstant.getBatchUploadPanelRedisKey(sessionId, i, FacRedisKeyConstant.GEO_TYPE_NAME); + redisTemplate.delete(batchKeyByLocation); + redisTemplate.delete(batchKeyByName); + } + redisTemplate.delete(operationPanelRedisKey); + } + }); } return true; } 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 new file mode 100644 index 00000000..449062d7 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/once/FullSyncYs7DeviceData.java @@ -0,0 +1,38 @@ +package org.dromara.job.once; + +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.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author lcj + * @date 2025/6/13 11:08 + */ +@Slf4j +//@Component +public class FullSyncYs7DeviceData implements CommandLineRunner { + + @Resource + private Ys7Manager ys7Manager; + + @Resource + private IOthYs7DeviceService ys7DeviceService; + + @Override + public void run(String... args) throws Exception { + 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/manager/ys7manager/Ys7Constant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java new file mode 100644 index 00000000..7720c052 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Constant.java @@ -0,0 +1,33 @@ +package org.dromara.manager.ys7manager; + +/** + * @author lcj + * @date 2025/6/12 16:56 + */ +public interface Ys7Constant { + + /** + * token redis 缓存 key 前缀 + */ + String TOKEN_REDIS_KEY = "ys7:token"; + + /** + * 分页查询设备列表最大条数 + */ + Integer MAX_PAGE_SIZE = 50; + + /** + * 获取 token 请求地址 Post + */ + String getTokenUrlByPost = "https://open.ys7.com/api/lapp/token/get"; + + /** + * 分页查询设备列表请求地址 Post + */ + String queryDevicePageUrlByPost = "https://open.ys7.com/api/lapp/device/list"; + + /** + * 修改设备名称请求地址 Post + */ + String updateDeviceNameUrlByPost = "https://open.ys7.com/api/lapp/device/name/update"; +} 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 new file mode 100644 index 00000000..3d9af76d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Manager.java @@ -0,0 +1,68 @@ +package org.dromara.manager.ys7manager; + +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @author lcj + * @date 2025/6/13 11:10 + */ +@Slf4j +@Component +public class Ys7Manager { + + @Resource + private Ys7Properties ys7Properties; + + @Resource + private StringRedisTemplate stringRedisTemplate; + + /** + * 获取所有设备列表 + * + * @return 设备列表 + */ + public List queryAllDeviceList() { + String token = getToken(); + int pageStart = 0; + int pageSize = 50; + List deviceList = new ArrayList<>(); + while (true) { + // 分页获取设备 + List list = Ys7RequestUtils.queryDeviceVoList(token, pageStart, pageSize); + deviceList.addAll(list); + // 获取设备数量小于分页大小,则结束循环 + if (list.size() < pageSize) { + break; + } + pageStart++; + } + return deviceList; + } + + /** + * 获取 token + * + * @return token + */ + public String getToken() { + String tokenRedisKey = Ys7Constant.TOKEN_REDIS_KEY; + String token = stringRedisTemplate.opsForValue().get(tokenRedisKey); + // 不为空,直接返回 token + if (token != null) { + return token; + } + // 向云服务商请求新的 token + String newToken = Ys7RequestUtils.getToken(ys7Properties.getAppKey(), ys7Properties.getAppSecret()); + // 设置有效期 + stringRedisTemplate.opsForValue().set(tokenRedisKey, newToken, 6, TimeUnit.DAYS); + return newToken; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Properties.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Properties.java new file mode 100644 index 00000000..1c5316c8 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7Properties.java @@ -0,0 +1,26 @@ +package org.dromara.manager.ys7manager; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author lcj + * @date 2025/6/12 16:50 + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "ys7") +public class Ys7Properties { + + /** + * appKey + */ + private String appKey; + + /** + * appSecret + */ + private String appSecret; + +} 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 new file mode 100644 index 00000000..ecb10533 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/Ys7RequestUtils.java @@ -0,0 +1,141 @@ +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; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.manager.ys7manager.vo.Ys7NoDataResponseVo; +import org.dromara.manager.ys7manager.vo.Ys7PageResponseVo; +import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo; +import org.dromara.manager.ys7manager.vo.Ys7ResponseVo; + +import java.util.HashMap; +import java.util.List; + +/** + * @author lcj + * @date 2025/6/12 16:54 + */ +@Slf4j +public class Ys7RequestUtils { + + /** + * 获取 token + * + * @param appKey appKey + * @param appSecret appSecret + * @return token + */ + public static String getToken(String appKey, String appSecret) { + HashMap paramMap = new HashMap<>(); + paramMap.put("appKey", appKey); + paramMap.put("appSecret", appSecret); + String errorMsg = "Ys7 Token 请求失败"; + try (HttpResponse response = HttpRequest.post(Ys7Constant.getTokenUrlByPost) + .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()); + } + log.info("Ys7 Token 请求成功:{}", body); + String data = responseVo.getData(); + JSONObject jsonObject = JSONUtil.parseObj(data); + return jsonObject.get("accessToken", String.class); + } + } + + /** + * 查询设备列表 + * + * @param accessToken 萤石开放API访问令牌 + * @param pageStart 分页页码,起始页从0开始,不超过400页 + * @param pageSize 分页大小,默认为10,不超过50 + * @return 设备列表 + */ + public static List queryDeviceVoList(String accessToken, Integer pageStart, Integer pageSize) { + if (pageStart < 0 || pageStart > 400) { + throw new ServiceException("分页页码超出范围"); + } + if (pageSize < 0 || pageSize > 50) { + pageSize = Ys7Constant.MAX_PAGE_SIZE; + } + HashMap paramMap = new HashMap<>(); + paramMap.put("accessToken", accessToken); + paramMap.put("pageStart", pageStart); + paramMap.put("pageSize", pageSize); + String errorMsg = String.format("Ys7 分页查询设备列表 第%s页大小%s 请求失败", (pageStart + 1), pageSize); + try (HttpResponse response = HttpRequest.post(Ys7Constant.queryDevicePageUrlByPost) + .form(paramMap) + .execute()) { + if (!response.isOk()) { + log.error("{}:{}", errorMsg, response.getStatus()); + throw new ServiceException(errorMsg + response.getStatus()); + } + String body = response.body(); + Ys7PageResponseVo responseVo = JSONUtil.toBean(body, Ys7PageResponseVo.class); + if (!responseVo.getCode().equals("200")) { + log.error("{}:{}", errorMsg, responseVo.getMsg()); + throw new ServiceException(errorMsg + responseVo.getMsg()); + } + log.info("Ys7 分页查询设备列表 第{}页大小{} 请求成功:{}", (pageStart + 1), pageSize, body); + return JSONUtil.toList(responseVo.getData(), Ys7QueryDeviceResponseVo.class); + } + } + + /** + * 修改设备名称 + * + * @param accessToken accessToken + * @param deviceSerial 设备序列号 + * @param deviceName 设备名称,长度不大于50字节,不能包含特殊字符 + * @return 是否修改成功 + */ + public static Boolean updateDeviceName(String accessToken, String deviceSerial, String deviceName) { + // 参数校验 + if (StringUtils.isAnyBlank(accessToken, deviceSerial, deviceName)) { + throw new ServiceException("修改设备名称参数为空", HttpStatus.BAD_REQUEST); + } + 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); + paramMap.put("deviceSerial", deviceSerial); + paramMap.put("deviceName", deviceName); + // 发送请求 + String errorMsg = "修改设备名称请求失败"; + try (HttpResponse response = HttpRequest.post(Ys7Constant.updateDeviceNameUrlByPost) + .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, deviceName); + return true; + } + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7NoDataResponseVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7NoDataResponseVo.java new file mode 100644 index 00000000..1b5f03be --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7NoDataResponseVo.java @@ -0,0 +1,22 @@ +package org.dromara.manager.ys7manager.vo; + +import lombok.Data; + +/** + * @author lcj + * @date 2025/6/13 14:30 + */ +@Data +public class Ys7NoDataResponseVo { + + /** + * 响应码 + */ + private String code; + + /** + * 响应信息 + */ + private String msg; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7PageResponseVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7PageResponseVo.java new file mode 100644 index 00000000..4a07deca --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7PageResponseVo.java @@ -0,0 +1,32 @@ +package org.dromara.manager.ys7manager.vo; + +import lombok.Data; + +/** + * @author lcj + * @date 2025/6/12 17:35 + */ +@Data +public class Ys7PageResponseVo { + + /** + * 响应码 + */ + private String code; + + /** + * 响应数据 + */ + private String data; + + /** + * 响应信息 + */ + private String msg; + + /** + * 分页信息 + */ + private String page; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7QueryDeviceResponseVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7QueryDeviceResponseVo.java new file mode 100644 index 00000000..efd652c3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7QueryDeviceResponseVo.java @@ -0,0 +1,72 @@ +package org.dromara.manager.ys7manager.vo; + +import lombok.Data; + +/** + * @author lcj + * @date 2025/6/12 17:33 + */ +@Data +public class Ys7QueryDeviceResponseVo { + + /** + * 条目索引 + */ + private String id; + + /** + * 设备序列号 + */ + private String deviceSerial; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备型号 + */ + private String deviceType; + + /** + * 设备在线状态,1-在线;0-离线 + */ + private Integer status; + + /** + * 布撤防状态 + */ + private Integer defence; + + /** + * 固件版本号 + */ + private String deviceVersion; + + /** + * 用户添加时间 + */ + private Long addTime; + + /** + * 设备最后更新时间 + */ + private Long updateTime; + + /** + * 设备二级类目名称 + */ + private String parentCategory; + + /** + * 设备风险安全等级,0-安全;大于0,有风险,风险越高,值越大 + */ + private Integer riskLevel; + + /** + * 设备IP地址 + */ + private String netAddress; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7ResponseVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7ResponseVo.java new file mode 100644 index 00000000..b4817ed2 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/ys7manager/vo/Ys7ResponseVo.java @@ -0,0 +1,27 @@ +package org.dromara.manager.ys7manager.vo; + +import lombok.Data; + +/** + * @author lcj + * @date 2025/6/12 17:14 + */ +@Data +public class Ys7ResponseVo { + + /** + * 响应码 + */ + private String code; + + /** + * 响应数据 + */ + private String data; + + /** + * 响应信息 + */ + private String msg; + +} 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 new file mode 100644 index 00000000..c00c28d6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthDevicePresetController.java @@ -0,0 +1,108 @@ +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; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +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.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.vo.devicepreset.OthDevicePresetVo; +import org.dromara.other.service.IOthDevicePresetService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 摄像头预置位 + * + * @author lcj + * @date 2025-06-13 + */ +@Validated +@RestController +@RequestMapping("/other/devicePreset") +public class OthDevicePresetController extends BaseController { + + @Resource + private IOthDevicePresetService othDevicePresetService; + + /** + * 查询摄像头预置位列表 + */ + @SaCheckPermission("other:devicePreset:list") + @GetMapping("/list") + public TableDataInfo list(OthDevicePresetQueryReq req, PageQuery pageQuery) { + return othDevicePresetService.queryPageList(req, pageQuery); + } + + /** + * 导出摄像头预置位列表 + */ + @SaCheckPermission("other:devicePreset:export") + @Log(title = "摄像头预置位", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(OthDevicePresetQueryReq req, HttpServletResponse response) { + List list = othDevicePresetService.queryList(req); + ExcelUtil.exportExcel(list, "摄像头预置位", OthDevicePresetVo.class, response); + } + + /** + * 获取摄像头预置位详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("other:devicePreset:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(othDevicePresetService.queryById(id)); + } + + /** + * 新增摄像头预置位 + */ + @SaCheckPermission("other:devicePreset:add") + @Log(title = "摄像头预置位", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody OthDevicePresetCreateReq req) { + return R.ok(othDevicePresetService.insertByBo(req)); + } + + /** + * 修改摄像头预置位 + */ + @SaCheckPermission("other:devicePreset:edit") + @Log(title = "摄像头预置位", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody OthDevicePresetUpdateReq req) { + return toAjax(othDevicePresetService.updateByBo(req)); + } + + /** + * 删除摄像头预置位 + * + * @param ids 主键串 + */ + @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)); + } +} 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 new file mode 100644 index 00000000..c90b7413 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/controller/OthYs7DeviceController.java @@ -0,0 +1,132 @@ +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.EditGroup; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.log.enums.BusinessType; +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.vo.ys7device.OthYs7DeviceVo; +import org.dromara.other.service.IOthYs7DeviceService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 萤石摄像头 + * + * @author lcj + * @date 2025-06-13 + */ +@Validated +@RestController +@RequestMapping("/other/ys7Device") +public class OthYs7DeviceController extends BaseController { + + @Resource + private IOthYs7DeviceService othYs7DeviceService; + + @Resource + private Ys7Manager ys7Manager; + + /** + * 查询萤石摄像头列表 + */ + @SaCheckPermission("other:ys7Device:list") + @GetMapping("/list") + public TableDataInfo list(OthYs7DeviceQueryReq req, PageQuery pageQuery) { + return othYs7DeviceService.queryPageList(req, pageQuery); + } + + /** + * 导出萤石摄像头列表 + */ + @SaCheckPermission("other:ys7Device:export") + @Log(title = "萤石摄像头", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(OthYs7DeviceQueryReq req, HttpServletResponse response) { + List list = othYs7DeviceService.queryList(req); + ExcelUtil.exportExcel(list, "萤石摄像头", OthYs7DeviceVo.class, response); + } + + /** + * 获取萤石摄像头详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("other:ys7Device:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(othYs7DeviceService.queryById(id)); + } + + /** + * 修改萤石摄像头 + */ + @SaCheckPermission("other:ys7Device:edit") + @Log(title = "萤石摄像头", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody OthYs7DeviceUpdateReq req) { + return toAjax(othYs7DeviceService.updateByBo(req)); + } + + /** + * 修改萤石摄像头所属项目 + */ + @SaCheckPermission("other:ys7Device:edit") + @Log(title = "萤石摄像头", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping("/with/project") + public R updateWithProject(@Validated @RequestBody OthYs7DeviceWithProjectReq req) { + return toAjax(othYs7DeviceService.updateWithProject(req)); + } + + /** + * 修改萤石摄像头视频加密 + */ + @SaCheckPermission("other:ys7Device:edit") + @Log(title = "萤石摄像头", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping("/video/encrypted") + public R updateVideoEncrypted(@Validated @RequestBody OthYs7DeviceUpdateEncryptedReq req) { + return toAjax(othYs7DeviceService.updateVideoEncrypted(req)); + } + + /** + * 删除萤石摄像头 + * + * @param ids 主键串 + */ + @SaCheckPermission("other:ys7Device:remove") + @Log(title = "萤石摄像头", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(othYs7DeviceService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 获取 token + */ + @SaCheckPermission("other:ys7Device:query") + @GetMapping("/get/token") + public R getToken() { + return R.ok(ys7Manager.getToken()); + } +} 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 new file mode 100644 index 00000000..f174f87e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthDevicePreset.java @@ -0,0 +1,60 @@ +package org.dromara.other.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 摄像头预置位对象 oth_device_preset + * + * @author lcj + * @date 2025-06-13 + */ +@Data +@TableName("oth_device_preset") +public class OthDevicePreset implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 设备序列号 + */ + private String deviceSerial; + + /** + * 通道号 + */ + private Long channelNo; + + /** + * 预置点序号 + */ + private Long index; + + /** + * 预置点 + */ + private String name; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + +} 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 new file mode 100644 index 00000000..2301924f --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/OthYs7Device.java @@ -0,0 +1,117 @@ +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; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 萤石摄像头对象 oth_ys7_device + * + * @author lcj + * @date 2025-06-13 + */ +@Data +@TableName("oth_ys7_device") +public class OthYs7Device implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备序列号 + */ + private String deviceSerial; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备型号 + */ + private String deviceType; + + /** + * 设备在线状态(0离线 1在线) + */ + private Integer status; + + /** + * 布撤防状态 + */ + private Long defence; + + /** + * 固件版本号 + */ + private String deviceVersion; + + /** + * 摄像头坐标信息 + */ + private String position; + + /** + * 设备添加时间 + */ + private Date deviceCreateTime; + + /** + * 设备最后更新时间 + */ + private Date deviceUpdateTime; + + /** + * 设备风险安全等级(0安全 大于0,值越大,风险越高) + */ + private Integer riskLevel; + + /** + * 视频加密(0关闭 1开启) + */ + private Integer videoEncrypted; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + 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 new file mode 100644 index 00000000..8eacc89b --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetCreateReq.java @@ -0,0 +1,40 @@ +package org.dromara.other.domain.dto.devicepreset; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 17:16 + */ +@Data +public class OthDevicePresetCreateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -6326735809456235573L; + + /** + * 设备序列号 + */ + @NotNull(message = "设备序列号不能为空") + private String deviceSerial; + + /** + * 通道号 + */ + private Long channelNo; + + /** + * 预置点序号 + */ + private Long index; + + /** + * 预置点 + */ + private String name; + +} 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 new file mode 100644 index 00000000..68400147 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetQueryReq.java @@ -0,0 +1,40 @@ +package org.dromara.other.domain.dto.devicepreset; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 17:17 + */ +@Data +public class OthDevicePresetQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 440026959610596318L; + + /** + * 设备序列号 + */ + @NotNull(message = "设备序列号不能为空") + private String deviceSerial; + + /** + * 通道号 + */ + private Long channelNo; + + /** + * 预置点序号 + */ + private Long index; + + /** + * 预置点 + */ + private String name; + +} 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 new file mode 100644 index 00000000..7184e911 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/devicepreset/OthDevicePresetUpdateReq.java @@ -0,0 +1,40 @@ +package org.dromara.other.domain.dto.devicepreset; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 17:17 + */ +@Data +public class OthDevicePresetUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -5204788392612423553L; + + /** + * 主键id + */ + @NotNull(message = "主键id不能为空") + private Long id; + + /** + * 通道号 + */ + private Long channelNo; + + /** + * 预置点序号 + */ + private Long index; + + /** + * 预置点 + */ + private String name; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceQueryReq.java new file mode 100644 index 00000000..700837b5 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceQueryReq.java @@ -0,0 +1,48 @@ +package org.dromara.other.domain.dto.ys7device; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 10:19 + */ +@Data +public class OthYs7DeviceQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = -4341677730149529815L; + + /** + * 设备序列号 + */ + private String deviceSerial; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备型号 + */ + private String deviceType; + + /** + * 固件版本号 + */ + private String deviceVersion; + + /** + * 设备在线状态(0离线 1在线) + */ + private Long status; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateEncryptedReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateEncryptedReq.java new file mode 100644 index 00000000..7c43ac65 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateEncryptedReq.java @@ -0,0 +1,28 @@ +package org.dromara.other.domain.dto.ys7device; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 16:20 + */ +@Data +public class OthYs7DeviceUpdateEncryptedReq implements Serializable { + + @Serial + private static final long serialVersionUID = -5570966854443595312L; + + /** + * 主键 + */ + private Long id; + + /** + * 视频加密(0关闭 1开启) + */ + private Integer videoEncrypted; + +} 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 new file mode 100644 index 00000000..c95fcfe9 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceUpdateReq.java @@ -0,0 +1,48 @@ +package org.dromara.other.domain.dto.ys7device; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 10:19 + */ +@Data +public class OthYs7DeviceUpdateReq implements Serializable { + + @Serial + private static final long serialVersionUID = -3434796275594146484L; + + /** + * 主键id + */ + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备型号 + */ + private String deviceType; + + /** + * 固件版本号 + */ + private String deviceVersion; + + /** + * 备注 + */ + private String remark; + +} 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 new file mode 100644 index 00000000..dc2c913e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7device/OthYs7DeviceWithProjectReq.java @@ -0,0 +1,31 @@ +package org.dromara.other.domain.dto.ys7device; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @author lcj + * @date 2025/6/13 16:04 + */ +@Data +public class OthYs7DeviceWithProjectReq implements Serializable { + + @Serial + private static final long serialVersionUID = 5874710543055812819L; + + /** + * 主键 + */ + @NotNull(message = "主键不能为空") + private Long id; + + /** + * 项目id + */ + @NotNull(message = "项目id不能为空") + private Long projectId; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthVideoEncryptedEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthVideoEncryptedEnum.java new file mode 100644 index 00000000..e521dcf6 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/enums/OthVideoEncryptedEnum.java @@ -0,0 +1,34 @@ +package org.dromara.other.domain.enums; + +import lombok.Getter; + +/** + * @author lcj + * @date 2025/6/13 16:25 + */ +@Getter +public enum OthVideoEncryptedEnum { + + OFF("关闭", 0), + OPEN("开启", 1); + + private final String text; + + private final int value; + + OthVideoEncryptedEnum(String text, int value) { + this.text = text; + this.value = value; + } + + // 根据 value 获取对应的 text + public static String getTextByValue(int value) { + for (OthVideoEncryptedEnum 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 new file mode 100644 index 00000000..32083b91 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/devicepreset/OthDevicePresetVo.java @@ -0,0 +1,57 @@ +package org.dromara.other.domain.vo.devicepreset; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.other.domain.OthDevicePreset; + +import java.io.Serial; +import java.io.Serializable; + + +/** + * 摄像头预置位视图对象 oth_device_preset + * + * @author lcj + * @date 2025-06-13 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = OthDevicePreset.class) +public class OthDevicePresetVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @ExcelProperty(value = "主键id") + private Long id; + + /** + * 设备序列号 + */ + @ExcelProperty(value = "设备序列号") + private String deviceSerial; + + /** + * 通道号 + */ + @ExcelProperty(value = "通道号") + private Long channelNo; + + /** + * 预置点序号 + */ + @ExcelProperty(value = "预置点序号") + private Long index; + + /** + * 预置点 + */ + @ExcelProperty(value = "预置点") + private String name; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/ys7device/OthYs7DeviceVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/ys7device/OthYs7DeviceVo.java new file mode 100644 index 00000000..2c626031 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/vo/ys7device/OthYs7DeviceVo.java @@ -0,0 +1,93 @@ +package org.dromara.other.domain.vo.ys7device; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.other.domain.OthYs7Device; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 萤石摄像头视图对象 oth_ys7_device + * + * @author lcj + * @date 2025-06-13 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = OthYs7Device.class) +public class OthYs7DeviceVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 项目id + */ + @ExcelProperty(value = "项目id") + private Long projectId; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 设备序列号 + */ + @ExcelProperty(value = "设备序列号") + private String deviceSerial; + + /** + * 设备名称 + */ + @ExcelProperty(value = "设备名称") + private String deviceName; + + /** + * 设备型号 + */ + @ExcelProperty(value = "设备型号") + private String deviceType; + + /** + * 设备在线状态(0离线 1在线) + */ + @ExcelProperty(value = "设备在线状态(0离线 1在线)") + private Integer status; + + /** + * 固件版本号 + */ + @ExcelProperty(value = "固件版本号") + private String deviceVersion; + + /** + * 设备添加时间 + */ + @ExcelProperty(value = "设备添加时间") + private Date deviceCreateTime; + + /** + * 视频加密(0关闭 1开启) + */ + @ExcelProperty(value = "视频加密(0关闭 1开启)") + private Integer videoEncrypted; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthDevicePresetMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthDevicePresetMapper.java new file mode 100644 index 00000000..788c84f0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthDevicePresetMapper.java @@ -0,0 +1,15 @@ +package org.dromara.other.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.other.domain.OthDevicePreset; +import org.dromara.other.domain.vo.devicepreset.OthDevicePresetVo; + +/** + * 摄像头预置位Mapper接口 + * + * @author lcj + * @date 2025-06-13 + */ +public interface OthDevicePresetMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthYs7DeviceMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthYs7DeviceMapper.java new file mode 100644 index 00000000..1bb66081 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/mapper/OthYs7DeviceMapper.java @@ -0,0 +1,15 @@ +package org.dromara.other.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.other.domain.OthYs7Device; +import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo; + +/** + * 萤石摄像头Mapper接口 + * + * @author lcj + * @date 2025-06-13 + */ +public interface OthYs7DeviceMapper extends BaseMapperPlus { + +} 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 new file mode 100644 index 00000000..baca7d36 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthDevicePresetService.java @@ -0,0 +1,98 @@ +package org.dromara.other.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.other.domain.OthDevicePreset; +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.vo.devicepreset.OthDevicePresetVo; + +import java.util.Collection; +import java.util.List; + +/** + * 摄像头预置位Service接口 + * + * @author lcj + * @date 2025-06-13 + */ +public interface IOthDevicePresetService extends IService { + + /** + * 查询摄像头预置位 + * + * @param id 主键 + * @return 摄像头预置位 + */ + OthDevicePresetVo queryById(Long id); + + /** + * 分页查询摄像头预置位列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 摄像头预置位分页列表 + */ + TableDataInfo queryPageList(OthDevicePresetQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的摄像头预置位列表 + * + * @param req 查询条件 + * @return 摄像头预置位列表 + */ + List queryList(OthDevicePresetQueryReq req); + + /** + * 新增摄像头预置位 + * + * @param req 摄像头预置位 + * @return 新增摄像头预置位主键id + */ + Long insertByBo(OthDevicePresetCreateReq req); + + /** + * 修改摄像头预置位 + * + * @param req 摄像头预置位 + * @return 是否修改成功 + */ + Boolean updateByBo(OthDevicePresetUpdateReq req); + + /** + * 校验并批量删除摄像头预置位信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取摄像头预置位视图 + * + * @param devicePreset 摄像头预置位 + * @return 摄像头预置位视图 + */ + OthDevicePresetVo getVo(OthDevicePreset devicePreset); + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(OthDevicePresetQueryReq req); + + /** + * 获取摄像头预置位分页对象视图 + * + * @param devicePresetPage 摄像头预置位分页对象 + * @return 摄像头预置位分页对象视图 + */ + Page getVoPage(Page devicePresetPage); +} 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 new file mode 100644 index 00000000..2dd67fb3 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/IOthYs7DeviceService.java @@ -0,0 +1,133 @@ +package org.dromara.other.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +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.vo.ys7device.OthYs7DeviceVo; + +import java.util.Collection; +import java.util.List; + +/** + * 萤石摄像头Service接口 + * + * @author lcj + * @date 2025-06-13 + */ +public interface IOthYs7DeviceService extends IService { + + /** + * 查询萤石摄像头 + * + * @param id 主键 + * @return 萤石摄像头 + */ + OthYs7DeviceVo queryById(Long id); + + /** + * 分页查询萤石摄像头列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 萤石摄像头分页列表 + */ + TableDataInfo queryPageList(OthYs7DeviceQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的萤石摄像头列表 + * + * @param req 查询条件 + * @return 萤石摄像头列表 + */ + List queryList(OthYs7DeviceQueryReq req); + + /** + * 修改萤石摄像头 + * + * @param req 萤石摄像头 + * @return 是否修改成功 + */ + Boolean updateByBo(OthYs7DeviceUpdateReq req); + + /** + * 设备分配项目 + * + * @param req 萤石摄像头 + * @return 是否分配成功 + */ + Boolean updateWithProject(OthYs7DeviceWithProjectReq req); + + /** + * 修改萤石摄像头视频加密 + * + * @param req 萤石摄像头 + * @return 是否修改成功 + */ + Boolean updateVideoEncrypted(OthYs7DeviceUpdateEncryptedReq req); + + /** + * 校验并批量删除萤石摄像头信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取萤石摄像头视图 + * + * @param ys7Device 萤石摄像头 + * @return 萤石摄像头视图 + */ + OthYs7DeviceVo getVo(OthYs7Device ys7Device); + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(OthYs7DeviceQueryReq req); + + /** + * 获取萤石摄像头分页对象视图 + * + * @param ys7DevicePage 萤石摄像头分页对象 + * @return 萤石摄像头分页对象视图 + */ + Page getVoPage(Page ys7DevicePage); + + /** + * 获取萤石摄像对象 + * + * @param deviceResponseVo 萤石摄像数据 + * @return 萤石摄像对象 + */ + OthYs7Device getEntity(Ys7QueryDeviceResponseVo deviceResponseVo); + + /** + * 获取萤石摄像对象列表 + * + * @param deviceResponseVoList 萤石摄像数据列表 + * @return 萤石摄像对象列表 + */ + List getEntityList(List deviceResponseVoList); + + /** + * 根据云端数据保存或更新萤石摄像对象列表 + * + * @param deviceResponseVoList 云端萤石摄像数据列表 + * @return 是否有值发生更改 + */ + Boolean saveOrUpdateByDeviceList(List deviceResponseVoList); + +} 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 new file mode 100644 index 00000000..c670f163 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthDevicePresetServiceImpl.java @@ -0,0 +1,214 @@ +package org.dromara.other.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +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.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.vo.devicepreset.OthDevicePresetVo; +import org.dromara.other.mapper.OthDevicePresetMapper; +import org.dromara.other.service.IOthDevicePresetService; +import org.dromara.other.service.IOthYs7DeviceService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +/** + * 摄像头预置位Service业务层处理 + * + * @author lcj + * @date 2025-06-13 + */ +@Service +public class OthDevicePresetServiceImpl extends ServiceImpl + implements IOthDevicePresetService { + + @Resource + private IOthYs7DeviceService othYs7DeviceService; + + /** + * 查询摄像头预置位 + * + * @param id 主键 + * @return 摄像头预置位 + */ + @Override + public OthDevicePresetVo queryById(Long id) { + OthDevicePreset devicePreset = this.getById(id); + if (devicePreset == null) { + throw new RuntimeException("摄像头预置位信息不存在"); + } + return this.getVo(devicePreset); + } + + /** + * 分页查询摄像头预置位列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 摄像头预置位分页列表 + */ + @Override + public TableDataInfo queryPageList(OthDevicePresetQueryReq req, PageQuery pageQuery) { + Page result = this.page(pageQuery.build(), this.buildQueryWrapper(req)); + return TableDataInfo.build(this.getVoPage(result)); + } + + /** + * 查询符合条件的摄像头预置位列表 + * + * @param req 查询条件 + * @return 摄像头预置位列表 + */ + @Override + public List queryList(OthDevicePresetQueryReq req) { + LambdaQueryWrapper lqw = buildQueryWrapper(req); + return this.list(lqw).stream().map(this::getVo).toList(); + } + + /** + * 新增摄像头预置位 + * + * @param req 摄像头预置位 + * @return 新增摄像头预置位主键id + */ + @Override + public Long insertByBo(OthDevicePresetCreateReq req) { + OthDevicePreset devicePreset = new OthDevicePreset(); + BeanUtils.copyProperties(req, devicePreset); + validEntityBeforeSave(devicePreset, true); + boolean result = this.save(devicePreset); + if (!result) { + throw new ServiceException("摄像头预置位信息新增失败", HttpStatus.ERROR); + } + return devicePreset.getId(); + } + + /** + * 修改摄像头预置位 + * + * @param req 摄像头预置位 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(OthDevicePresetUpdateReq req) { + OthDevicePreset devicePreset = new OthDevicePreset(); + BeanUtils.copyProperties(req, devicePreset); + validEntityBeforeSave(devicePreset, false); + OthDevicePreset oldDevicePreset = this.getById(req.getId()); + if (oldDevicePreset == null) { + throw new ServiceException("修改摄像头预置位信息失败,数据不存在", HttpStatus.NOT_FOUND); + } + boolean result = this.updateById(devicePreset); + if (!result) { + throw new ServiceException("摄像头预置位信息更新失败", HttpStatus.ERROR); + } + return true; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(OthDevicePreset entity, Boolean create) { + //TODO 做一些数据校验,如唯一约束 + String deviceSerial = entity.getDeviceSerial(); + if (create) { + if (StringUtils.isBlank(deviceSerial)) { + throw new ServiceException("设备序列号不能为空", HttpStatus.BAD_REQUEST); + } + } + if (StringUtils.isNotBlank(deviceSerial)) { + Long count = othYs7DeviceService.lambdaQuery() + .eq(OthYs7Device::getDeviceSerial, deviceSerial) + .count(); + if (count <= 0) { + throw new ServiceException("设备不存在", HttpStatus.BAD_REQUEST); + } + } + } + + /** + * 校验并批量删除摄像头预置位信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 获取摄像头预置位视图 + * + * @param devicePreset 摄像头预置位 + * @return 摄像头预置位视图 + */ + @Override + public OthDevicePresetVo getVo(OthDevicePreset devicePreset) { + OthDevicePresetVo vo = new OthDevicePresetVo(); + if (devicePreset == null) { + return vo; + } + BeanUtils.copyProperties(devicePreset, vo); + return vo; + } + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(OthDevicePresetQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + String deviceSerial = req.getDeviceSerial(); + Long channelNo = req.getChannelNo(); + Long index = req.getIndex(); + String name = req.getName(); + 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); + return lqw; + } + + /** + * 获取摄像头预置位分页对象视图 + * + * @param devicePresetPage 摄像头预置位分页对象 + * @return 摄像头预置位分页对象视图 + */ + @Override + public Page getVoPage(Page devicePresetPage) { + List devicePresetList = devicePresetPage.getRecords(); + Page devicePresetVoPage = new Page<>( + devicePresetPage.getCurrent(), + devicePresetPage.getSize(), + devicePresetPage.getTotal()); + if (CollUtil.isEmpty(devicePresetList)) { + return devicePresetVoPage; + } + List devicePresetVoList = devicePresetList.stream().map(this::getVo).toList(); + devicePresetVoPage.setRecords(devicePresetVoList); + return devicePresetVoPage; + } +} 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 new file mode 100644 index 00000000..32eb1807 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceServiceImpl.java @@ -0,0 +1,407 @@ +package org.dromara.other.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.HttpStatus; +import org.dromara.common.core.exception.ServiceException; +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.manager.ys7manager.Ys7RequestUtils; +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.enums.OthVideoEncryptedEnum; +import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo; +import org.dromara.other.mapper.OthYs7DeviceMapper; +import org.dromara.other.service.IOthYs7DeviceService; +import org.dromara.project.domain.BusProject; +import org.dromara.project.service.IBusProjectService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 萤石摄像头Service业务层处理 + * + * @author lcj + * @date 2025-06-13 + */ +@Slf4j +@Service +public class OthYs7DeviceServiceImpl extends ServiceImpl + implements IOthYs7DeviceService { + + @Resource + private IBusProjectService projectService; + + @Resource + private Ys7Manager ys7Manager; + + /** + * 查询萤石摄像头 + * + * @param id 主键 + * @return 萤石摄像头 + */ + @Override + public OthYs7DeviceVo queryById(Long id) { + OthYs7Device ys7Device = this.getById(id); + if (ys7Device == null) { + throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(ys7Device); + } + + /** + * 分页查询萤石摄像头列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 萤石摄像头分页列表 + */ + @Override + public TableDataInfo queryPageList(OthYs7DeviceQueryReq req, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(req); + Page result = this.page(pageQuery.build(), lqw); + return TableDataInfo.build(this.getVoPage(result)); + } + + /** + * 查询符合条件的萤石摄像头列表 + * + * @param req 查询条件 + * @return 萤石摄像头列表 + */ + @Override + public List queryList(OthYs7DeviceQueryReq req) { + LambdaQueryWrapper lqw = buildQueryWrapper(req); + return this.list(lqw).stream().map(this::getVo).toList(); + } + + /** + * 修改萤石摄像头 + * + * @param req 萤石摄像头 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(OthYs7DeviceUpdateReq req) { + // 将实体类和 DTO 进行转换 + OthYs7Device ys7Device = new OthYs7Device(); + BeanUtils.copyProperties(req, ys7Device); + // 数据校验 + OthYs7Device oldYs7Device = this.getById(req.getId()); + if (oldYs7Device == null) { + throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND); + } + validEntityBeforeSave(ys7Device); + // 判断是否更新名称 + String deviceName = req.getDeviceName(); + if (deviceName != null && !deviceName.equals(oldYs7Device.getDeviceName())) { + Long count = this.lambdaQuery() + .eq(OthYs7Device::getDeviceName, req.getDeviceName()) + .count(); + if (count > 0) { + throw new ServiceException("已存在同名萤石摄像头", HttpStatus.CONFLICT); + } + String token = ys7Manager.getToken(); + Boolean result = Ys7RequestUtils.updateDeviceName(token, oldYs7Device.getDeviceSerial(), deviceName); + if (!result) { + throw new ServiceException("更新云端萤石摄像头名称异常", HttpStatus.ERROR); + } + } + boolean result = this.updateById(ys7Device); + if (!result) { + throw new ServiceException("更新萤石摄像头信息异常", HttpStatus.ERROR); + } + return true; + } + + /** + * 设备分配项目 + * + * @param req 萤石摄像头 + * @return 是否分配成功 + */ + @Override + public Boolean updateWithProject(OthYs7DeviceWithProjectReq req) { + Long id = req.getId(); + Long projectId = req.getProjectId(); + // 参数校验 + if (id == null || projectId == null) { + throw new ServiceException("参数为空", HttpStatus.BAD_REQUEST); + } + OthYs7Device ys7Device = this.getById(id); + if (ys7Device == null) { + throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND); + } + BusProject project = projectService.getById(projectId); + if (project == null) { + throw new ServiceException("项目信息不存在", HttpStatus.NOT_FOUND); + } + // 权限校验 + Long userId = LoginHelper.getUserId(); + projectService.validAuth(projectId, userId); + // 更新 + boolean update = this.lambdaUpdate() + .eq(OthYs7Device::getId, id) + .set(OthYs7Device::getProjectId, projectId) + .update(); + if (!update) { + throw new ServiceException("更新萤石摄像头信息异常", HttpStatus.ERROR); + } + return true; + } + + /** + * 修改萤石摄像头视频加密 + * + * @param req 萤石摄像头 + * @return 是否修改成功 + */ + @Override + public Boolean updateVideoEncrypted(OthYs7DeviceUpdateEncryptedReq req) { + Long id = req.getId(); + Integer videoEncrypted = req.getVideoEncrypted(); + // 参数校验 + if (id == null || videoEncrypted == null) { + throw new ServiceException("参数为空", HttpStatus.BAD_REQUEST); + } + OthYs7Device ys7Device = this.getById(id); + if (ys7Device == null) { + throw new ServiceException("萤石摄像头信息不存在", HttpStatus.NOT_FOUND); + } + if (videoEncrypted.equals(ys7Device.getVideoEncrypted())) { + return true; + } + String text = OthVideoEncryptedEnum.getTextByValue(videoEncrypted); + if (text == null) { + throw new ServiceException("参数错误,未知状态", HttpStatus.BAD_REQUEST); + } + boolean update = this.lambdaUpdate() + .eq(OthYs7Device::getId, id) + .set(OthYs7Device::getVideoEncrypted, videoEncrypted) + .update(); + if (!update) { + throw new ServiceException("更新萤石摄像头信息异常", HttpStatus.ERROR); + } + return true; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(OthYs7Device entity) { + //TODO 做一些数据校验,如唯一约束 + Long projectId = entity.getProjectId(); + if (projectId != null && projectId != 0) { + if (projectService.getById(projectId) == null) { + throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND); + } + } + } + + /** + * 校验并批量删除萤石摄像头信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 获取萤石摄像头视图 + * + * @param ys7Device 萤石摄像头 + * @return 萤石摄像头视图 + */ + @Override + public OthYs7DeviceVo getVo(OthYs7Device ys7Device) { + // 对象转封装类 + OthYs7DeviceVo ys7DeviceVo = new OthYs7DeviceVo(); + if (ys7Device == null) { + return ys7DeviceVo; + } + BeanUtils.copyProperties(ys7Device, ys7DeviceVo); + Long projectId = ys7Device.getProjectId(); + if (projectId != null && !projectId.equals(0L)) { + BusProject project = projectService.getById(projectId); + ys7DeviceVo.setProjectName(project.getProjectName()); + } + return ys7DeviceVo; + } + + /** + * 构建查询条件封装 + * + * @param req 查询条件 + * @return 查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(OthYs7DeviceQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + String deviceSerial = req.getDeviceSerial(); + Long projectId = req.getProjectId(); + String deviceName = req.getDeviceName(); + String deviceType = req.getDeviceType(); + String deviceVersion = req.getDeviceVersion(); + Long status = req.getStatus(); + lqw.eq(ObjectUtils.isNotEmpty(projectId), OthYs7Device::getProjectId, projectId) + .or() + .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); + return lqw; + } + + /** + * 获取萤石摄像头分页对象视图 + * + * @param ys7DevicePage 萤石摄像头分页对象 + * @return 萤石摄像头分页对象视图 + */ + @Override + public Page getVoPage(Page ys7DevicePage) { + List ys7DeviceList = ys7DevicePage.getRecords(); + Page ys7DeviceVoPage = new Page<>( + ys7DevicePage.getCurrent(), + ys7DevicePage.getSize(), + ys7DevicePage.getTotal()); + if (CollUtil.isEmpty(ys7DeviceList)) { + return ys7DeviceVoPage; + } + // 获取项目列表 + Set projectIdList = ys7DeviceList.stream().map(OthYs7Device::getProjectId).collect(Collectors.toSet()); + List projectList = projectService.lambdaQuery() + .select(BusProject::getId, BusProject::getProjectName) + .in(BusProject::getId, projectIdList) + .list(); + Map projectMap = projectList.stream().collect(Collectors.toMap(BusProject::getId, project -> project)); + // 对象列表 => 封装对象列表 + List ys7DeviceVoList = ys7DeviceList.stream().map(ys7Device -> { + OthYs7DeviceVo ys7DeviceVo = new OthYs7DeviceVo(); + BeanUtils.copyProperties(ys7Device, ys7DeviceVo); + Long projectId = ys7Device.getProjectId(); + if (projectId != null && !projectId.equals(0L)) { + BusProject project = projectMap.get(projectId); + ys7DeviceVo.setProjectName(project.getProjectName()); + } + return ys7DeviceVo; + }).toList(); + ys7DeviceVoPage.setRecords(ys7DeviceVoList); + return ys7DeviceVoPage; + } + + /** + * 获取萤石摄像对象 + * + * @param deviceResponseVo 萤石摄像数据 + * @return 萤石摄像对象 + */ + @Override + public OthYs7Device getEntity(Ys7QueryDeviceResponseVo deviceResponseVo) { + OthYs7Device ys7Device = new OthYs7Device(); + if (deviceResponseVo == null) { + return ys7Device; + } + ys7Device.setDeviceSerial(deviceResponseVo.getDeviceSerial()); + ys7Device.setDeviceName(deviceResponseVo.getDeviceName()); + ys7Device.setDeviceType(deviceResponseVo.getDeviceType()); + ys7Device.setStatus(deviceResponseVo.getStatus()); + ys7Device.setDefence(Long.valueOf(deviceResponseVo.getDefence())); + ys7Device.setDeviceVersion(deviceResponseVo.getDeviceVersion()); + ys7Device.setPosition(deviceResponseVo.getNetAddress()); + ys7Device.setDeviceCreateTime(new Date(deviceResponseVo.getAddTime())); + ys7Device.setDeviceUpdateTime(new Date(deviceResponseVo.getUpdateTime())); + ys7Device.setRiskLevel(deviceResponseVo.getRiskLevel()); + return ys7Device; + } + + /** + * 获取萤石摄像对象列表 + * + * @param deviceResponseVoList 萤石摄像数据列表 + * @return 萤石摄像对象列表 + */ + @Override + public List getEntityList(List deviceResponseVoList) { + if (CollUtil.isEmpty(deviceResponseVoList)) { + return List.of(); + } + return deviceResponseVoList.stream().map(this::getEntity).toList(); + } + + /** + * 根据云端数据保存或更新萤石摄像对象列表 + * + * @param deviceResponseVoList 云端萤石摄像数据列表 + * @return 是否有值发生更改 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean saveOrUpdateByDeviceList(List deviceResponseVoList) { + if (deviceResponseVoList == null) { + return false; + } + List deviceList = this.getEntityList(deviceResponseVoList); + // 查询数据库中的数据并构建 Map + Map entityMap = this.list().stream() + .collect(Collectors.toMap( + OthYs7Device::getDeviceSerial, + Function.identity(), + (a, b) -> a)); + // 记录日志 + StringBuffer updateLog = new StringBuffer(); + StringBuffer saveLog = new StringBuffer(); + // 遍历设备列表,设置已存在的 id + List resultList = deviceList.stream() + .peek(device -> { + OthYs7Device existing = entityMap.get(device.getDeviceSerial()); + if (existing != null) { + device.setId(existing.getId()); + updateLog.append("[") + .append(device.getDeviceName()) + .append(",") + .append(device.getDeviceSerial()) + .append("]"); + } else { + saveLog.append("[") + .append(device.getDeviceName()) + .append(",") + .append(device.getDeviceSerial()) + .append("]"); + } + }) + .toList(); + log.info("需新增信息设备:{}", saveLog); + log.info("需修改信息设备:{}", updateLog); + // 更新或保存设备列表 + return saveOrUpdateBatch(resultList); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/constant/PgsProgressCategoryConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/constant/PgsProgressCategoryConstant.java index 3270db89..9233d48c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/constant/PgsProgressCategoryConstant.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/constant/PgsProgressCategoryConstant.java @@ -8,6 +8,11 @@ import java.util.List; */ public interface PgsProgressCategoryConstant { + /** + * 顶级父级id + */ + Long TOP_PARENT_ID = 0L; + /** * 项目公共进度类别ID */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/PgsProgressCategory.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/PgsProgressCategory.java index 6dd8b774..ff63bc10 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/PgsProgressCategory.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/PgsProgressCategory.java @@ -1,7 +1,6 @@ package org.dromara.progress.domain; import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,7 +8,6 @@ import org.dromara.common.mybatis.core.domain.BaseEntity; import java.io.Serial; import java.math.BigDecimal; -import java.util.Date; /** * 进度类别对象 pgs_progress_category @@ -46,6 +44,11 @@ public class PgsProgressCategory extends BaseEntity { */ private Long matrixId; + /** + * 方阵名称 + */ + private String matrixName; + /** * 类别名称 */ @@ -91,15 +94,4 @@ public class PgsProgressCategory extends BaseEntity { */ private String remark; - /** - * 删除时间 - */ - private Date deletedAt; - - /** - * 是否删除(0正常 1删除) - */ - @TableLogic - private Long isDelete; - } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryMatrixVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryMatrixVo.java index cc11f3a1..c083ea97 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryMatrixVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryMatrixVo.java @@ -27,6 +27,11 @@ public class PgsProgressCategoryMatrixVo implements Serializable { */ private Long matrixId; + /** + * 方阵名称 + */ + private String name; + /** * 总数量/百分比 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryProjectVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryProjectVo.java index e87f93ec..af3d419d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryProjectVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategoryProjectVo.java @@ -24,6 +24,11 @@ public class PgsProgressCategoryProjectVo implements Serializable { */ private Long projectId; + /** + * 项目名称 + */ + private String name; + /** * 总数量/百分比 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategorySubProjectVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategorySubProjectVo.java index e17614f4..33e5f65f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategorySubProjectVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/domain/vo/progresscategory/PgsProgressCategorySubProjectVo.java @@ -28,6 +28,11 @@ public class PgsProgressCategorySubProjectVo implements Serializable { */ private Long subProjectId; + /** + * 子项目名称 + */ + private String name; + /** * 总数量/百分比 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java index 3d491586..e9c59dbf 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/IPgsProgressCategoryService.java @@ -2,6 +2,7 @@ package org.dromara.progress.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.facility.domain.FacMatrix; import org.dromara.progress.domain.PgsProgressCategory; import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryCreateReq; import org.dromara.progress.domain.dto.progresscategory.PgsProgressCategoryQueryReq; @@ -98,11 +99,12 @@ public interface IPgsProgressCategoryService extends IService matrixIds); + Boolean insertByTemplate(Long projectId, List matrixList, List oldMatrixList); /** * 根据id获取进度类别坐标信息 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java index 54b46c2f..cb27cfea 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressCategoryServiceImpl.java @@ -113,7 +113,13 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl queryList(PgsProgressCategoryQueryReq req) { - List list = this.list(this.buildQueryWrapper(req)); + Long matrixId = req.getMatrixId(); + if (matrixService.getById(matrixId) == null) { + throw new ServiceException("方阵不存在", HttpStatus.BAD_REQUEST); + } + List list = this.lambdaQuery() + .eq(PgsProgressCategory::getMatrixId, matrixId) + .list(); return this.getVoList(list); } @@ -275,7 +281,7 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl matrixIds) { + public Boolean insertByTemplate(Long projectId, List matrixList, List oldMatrixList) { + List oldMatrixIdList = oldMatrixList.stream().map(FacMatrix::getId).toList(); // 获取模板进度类别 List categoryTemplateList = pgsProgressCategoryTemplateService.lambdaQuery() .in(PgsProgressCategoryTemplate::getProjectId, projectId, PgsProgressCategoryConstant.PUBLIC_PROJECT_ID) @@ -339,10 +347,45 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl> oldPercentageCategoryMap = new HashMap<>(); + Map> oldPlanMap = new HashMap<>(); + Map> oldPlanDetailMap = new HashMap<>(); + if (CollUtil.isNotEmpty(oldMatrixList)) { + List oldPercentageCategoryList = this.lambdaQuery() + .in(PgsProgressCategory::getMatrixId, oldMatrixIdList) + .ne(PgsProgressCategory::getPid, PgsProgressCategoryConstant.TOP_PARENT_ID) + .eq(PgsProgressCategory::getUnitType, PgsProgressUnitTypeEnum.PERCENTAGE.getValue()) + .list(); + oldPercentageCategoryMap = oldPercentageCategoryList.stream() + .collect(Collectors.groupingBy(item -> item.getMatrixName() + "_" + item.getWorkType())); + // 获取百分比设施计划数据 + List oldPercentageCategoryIdList = oldPercentageCategoryList.stream().map(PgsProgressCategory::getId).toList(); + if (CollUtil.isNotEmpty(oldPercentageCategoryIdList)) { + List oldPlanList = progressPlanService.lambdaQuery() + .select(PgsProgressPlan::getId, PgsProgressPlan::getProgressCategoryId) + .in(PgsProgressPlan::getProgressCategoryId, oldPercentageCategoryIdList) + .list(); + oldPlanMap = oldPlanList.stream() + .collect(Collectors.groupingBy(PgsProgressPlan::getProgressCategoryId)); + // 获取百分比设施计划详情数据 + List oldPlanIdList = oldPlanList.stream().map(PgsProgressPlan::getId).toList(); + if (CollUtil.isNotEmpty(oldPlanIdList)) { + List oldPlanDetailList = progressPlanDetailService.lambdaQuery() + .in(PgsProgressPlanDetail::getProgressPlanId, oldPlanIdList) + .list(); + oldPlanDetailMap = oldPlanDetailList.stream() + .collect(Collectors.groupingBy(PgsProgressPlanDetail::getProgressPlanId)); + } + } + } + // 需修改、保存的数据 List newList = new ArrayList<>(); List percentageFacilityList = new ArrayList<>(); + List newPlanList = new ArrayList<>(); + List newPlanDetailList = new ArrayList<>(); // 每个 matrixId 对应一套新的 ID 映射 - for (Long matrixId : matrixIds) { + for (FacMatrix matrix : matrixList) { // templateId -> newId Map localIdMap = new HashMap<>(); List localList = new ArrayList<>(); @@ -355,17 +398,50 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl planList = oldPlanMap.get(oldPercentageCategory.getId()); + // 填充计划数据 + for (PgsProgressPlan plan : planList) { + PgsProgressPlan newPlan = new PgsProgressPlan(); + Long planId = plan.getId(); + newPlan.setId(planId); + newPlan.setProjectId(projectId); + newPlan.setMatrixId(matrix.getId()); + newPlan.setProgressCategoryId(newId); + newPlanList.add(newPlan); + // 填充计划详情数据 + if (CollUtil.isNotEmpty(oldPlanDetailMap) && oldPlanDetailMap.containsKey(planId)) { + List planDetailList = oldPlanDetailMap.get(planId); + for (PgsProgressPlanDetail planDetail : planDetailList) { + PgsProgressPlanDetail newPlanDetail = new PgsProgressPlanDetail(); + newPlanDetail.setId(planDetail.getId()); + newPlanDetail.setProgressCategoryId(newId); + newPlanDetailList.add(newPlanDetail); + } + } + } + } + newCategory.setCompleted(oldPercentageCategory.getCompleted()); + newCategory.setPlanTotal(oldPercentageCategory.getPlanTotal()); + newCategory.setIsDelay(oldPercentageCategory.getIsDelay()); + newCategory.setStatus(oldPercentageCategory.getStatus()); + } newCategory.setTotal(BigDecimal.valueOf(100)); FacPercentageFacility percentageFacility = new FacPercentageFacility(); percentageFacility.setProjectId(projectId); - percentageFacility.setMatrixId(matrixId); + percentageFacility.setMatrixId(matrix.getId()); percentageFacility.setProgressCategoryId(newId); percentageFacility.setProgressCategoryName(template.getName()); percentageFacilityList.add(percentageFacility); @@ -380,10 +456,31 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl lqw = new LambdaQueryWrapper<>(); + lqw.eq(PgsProgressCategory::getProjectId, projectId); + long oldCategoryCount = this.count(lqw); + if (oldCategoryCount > 0) { + boolean remove = this.remove(lqw); + if (!remove) { + throw new ServiceException("删除旧进度类别失败", HttpStatus.ERROR); + } + } + // 批量保存新进度类别 boolean result = this.saveBatch(newList); if (!result) { throw new ServiceException("创建进度类别失败", HttpStatus.ERROR); } + // 删除旧数据 + LambdaQueryWrapper percentageFacilityLqw = new LambdaQueryWrapper<>(); + percentageFacilityLqw.eq(FacPercentageFacility::getMatrixId, oldMatrixIdList); + long count = percentageFacilityService.count(percentageFacilityLqw); + if (count > 0) { + boolean remove = percentageFacilityService.remove(percentageFacilityLqw); + if (!remove) { + throw new ServiceException("删除旧百分比设施数据失败", HttpStatus.ERROR); + } + } // 保存百分比设施 if (CollUtil.isNotEmpty(percentageFacilityList)) { boolean save = percentageFacilityService.saveBatch(percentageFacilityList); @@ -391,6 +488,20 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl subProjectIdList = subProjectList.stream().map(BusProject::getId).toList(); // 获取方阵信息 List matrixList = matrixService.lambdaQuery() - .select(FacMatrix::getId) + .select(FacMatrix::getId, FacMatrix::getProjectId) .in(FacMatrix::getProjectId, subProjectIdList) .list(); if (CollUtil.isEmpty(matrixList)) { @@ -527,7 +638,12 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl progressCategoryList = this.lambdaQuery() - .select(PgsProgressCategory::getId, PgsProgressCategory::getStatus, PgsProgressCategory::getMatrixId) + .select(PgsProgressCategory::getId, + PgsProgressCategory::getStatus, + PgsProgressCategory::getMatrixId, + PgsProgressCategory::getTotal, + PgsProgressCategory::getPlanTotal, + PgsProgressCategory::getCompleted) .in(PgsProgressCategory::getMatrixId, matrixIdList) .list(); // 分组:matrixId -> categoryList @@ -573,6 +689,7 @@ public class PgsProgressCategoryServiceImpl extends ServiceImpl progressPlan.getPlanNumber()) { + // todo 是否判断完成百分比是否大于计划进度 +/* if (finishedNumberTotal + finishedNumber > progressPlan.getPlanNumber()) { throw new ServiceException("完成百分比不能大于计划进度", HttpStatus.BAD_REQUEST); - } + }*/ progressPlanDetail.setFinishedNumber(finishedNumber); // 更新 boolean update = this.updateById(progressPlanDetail); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusProjectController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusProjectController.java index d916a0bf..3fe7d798 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusProjectController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/controller/BusProjectController.java @@ -61,6 +61,16 @@ public class BusProjectController extends BaseController { return R.ok(projectService.querySubList(id)); } + /** + * 查询项目下的子项目方阵列表 + */ + @SaCheckPermission("project:project:list") + @GetMapping("/list/sub/matrix/{id}") + public R> listSubProjectMatrix(@NotNull(message = "项目id不能为空") + @PathVariable Long id) { + return R.ok(projectService.querySubProjectMatrixList(id)); + } + /** * 导出项目列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/project/BusSubProjectMatrixVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/project/BusSubProjectMatrixVo.java new file mode 100644 index 00000000..27491458 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/project/BusSubProjectMatrixVo.java @@ -0,0 +1,35 @@ +package org.dromara.project.domain.vo.project; + +import lombok.Data; +import org.dromara.facility.domain.vo.matrix.FacMatrixBySubProjectVo; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @author lcj + * @date 2025/6/10 15:06 + */ +@Data +public class BusSubProjectMatrixVo implements Serializable { + + @Serial + private static final long serialVersionUID = 5817777295498328412L; + + /** + * id + */ + private Long projectId; + + /** + * 项目名称 + */ + private String name; + + /** + * 方阵列表 + */ + private List children; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java index 0a4329d4..c089a9ac 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusProjectService.java @@ -56,6 +56,14 @@ public interface IBusProjectService extends IService { */ List querySubList(Long id); + /** + * 获取项目子项目方阵信息 + * + * @param id 项目id + * @return 子项目方阵信息列表 + */ + List querySubProjectMatrixList(Long id); + /** * 查询当前登录用户项目列表以及项目列表下的分包公司列表 * diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java index 02d01f3f..0320b1bb 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectServiceImpl.java @@ -26,6 +26,9 @@ 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.facility.domain.FacMatrix; +import org.dromara.facility.domain.vo.matrix.FacMatrixBySubProjectVo; +import org.dromara.facility.service.IFacMatrixService; import org.dromara.manager.weathermanager.WeatherConstant; import org.dromara.manager.weathermanager.WeatherManager; import org.dromara.project.constant.BusProjectConstant; @@ -82,6 +85,10 @@ public class BusProjectServiceImpl extends ServiceImpl WEATHER_CACHE = Caffeine.newBuilder().initialCapacity(1024) .maximumSize(10000L) @@ -164,6 +171,62 @@ public class BusProjectServiceImpl extends ServiceImpl querySubProjectMatrixList(Long id) { + // 获取项目信息 + BusProject project = this.getById(id); + if (project == null) { + throw new ServiceException("查询项目不存在", HttpStatus.NOT_FOUND); + } + // 获取项目下的子项目信息 + List subProjectList = this.lambdaQuery() + .select(BusProject::getId, BusProject::getProjectName) + .eq(BusProject::getPId, id) + .list(); + if (CollUtil.isEmpty(subProjectList)) { + return List.of(); + } + List subProjectIdList = subProjectList.stream().map(BusProject::getId).toList(); + // 获取方阵信息 + List matrixList = matrixService.lambdaQuery() + .select(FacMatrix::getId, FacMatrix::getProjectId, FacMatrix::getMatrixName) + .in(FacMatrix::getProjectId, subProjectIdList) + .list(); + if (CollUtil.isEmpty(matrixList)) { + return subProjectList.stream().map(subProject -> { + BusSubProjectMatrixVo vo = new BusSubProjectMatrixVo(); + vo.setProjectId(subProject.getId()); + vo.setName(subProject.getProjectName()); + vo.setChildren(List.of()); + return vo; + }).toList(); + } + // 获取子项目下的方阵信息 + Map> matrixMap = matrixList.stream() + .collect(Collectors.groupingBy(FacMatrix::getProjectId)); + return subProjectList.stream().map(subProject -> { + BusSubProjectMatrixVo vo = new BusSubProjectMatrixVo(); + vo.setProjectId(subProject.getId()); + vo.setName(subProject.getProjectName()); + if (matrixMap.containsKey(subProject.getId())) { + List subProjectMatrix = matrixMap.get(subProject.getId()); + vo.setChildren(subProjectMatrix.stream().map(matrix -> { + FacMatrixBySubProjectVo matrixVo = new FacMatrixBySubProjectVo(); + matrixVo.setMatrixId(matrix.getId()); + matrixVo.setName(matrix.getMatrixName()); + return matrixVo; + }).toList()); + } + return vo; + }).toList(); + } + /** * 查询当前登录用户项目列表以及项目列表下的分包公司列表 * @@ -520,7 +583,7 @@ public class BusProjectServiceImpl extends ServiceImpl subProjectVoList = new ArrayList<>(); - if (subProjectMap.containsKey(project.getId())){ + if (subProjectMap.containsKey(project.getId())) { subProjectVoList = subProjectMap.get(project.getId()).stream().map(subProject -> { BusSubProjectVo subProjectVo = new BusSubProjectVo(); BeanUtils.copyProperties(subProject, subProjectVo); @@ -542,10 +605,10 @@ public class BusProjectServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("project_id", projectId); - queryWrapper.eq("user_id", userId); - if (userProjectRelevancyService.count(queryWrapper) <= 0) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(BusUserProjectRelevancy::getProjectId, projectId); + lqw.eq(BusUserProjectRelevancy::getUserId, userId); + if (userProjectRelevancyService.count(lqw) <= 0) { throw new ServiceException("当前用户无该项目权限操作", HttpStatus.FORBIDDEN); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthDevicePresetMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthDevicePresetMapper.xml new file mode 100644 index 00000000..25cffab8 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthDevicePresetMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthYs7DeviceMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthYs7DeviceMapper.xml new file mode 100644 index 00000000..39ddbb06 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/other/OthYs7DeviceMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/script/sql/menuInitValue.sql b/xinnengyuan/script/sql/menuInitValue.sql index ffaf1747..41b1304f 100644 --- a/xinnengyuan/script/sql/menuInitValue.sql +++ b/xinnengyuan/script/sql/menuInitValue.sql @@ -497,3 +497,43 @@ values(1927984223038324742, '进度类别模版删除', 1927984223038324738, '4' insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) values(1927984223038324743, '进度类别模版导出', 1927984223038324738, '5', '#', '', 1, 0, 'F', '0', '0', 'progress:progressCategoryTemplate:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147969, '萤石摄像头', '1933341785996664834', '1', 'ys7Device', 'other/ys7Device/index', 1, 0, 'C', '0', '0', 'other:ys7Device:list', '#', 103, 1, sysdate(), null, null, '萤石摄像头菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147970, '萤石摄像头查询', 1933345067448147969, '1', '#', '', 1, 0, 'F', '0', '0', 'other:ys7Device:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147971, '萤石摄像头新增', 1933345067448147969, '2', '#', '', 1, 0, 'F', '0', '0', 'other:ys7Device:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147972, '萤石摄像头修改', 1933345067448147969, '3', '#', '', 1, 0, 'F', '0', '0', 'other:ys7Device:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147973, '萤石摄像头删除', 1933345067448147969, '4', '#', '', 1, 0, 'F', '0', '0', 'other:ys7Device:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933345067448147974, '萤石摄像头导出', 1933345067448147969, '5', '#', '', 1, 0, 'F', '0', '0', 'other:ys7Device:export', '#', 103, 1, sysdate(), null, null, ''); + +-- 菜单 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406401, '摄像头预置位', '1933345067448147969', '1', 'devicePreset', 'other/devicePreset/index', 1, 0, 'C', '0', '0', 'other:devicePreset:list', '#', 103, 1, sysdate(), null, null, '摄像头预置位菜单'); + +-- 按钮 SQL +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406402, '摄像头预置位查询', 1933445976098406401, '1', '#', '', 1, 0, 'F', '0', '0', 'other:devicePreset:query', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406403, '摄像头预置位新增', 1933445976098406401, '2', '#', '', 1, 0, 'F', '0', '0', 'other:devicePreset:add', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406404, '摄像头预置位修改', 1933445976098406401, '3', '#', '', 1, 0, 'F', '0', '0', 'other:devicePreset:edit', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406405, '摄像头预置位删除', 1933445976098406401, '4', '#', '', 1, 0, 'F', '0', '0', 'other:devicePreset:remove', '#', 103, 1, sysdate(), null, null, ''); + +insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) +values(1933445976098406406, '摄像头预置位导出', 1933445976098406401, '5', '#', '', 1, 0, 'F', '0', '0', 'other:devicePreset:export', '#', 103, 1, sysdate(), null, null, ''); diff --git a/xinnengyuan/script/sql/xinnengyuan.sql b/xinnengyuan/script/sql/xinnengyuan.sql index 7084c03a..4cb5b1f0 100644 --- a/xinnengyuan/script/sql/xinnengyuan.sql +++ b/xinnengyuan/script/sql/xinnengyuan.sql @@ -34,7 +34,7 @@ create table `bus_project` PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '项目表' + collate = utf8mb4_general_ci comment = '项目表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS bus_user_project_relevancy; @@ -52,7 +52,7 @@ CREATE TABLE `bus_user_project_relevancy` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '系统用户与项目关联表' + collate = utf8mb4_general_ci comment = '系统用户与项目关联表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS mat_company; @@ -74,7 +74,7 @@ CREATE TABLE `mat_company` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '公司表' + collate = utf8mb4_general_ci comment = '公司表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS mat_materials; @@ -101,7 +101,7 @@ CREATE TABLE `mat_materials` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '材料名称表' + collate = utf8mb4_general_ci comment = '材料名称表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS mat_materials_inventory; @@ -130,7 +130,7 @@ CREATE TABLE `mat_materials_inventory` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目ID' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '材料出/入库表' + collate = utf8mb4_general_ci comment = '材料出/入库表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS `bus_contractor`; @@ -152,7 +152,7 @@ CREATE TABLE `bus_contractor` PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '分包单位' + collate = utf8mb4_general_ci comment = '分包单位' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS `bus_construction_user`; @@ -195,7 +195,7 @@ CREATE TABLE `bus_construction_user` INDEX `idx_phone` (`phone` ASC) USING BTREE comment '电话' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '施工人员表' + collate = utf8mb4_general_ci comment = '施工人员表' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS `bus_project_team`; @@ -216,7 +216,7 @@ CREATE TABLE `bus_project_team` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 - COLLATE = utf8mb4_general_ci comment = '项目班组' + collate = utf8mb4_general_ci comment = '项目班组' ROW_FORMAT = DYNAMIC; DROP TABLE IF EXISTS `bus_project_team_member`; @@ -334,7 +334,7 @@ CREATE TABLE `bus_safety_inspection` `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE -) comment = '安全巡检工单' COLLATE = utf8mb4_unicode_ci; +) comment = '安全巡检工单' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS hse_safety_log; CREATE TABLE `bus_safety_log` @@ -440,7 +440,7 @@ CREATE TABLE `hse_question_user_answer` `deleted_at` datetime null comment '删除时间', `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', PRIMARY KEY (`id`) USING BTREE -) comment = '用户试卷存储' COLLATE = utf8mb4_unicode_ci; +) comment = '用户试卷存储' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `bus_attendance`; CREATE TABLE `bus_attendance` @@ -471,7 +471,7 @@ CREATE TABLE `bus_attendance` INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '人员id', INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_clock_date` (`clock_date` ASC) USING BTREE comment '打卡日期' -) comment = '考勤表' COLLATE = utf8mb4_unicode_ci; +) comment = '考勤表' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `bus_work_wage`; CREATE TABLE `bus_work_wage` @@ -493,7 +493,7 @@ CREATE TABLE `bus_work_wage` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_work_type` (`work_type` ASC) USING BTREE comment '工种' -) comment = '工种薪水' COLLATE = utf8mb4_unicode_ci; +) comment = '工种薪水' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `bus_construction_blacklist`; CREATE TABLE `bus_construction_blacklist` @@ -540,7 +540,7 @@ CREATE TABLE `bus_construction_user_exit` INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id', INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_team_id` (`team_id` ASC) USING BTREE comment '班组id' -) comment = '施工人员入场退场记录信息' COLLATE = utf8mb4_unicode_ci; +) comment = '施工人员入场退场记录信息' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `bus_reissue_card`; CREATE TABLE `bus_reissue_card` @@ -677,7 +677,7 @@ CREATE TABLE `hse_document_safety_meeting` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_pid` (`pid` ASC) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE -) comment = '安全会议纪要' COLLATE = utf8mb4_unicode_ci; +) comment = '安全会议纪要' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS hse_questions_category; CREATE TABLE `hse_questions_category` @@ -689,7 +689,7 @@ CREATE TABLE `hse_questions_category` `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE -) comment = '题库类别' COLLATE = utf8mb4_unicode_ci; +) comment = '题库类别' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS qlt_quality_inspection; CREATE TABLE `qlt_quality_inspection` @@ -721,7 +721,7 @@ CREATE TABLE `qlt_quality_inspection` PRIMARY KEY (`id`) USING BTREE, INDEX `project_id` (`project_id` ASC) USING BTREE, INDEX `team_id` (`team_id` ASC) USING BTREE -) comment = '质量-检查工单' COLLATE = utf8mb4_unicode_ci; +) comment = '质量-检查工单' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS qlt_quality_construction_log; CREATE TABLE `qlt_quality_construction_log` @@ -741,7 +741,7 @@ CREATE TABLE `qlt_quality_construction_log` `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE -) comment = '质量-施工日志' COLLATE = utf8mb4_unicode_ci; +) comment = '质量-施工日志' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `app_user`; CREATE TABLE `app_user` @@ -762,7 +762,7 @@ CREATE TABLE `app_user` PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `idx_user_account` (`user_account` ASC) USING BTREE, UNIQUE INDEX `idx_phone` (`phone` ASC) USING BTREE -) comment = 'app用户表' COLLATE = utf8mb4_unicode_ci; +) comment = 'app用户表' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `user_relevancy`; CREATE TABLE `user_relevancy` @@ -773,7 +773,7 @@ CREATE TABLE `user_relevancy` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_app_id` (`app_id` ASC) USING BTREE, INDEX `idx_web_id` (`web_id` ASC) USING BTREE -) comment = '用户关联表' COLLATE = utf8mb4_unicode_ci; +) comment = '用户关联表' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_matrix`; CREATE TABLE `fac_matrix` @@ -791,7 +791,7 @@ CREATE TABLE `fac_matrix` `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' -) comment = '设施-方阵' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-方阵' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_photovoltaic_panel`; CREATE TABLE `fac_photovoltaic_panel` @@ -813,7 +813,7 @@ CREATE TABLE `fac_photovoltaic_panel` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-光伏板' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-光伏板' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_photovoltaic_panel_point`; CREATE TABLE `fac_photovoltaic_panel_point` @@ -835,7 +835,7 @@ CREATE TABLE `fac_photovoltaic_panel_point` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-光伏板桩点' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-光伏板桩点' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_photovoltaic_panel_column`; CREATE TABLE `fac_photovoltaic_panel_column` @@ -857,7 +857,7 @@ CREATE TABLE `fac_photovoltaic_panel_column` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-光伏板立柱' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-光伏板立柱' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_photovoltaic_panel_support`; CREATE TABLE `fac_photovoltaic_panel_support` @@ -879,7 +879,7 @@ CREATE TABLE `fac_photovoltaic_panel_support` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-光伏板支架' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-光伏板支架' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_inverter`; CREATE TABLE `fac_inverter` @@ -901,7 +901,7 @@ CREATE TABLE `fac_inverter` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-逆变器' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-逆变器' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_box_transformer`; CREATE TABLE `fac_box_transformer` @@ -923,7 +923,7 @@ CREATE TABLE `fac_box_transformer` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE, INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE -) comment = '设施-箱变' COLLATE = utf8mb4_unicode_ci; +) comment = '设施-箱变' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `bus_project_file`; CREATE TABLE `bus_project_file` @@ -956,7 +956,7 @@ CREATE TABLE `bus_project_news` `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' -) comment = '项目新闻' COLLATE = utf8mb4_unicode_ci; +) comment = '项目新闻' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `pgs_progress_category_template`; CREATE TABLE `pgs_progress_category_template` @@ -971,7 +971,7 @@ CREATE TABLE `pgs_progress_category_template` PRIMARY KEY (`id`) USING BTREE, INDEX `idx_pid` (`pid` ASC) USING BTREE comment '父类别id', INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' -) comment ='进度类别模版' COLLATE = utf8mb4_unicode_ci; +) comment ='进度类别模版' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `pgs_progress_category`; CREATE TABLE `pgs_progress_category` @@ -997,7 +997,7 @@ CREATE TABLE `pgs_progress_category` INDEX `idx_pid` (`pid` ASC) USING BTREE comment '父类别id', INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE comment '方阵id', INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id' -) comment ='进度类别' COLLATE = utf8mb4_unicode_ci; +) comment ='进度类别' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `fac_percentage_facility`; CREATE TABLE `fac_percentage_facility` @@ -1015,7 +1015,7 @@ CREATE TABLE `fac_percentage_facility` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE comment '方阵id', INDEX `idx_progress_category_id` (`progress_category_id` ASC) USING BTREE comment '进度类别id' -) comment ='设施-百分比设施' COLLATE = utf8mb4_unicode_ci; +) comment ='设施-百分比设施' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `pgs_progress_plan`; CREATE TABLE `pgs_progress_plan` @@ -1040,7 +1040,7 @@ CREATE TABLE `pgs_progress_plan` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_matrix_id` (`matrix_id` ASC) USING BTREE comment '方阵id', INDEX `idx_progress_category_id` (`progress_category_id` ASC) USING BTREE comment '进度类别id' -) comment ='进度计划' COLLATE = utf8mb4_unicode_ci; +) comment ='进度计划' collate = utf8mb4_unicode_ci; DROP TABLE IF EXISTS `pgs_progress_plan_detail`; CREATE TABLE `pgs_progress_plan_detail` @@ -1064,4 +1064,43 @@ CREATE TABLE `pgs_progress_plan_detail` INDEX `idx_project_id` (`project_id` ASC) USING BTREE comment '项目id', INDEX `idx_progress_plan_id` (`progress_plan_id` ASC) USING BTREE comment '进度计划id', INDEX `idx_date` (`date` ASC) USING BTREE comment '计划时间' -) comment ='进度计划详情' COLLATE = utf8mb4_unicode_ci; +) comment ='进度计划详情' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `oth_ys7_device`; +CREATE TABLE `oth_ys7_device` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint default 0 not null comment '项目id', + `device_serial` varchar(255) null comment '设备序列号', + `device_name` varchar(255) null comment '设备名称', + `device_type` varchar(255) null comment '设备型号', + `status` tinyint(4) null comment '设备在线状态(0离线 1在线)', + `defence` bigint null comment '布撤防状态', + `device_version` varchar(255) null comment '固件版本号', + `position` varchar(255) null comment '摄像头坐标信息', + `device_create_time` datetime null comment '设备添加时间', + `device_update_time` datetime null comment '设备最后更新时间', + `risk_level` int null comment '设备风险安全等级(0安全 大于0,值越大,风险越高)', + `video_encrypted` tinyint(4) default 0 not null comment '视频加密(0关闭 1开启)', + `remark` varchar(512) null comment '备注', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + `deleted_at` datetime null comment '删除时间', + `is_delete` tinyint(4) default 0 not null comment '是否删除(0正常 1删除)', + primary key (`id`) using btree, + index `idx_project_id` (`project_id` asc) using btree comment '项目id', + unique index `idx_device_serial` (`device_serial` asc) using btree comment '设备序列号' +) comment = '萤石摄像头' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `oth_device_preset`; +CREATE TABLE `oth_device_preset` +( + `id` bigint not null auto_increment comment '主键id', + `device_serial` varchar(255) null comment '设备序列号', + `channel_no` bigint null comment '通道号', + `index` int null comment '预置点序号', + `name` varchar(255) null comment '预置点', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + primary key (`id`) using btree +) comment = '摄像头预置位' collate = utf8mb4_unicode_ci;