From e492c08eef3f140a6b7bd27d3018a5ad74dfe903 Mon Sep 17 00:00:00 2001 From: lcj <2331845269@qq.com> Date: Wed, 25 Jun 2025 09:08:06 +0800 Subject: [PATCH] =?UTF-8?q?[add]=20=E6=B7=BB=E5=8A=A0=20AI=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=20=E8=AF=86=E5=88=AB=E8=AE=B0=E5=BD=95=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A1=B9=E7=9B=AE=E4=B8=8E=E9=83=A8=E9=97=A8=E5=85=B3?= =?UTF-8?q?=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- drone/.gitignore | 2 + .../cycle/IncSyncYs7DeviceCapturePicData.java | 2 + .../job/cycle/IncSyncYs7DeviceData.java | 3 +- .../enums/SpartaRecTypeEnum.java | 43 ++-- .../OthYs7DeviceImgCreateByCapture.java | 5 + .../impl/OthYs7DeviceImgServiceImpl.java | 23 +- .../project/constant/BusProjectConstant.java | 4 +- .../dromara/project/domain/BusProject.java | 5 + .../service/impl/BusProjectServiceImpl.java | 34 ++- .../BusUserProjectRelevancyServiceImpl.java | 4 +- .../HseRecognizeRecordController.java | 81 +++++++ .../safety/domain/HseRecognizeRecord.java | 97 ++++++++ .../HseRecognizeRecordCreateDto.java | 55 +++++ .../HseRecognizeRecordQueryReq.java | 48 ++++ .../domain/enums/HseRecordCategoryEnum.java | 24 ++ .../recognizerecord/HseRecognizeRecordVo.java | 87 +++++++ .../mapper/HseRecognizeRecordMapper.java | 15 ++ .../service/IHseRecognizeRecordService.java | 87 +++++++ .../impl/HseRecognizeRecordServiceImpl.java | 225 ++++++++++++++++++ .../system/service/ISysDeptService.java | 8 + .../service/impl/SysDeptServiceImpl.java | 14 ++ .../safety/HseRecognizeRecordMapper.xml | 7 + xinnengyuan/script/sql/menuInitValue.sql | 20 ++ xinnengyuan/script/sql/xinnengyuan.sql | 23 +- 24 files changed, 889 insertions(+), 27 deletions(-) create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/controller/HseRecognizeRecordController.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseRecognizeRecord.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordCreateDto.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordQueryReq.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/HseRecordCategoryEnum.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/recognizerecord/HseRecognizeRecordVo.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/HseRecognizeRecordMapper.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IHseRecognizeRecordService.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseRecognizeRecordServiceImpl.java create mode 100644 xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/HseRecognizeRecordMapper.xml diff --git a/drone/.gitignore b/drone/.gitignore index ed8368aa..7c0bc620 100644 --- a/drone/.gitignore +++ b/drone/.gitignore @@ -45,3 +45,5 @@ nbdist/ !*/build/*.java !*/build/*.html !*/build/*.xml + +*.lck diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceCapturePicData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceCapturePicData.java index 3040b963..7041bd8a 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceCapturePicData.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceCapturePicData.java @@ -75,6 +75,7 @@ public class IncSyncYs7DeviceCapturePicData { if (presets != null && !presets.isEmpty()) { for (OthDevicePreset preset : presets) { OthYs7DeviceImgCreateByCapture img = new OthYs7DeviceImgCreateByCapture(); + img.setProjectId(ys7Device.getProjectId()); img.setDeviceSerial(deviceSerial); img.setDeviceName(ys7Device.getDeviceName()); int channelNo = preset.getChannelNo(); @@ -105,6 +106,7 @@ public class IncSyncYs7DeviceCapturePicData { } else { // 如果没有预置位,则直接对默认通道抓图 OthYs7DeviceImgCreateByCapture img = new OthYs7DeviceImgCreateByCapture(); + img.setProjectId(ys7Device.getProjectId()); img.setDeviceSerial(deviceSerial); img.setDeviceName(ys7Device.getDeviceName()); try { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java index 8df18a5e..29ffbfe7 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/job/cycle/IncSyncYs7DeviceData.java @@ -25,7 +25,8 @@ public class IncSyncYs7DeviceData { private IOthYs7DeviceService ys7DeviceService; // 每 5 分钟执行一次 - @Scheduled(cron = "0 */5 * * * ?") + // todo 修改为 5 分钟 + @Scheduled(cron = "0 */10 * * * ?") public void run() { log.info("定时同步摄像头设备数据"); List ys7QueryDeviceList = ys7Manager.queryAllDeviceList(); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/spartamanager/enums/SpartaRecTypeEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/spartamanager/enums/SpartaRecTypeEnum.java index 0c504f8c..778fe4ed 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/spartamanager/enums/SpartaRecTypeEnum.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/spartamanager/enums/SpartaRecTypeEnum.java @@ -12,30 +12,37 @@ import java.util.stream.Collectors; @Getter public enum SpartaRecTypeEnum { - HAT("安全帽识别", "hat"), - HEAD("不戴安全帽识别", "head"), - SMOKE("吸烟识别", "smoke"), - BELT("安全带识别", "belt"), - WASTE("工程垃圾识别(暂无)", "waste"), - EXCAVATOR("挖掘机", "excavator"), - ROLLER("压路机", "Roller"), - TRUCK_CRANE("汽车吊", "Truck_crane"), - LOADER("装载机", "Loader"), - SUBMERSIBLE_DRILLING_RIG("潜挖钻机", "Submersible_drilling_rig"), - SPRINKLER("洒水车", "Sprinkler"), - TRUCK_MOUNTED_CRANE("随车吊", "Truck_mounted_crane"), - TRUCK("货车", "Truck"), - PHO("光伏板", "pho"), - HOLE("洞", "hole"), - SHELVES("架子", "shelves"), - PILE("桩", "pile"); + HAT("安全帽识别", "hat", ""), + HEAD("不戴安全帽识别", "head", "1"), + SMOKE("吸烟识别", "smoke", "3"), + BELT("安全带识别", "belt", "2"), + WASTE("工程垃圾识别(暂无)", "waste", ""), + EXCAVATOR("挖掘机", "excavator", ""), + ROLLER("压路机", "Roller", ""), + TRUCK_CRANE("汽车吊", "Truck_crane", ""), + LOADER("装载机", "Loader", ""), + SUBMERSIBLE_DRILLING_RIG("潜挖钻机", "Submersible_drilling_rig", ""), + SPRINKLER("洒水车", "Sprinkler", ""), + TRUCK_MOUNTED_CRANE("随车吊", "Truck_mounted_crane", ""), + TRUCK("货车", "Truck", ""), + PHO("光伏板", "pho", ""), + HOLE("洞", "hole", ""), + SHELVES("架子", "shelves", ""), + PILE("桩", "pile", ""); private final String text; + private final String value; - SpartaRecTypeEnum(String text, String value) { + /** + * 描述:对应字典violation_level_type + */ + private final String code; + + SpartaRecTypeEnum(String text, String value, String code) { this.text = text; this.value = value; + this.code = code; } public static SpartaRecTypeEnum fromValue(String value) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7deviceimg/OthYs7DeviceImgCreateByCapture.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7deviceimg/OthYs7DeviceImgCreateByCapture.java index b02916ac..e61a644f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7deviceimg/OthYs7DeviceImgCreateByCapture.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/domain/dto/ys7deviceimg/OthYs7DeviceImgCreateByCapture.java @@ -16,6 +16,11 @@ public class OthYs7DeviceImgCreateByCapture implements Serializable { @Serial private static final long serialVersionUID = 9152300524686055187L; + /** + * 项目id + */ + private Long projectId; + /** * 设备序列号 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceImgServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceImgServiceImpl.java index 3593bca0..5ebcd841 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceImgServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/other/service/impl/OthYs7DeviceImgServiceImpl.java @@ -27,6 +27,9 @@ import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq; import org.dromara.other.domain.vo.ys7deviceimg.OthYs7DeviceImgVo; import org.dromara.other.mapper.OthYs7DeviceImgMapper; import org.dromara.other.service.IOthYs7DeviceImgService; +import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto; +import org.dromara.safety.domain.enums.HseRecordCategoryEnum; +import org.dromara.safety.service.IHseRecognizeRecordService; import org.dromara.system.domain.vo.SysOssUploadVo; import org.dromara.system.service.ISysOssService; import org.springframework.beans.BeanUtils; @@ -56,6 +59,9 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl imgList) { List saveList = new ArrayList<>(); + List recordList = new ArrayList<>(); for (OthYs7DeviceImgCreateByCapture img : imgList) { OthYs7DeviceImg othYs7DeviceImg = new OthYs7DeviceImg(); String url = img.getUrl(); @@ -206,12 +213,16 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl recTypes = List.of(SpartaRecTypeEnum.HEAD, SpartaRecTypeEnum.SMOKE); SpartaRecognizeVo recognizeVo = spartaManager.recognize(ossUrl, recTypes); if (recognizeVo != null && recognizeVo.getHasTarget().equals(SpartaHasTargetEnum.YES.getValue())) { + // 记录识别信息 + HseRecognizeRecordCreateDto record = new HseRecognizeRecordCreateDto(); + record.setCreateTime(new Date()); List targets = recognizeVo.getTargets(); othYs7DeviceImg.setTargets(JSONUtil.toJsonStr(targets)); othYs7DeviceImg.setImgSize(JSONUtil.toJsonStr(recognizeVo.getOriginalImgSize())); othYs7DeviceImg.setIsRecognize(SpartaHasTargetEnum.YES.getValue()); List recTypeList = targets.stream().map(SpartaTargetVo::getType).distinct().toList(); othYs7DeviceImg.setRecType(JSONUtil.toJsonStr(recTypeList)); + String targetUrl = null; try { ImageStreamResult imageStreamResult = spartaManager.drawImageToStream(url, targets); InputStream inputStream = imageStreamResult.getInputStream(); @@ -219,13 +230,20 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl implements IBusProjectService { @@ -89,6 +94,9 @@ public class BusProjectServiceImpl extends ServiceImpl WEATHER_CACHE = Caffeine.newBuilder().initialCapacity(1024) .maximumSize(10000L) @@ -282,10 +290,32 @@ public class BusProjectServiceImpl extends ServiceImpl 0) { + if (this.lambdaQuery().eq(BusProject::getProjectName, req.getProjectName()).count() > 0) { throw new ServiceException("项目名称已存在", HttpStatus.BAD_REQUEST); } + if (this.lambdaQuery().eq(BusProject::getShortName, req.getShortName()).count() > 0) { + throw new ServiceException("项目简称已存在", HttpStatus.BAD_REQUEST); + } + // 添加新部门 + SysDeptBo queryBo = new SysDeptBo(); + queryBo.setParentId(BusProjectConstant.PARENT_ID); + // 查询父节点部门 + SysDeptVo deptVo = deptService.selectDeptList(queryBo).getFirst(); + Long deptId = deptVo.getDeptId(); + SysDeptBo createBo = new SysDeptBo(); + createBo.setParentId(deptId); + String shortName = req.getShortName(); + createBo.setDeptName(shortName != null ? shortName : req.getProjectName()); + if (!deptService.checkDeptNameUnique(createBo)) { + throw new ServiceException("新增项目部门'" + createBo.getDeptName() + "'失败,项目名称已存在"); + } + // 新增部门 + int dept = deptService.insertDept(createBo); + if (dept <= 0) { + throw new ServiceException("新增项目部门'" + createBo.getDeptName() + "'失败"); + } + Long newDeptId = deptService.selectIdByDeptName(createBo.getDeptName()); + project.setDeptId(newDeptId); // 写入数据库 boolean save = this.save(project); if (!save) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusUserProjectRelevancyServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusUserProjectRelevancyServiceImpl.java index 7b08cb77..a6d62312 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusUserProjectRelevancyServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusUserProjectRelevancyServiceImpl.java @@ -212,7 +212,7 @@ public class BusUserProjectRelevancyServiceImpl extends ServiceImpl> projectMap = projectService.lambdaQuery() .select(BusProject::getId, BusProject::getPId, BusProject::getProjectName, BusProject::getShortName) .in(BusProject::getId, projectIdList) - .eq(BusProject::getPId, BusProjectConstant.PARENT_PROJECT_ID) + .eq(BusProject::getPId, BusProjectConstant.PARENT_ID) .list() .stream().collect(Collectors.groupingBy(BusProject::getId)); // 获取封装 @@ -223,7 +223,7 @@ public class BusUserProjectRelevancyServiceImpl extends ServiceImpl list(HseRecognizeRecordQueryReq req, PageQuery pageQuery) { + return recognizeRecordService.queryPageList(req, pageQuery); + } + + /** + * 导出识别记录列表 + */ + @SaCheckPermission("safety:recognizeRecord:export") + @Log(title = "识别记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HseRecognizeRecordQueryReq req, HttpServletResponse response) { + List list = recognizeRecordService.queryList(req); + ExcelUtil.exportExcel(list, "识别记录", HseRecognizeRecordVo.class, response); + } + + /** + * 获取识别记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("safety:recognizeRecord:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(recognizeRecordService.queryById(id)); + } + + /** + * 删除识别记录 + * + * @param id 主键 + */ + @SaCheckPermission("safety:recognizeRecord:remove") + @Log(title = "识别记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{id}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long id) { + return toAjax(recognizeRecordService.deleteById(id)); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseRecognizeRecord.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseRecognizeRecord.java new file mode 100644 index 00000000..645775b0 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/HseRecognizeRecord.java @@ -0,0 +1,97 @@ +package org.dromara.safety.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; + +/** + * 识别记录对象 hse_recognize_record + * + * @author lcj + * @date 2025-06-24 + */ +@Data +@TableName("hse_recognize_record") +public class HseRecognizeRecord 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; + + /** + * 识别类别(1无人机识别 2监控拍摄) + */ + private String recordCategory; + + /** + * 违章类型(多个逗号分隔) + */ + private String violationType; + + /** + * 图片路径 + */ + private String picture; + + /** + * 违规数量 + */ + private Integer num; + + /** + * 故障描述 + */ + private String description; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 删除时间 + */ + private Date deletedAt; + + /** + * 是否删除(0正常 1删除) + */ + @TableLogic + private Long isDelete; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordCreateDto.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordCreateDto.java new file mode 100644 index 00000000..2a935816 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordCreateDto.java @@ -0,0 +1,55 @@ +package org.dromara.safety.domain.dto.recognizerecord; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.dromara.manager.spartamanager.vo.SpartaTargetVo; + +import java.util.Date; +import java.util.List; + +/** + * @author lcj + * @date 2025/6/24 11:48 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class HseRecognizeRecordCreateDto { + + /** + * 项目id + */ + private Long projectId; + + /** + * 设备序列号 + */ + private String deviceSerial; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 识别类别(1无人机识别 2监控拍摄) + */ + private String recordCategory; + + /** + * 图片路径 + */ + private String picture; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 目标信息 + */ + private List targets; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordQueryReq.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordQueryReq.java new file mode 100644 index 00000000..772e8aba --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/dto/recognizerecord/HseRecognizeRecordQueryReq.java @@ -0,0 +1,48 @@ +package org.dromara.safety.domain.dto.recognizerecord; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * @author lcj + * @date 2025/6/24 11:05 + */ +@Data +public class HseRecognizeRecordQueryReq implements Serializable { + + @Serial + private static final long serialVersionUID = 8542182388042031320L; + + /** + * 项目id + */ + private Long projectId; + + /** + * 识别类别(1无人机识别 2监控拍摄) + */ + private String recordCategory; + + /** + * 违章类型(多个逗号分隔) + */ + private String violationType; + + /** + * 故障描述 + */ + private String description; + + /** + * 创建时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + private Date createTime; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/HseRecordCategoryEnum.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/HseRecordCategoryEnum.java new file mode 100644 index 00000000..52697649 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/enums/HseRecordCategoryEnum.java @@ -0,0 +1,24 @@ +package org.dromara.safety.domain.enums; + +import lombok.Getter; + +/** + * @author lcj + * @date 2025/6/24 14:37 + */ +@Getter +public enum HseRecordCategoryEnum { + + DRONE("无人机识别", "1"), + MONITOR("监控设备识别", "2"); + + private final String text; + + private final String value; + + HseRecordCategoryEnum(String text, String value) { + this.text = text; + this.value = value; + } + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/recognizerecord/HseRecognizeRecordVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/recognizerecord/HseRecognizeRecordVo.java new file mode 100644 index 00000000..67efe8e1 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/domain/vo/recognizerecord/HseRecognizeRecordVo.java @@ -0,0 +1,87 @@ +package org.dromara.safety.domain.vo.recognizerecord; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableId; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import org.dromara.safety.domain.HseRecognizeRecord; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + +/** + * 识别记录视图对象 hse_recognize_record + * + * @author lcj + * @date 2025-06-24 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = HseRecognizeRecord.class) +public class HseRecognizeRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(value = "主键id") + private Long id; + + /** + * 项目id + */ + @ExcelProperty(value = "项目id") + private Long projectId; + + /** + * 设备序列号 + */ + @ExcelProperty(value = "设备序列号") + private String deviceSerial; + + /** + * 设备名称 + */ + @ExcelProperty(value = "设备名称") + private String deviceName; + + /** + * 识别类别(1无人机识别 2监控拍摄) + */ + @ExcelProperty(value = "识别类别", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "1=无人机识别,2=监控拍摄") + private String recordCategory; + + /** + * 违章类型(多个逗号分隔) + */ + @ExcelProperty(value = "违章类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "violation_level_type") + private String violationType; + + /** + * 图片路径 + */ + @ExcelProperty(value = "图片路径") + private String picture; + + /** + * 故障描述 + */ + @ExcelProperty(value = "故障描述") + private String description; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private Date createTime; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/HseRecognizeRecordMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/HseRecognizeRecordMapper.java new file mode 100644 index 00000000..11ce342d --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/mapper/HseRecognizeRecordMapper.java @@ -0,0 +1,15 @@ +package org.dromara.safety.mapper; + +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.safety.domain.HseRecognizeRecord; +import org.dromara.safety.domain.vo.recognizerecord.HseRecognizeRecordVo; + +/** + * 识别记录Mapper接口 + * + * @author lcj + * @date 2025-06-24 + */ +public interface HseRecognizeRecordMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IHseRecognizeRecordService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IHseRecognizeRecordService.java new file mode 100644 index 00000000..ffff03e4 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/IHseRecognizeRecordService.java @@ -0,0 +1,87 @@ +package org.dromara.safety.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.safety.domain.HseRecognizeRecord; +import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto; +import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordQueryReq; +import org.dromara.safety.domain.vo.recognizerecord.HseRecognizeRecordVo; + +import java.util.List; + +/** + * 识别记录Service接口 + * + * @author lcj + * @date 2025-06-24 + */ +public interface IHseRecognizeRecordService extends IService { + + /** + * 查询识别记录 + * + * @param id 主键 + * @return 识别记录 + */ + HseRecognizeRecordVo queryById(Long id); + + /** + * 分页查询识别记录列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 识别记录分页列表 + */ + TableDataInfo queryPageList(HseRecognizeRecordQueryReq req, PageQuery pageQuery); + + /** + * 查询符合条件的识别记录列表 + * + * @param req 查询条件 + * @return 识别记录列表 + */ + List queryList(HseRecognizeRecordQueryReq req); + + /** + * 创建识别记录(摄像头) + * + * @param recordList 识别记录列表 + */ + void saveByMonitor(List recordList); + + /** + * 删除识别记录信息 + * + * @param id 待删除的主键 + * @return 是否删除成功 + */ + Boolean deleteById(Long id); + + /** + * 获取识别记录视图对象 + * + * @param recognizeRecord 识别记录对象 + * @return 识别记录视图对象 + */ + HseRecognizeRecordVo getVo(HseRecognizeRecord recognizeRecord); + + /** + * 获取识别记录查询条件封装 + * + * @param req 识别记录查询条件 + * @return 识别记录查询条件封装 + */ + LambdaQueryWrapper buildQueryWrapper(HseRecognizeRecordQueryReq req); + + /** + * 获取识别记录分页对象视图 + * + * @param recognizeRecordPage 识别记录分页对象 + * @return 识别记录分页对象视图 + */ + Page getVoPage(Page recognizeRecordPage); + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseRecognizeRecordServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseRecognizeRecordServiceImpl.java new file mode 100644 index 00000000..f8b3614e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseRecognizeRecordServiceImpl.java @@ -0,0 +1,225 @@ +package org.dromara.safety.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.common.satoken.utils.LoginHelper; +import org.dromara.manager.spartamanager.enums.SpartaRecTypeEnum; +import org.dromara.manager.spartamanager.vo.SpartaTargetVo; +import org.dromara.project.service.IBusProjectService; +import org.dromara.safety.domain.HseRecognizeRecord; +import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto; +import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordQueryReq; +import org.dromara.safety.domain.vo.recognizerecord.HseRecognizeRecordVo; +import org.dromara.safety.mapper.HseRecognizeRecordMapper; +import org.dromara.safety.service.IHseRecognizeRecordService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 识别记录Service业务层处理 + * + * @author lcj + * @date 2025-06-24 + */ +@Service +public class HseRecognizeRecordServiceImpl extends ServiceImpl + implements IHseRecognizeRecordService { + + @Resource + private IBusProjectService projectService; + + /** + * 查询识别记录 + * + * @param id 主键 + * @return 识别记录 + */ + @Override + public HseRecognizeRecordVo queryById(Long id) { + HseRecognizeRecord recognizeRecord = this.getById(id); + if (recognizeRecord == null) { + throw new ServiceException("识别记录信息不存在", HttpStatus.NOT_FOUND); + } + return this.getVo(recognizeRecord); + } + + /** + * 分页查询识别记录列表 + * + * @param req 查询条件 + * @param pageQuery 分页参数 + * @return 识别记录分页列表 + */ + @Override + public TableDataInfo queryPageList(HseRecognizeRecordQueryReq 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(HseRecognizeRecordQueryReq req) { + LambdaQueryWrapper lqw = buildQueryWrapper(req); + return this.list(lqw).stream().map(this::getVo).toList(); + } + + /** + * 创建识别记录(摄像头) + * + * @param recordList 识别记录列表 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void saveByMonitor(List recordList) { + List entityList = new ArrayList<>(); + for (HseRecognizeRecordCreateDto record : recordList) { + HseRecognizeRecord entity = new HseRecognizeRecord(); + entity.setDeviceSerial(record.getDeviceSerial()); + entity.setDeviceName(record.getDeviceName()); + entity.setRecordCategory(record.getRecordCategory()); + entity.setPicture(record.getPicture()); + entity.setCreateTime(record.getCreateTime()); + Long projectId = record.getProjectId(); + if (projectId == null) { + entity.setRemark("该摄像头暂未分配到项目中"); + } + List targets = record.getTargets(); + List codeList = targets.stream() + .map(SpartaTargetVo::getType).distinct() + .map(SpartaRecTypeEnum::fromValue).filter(Objects::nonNull) + .map(SpartaRecTypeEnum::getCode).filter(Objects::nonNull) + .toList(); + String codeStr = String.join(",", codeList); + entity.setViolationType(codeStr); + entity.setNum(targets.size()); + entityList.add(entity); + } + if (CollUtil.isNotEmpty(entityList)) { + boolean result = this.saveBatch(entityList); + if (!result) { + throw new ServiceException("保存识别记录失败"); + } + } + } + + /** + * 校验并批量删除识别记录信息 + * + * @param id 待删除的主键集合 + * @return 是否删除成功 + */ + @Override + public Boolean deleteById(Long id) { + Long userId = LoginHelper.getUserId(); + HseRecognizeRecord recognizeRecord = this.getById(id); + Long projectId = recognizeRecord.getProjectId(); + projectService.validAuth(projectId, userId); + return this.removeById(id); + } + + /** + * 获取识别记录视图对象 + * + * @param recognizeRecord 识别记录对象 + * @return 识别记录视图对象 + */ + @Override + public HseRecognizeRecordVo getVo(HseRecognizeRecord recognizeRecord) { + HseRecognizeRecordVo recognizeRecordVo = new HseRecognizeRecordVo(); + if (recognizeRecord == null) { + return recognizeRecordVo; + } + BeanUtils.copyProperties(recognizeRecord, recognizeRecordVo); + return recognizeRecordVo; + } + + /** + * 获取识别记录查询条件封装 + * + * @param req 识别记录查询条件 + * @return 识别记录查询条件封装 + */ + @Override + public LambdaQueryWrapper buildQueryWrapper(HseRecognizeRecordQueryReq req) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + Long projectId = req.getProjectId(); + String recordCategory = req.getRecordCategory(); + String violationType = req.getViolationType(); + String description = req.getDescription(); + Date createTime = req.getCreateTime(); + lqw.eq(ObjectUtils.isNotEmpty(projectId), HseRecognizeRecord::getProjectId, projectId); + lqw.eq(StringUtils.isNotBlank(recordCategory), HseRecognizeRecord::getRecordCategory, recordCategory); + if (StringUtils.isNotBlank(violationType)) { + lqw.likeRight(HseRecognizeRecord::getViolationType, violationType + ",") + .or() + .likeLeft(HseRecognizeRecord::getViolationType, "," + violationType) + .or() + .like(HseRecognizeRecord::getViolationType, "," + violationType + ",") + .or() + .eq(HseRecognizeRecord::getViolationType, violationType); + } + lqw.like(StringUtils.isNotBlank(description), HseRecognizeRecord::getDescription, description); + if (createTime != null) { + // 构造当天的起始和结束时间 + LocalDate localDate = createTime.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + LocalDateTime startOfDay = localDate.atStartOfDay(); + LocalDateTime startOfNextDay = localDate.plusDays(1).atStartOfDay(); + Date start = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()); + Date end = Date.from(startOfNextDay.atZone(ZoneId.systemDefault()).toInstant()); + lqw.ge(HseRecognizeRecord::getCreateTime, start) + .lt(HseRecognizeRecord::getCreateTime, end); + } + return lqw; + } + + /** + * 获取识别记录分页对象视图 + * + * @param recognizeRecordPage 识别记录分页对象 + * @return 识别记录分页对象视图 + */ + @Override + public Page getVoPage(Page recognizeRecordPage) { + List recognizeRecordList = recognizeRecordPage.getRecords(); + Page recognizeRecordVoPage = new Page<>( + recognizeRecordPage.getCurrent(), + recognizeRecordPage.getSize(), + recognizeRecordPage.getTotal()); + if (CollUtil.isEmpty(recognizeRecordList)) { + return recognizeRecordVoPage; + } + List recognizeRecordVoList = recognizeRecordList.stream().map(violationLevel -> { + HseRecognizeRecordVo vo = new HseRecognizeRecordVo(); + BeanUtils.copyProperties(violationLevel, vo); + return vo; + }).toList(); + recognizeRecordVoPage.setRecords(recognizeRecordVoList); + return recognizeRecordVoPage; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java index bf16642f..2af4841d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java @@ -52,6 +52,14 @@ public interface ISysDeptService { */ SysDeptVo selectDeptById(Long deptId); + /** + * 通过部门名称查询部门ID + * + * @param deptName 部门名称 + * @return 部门ID + */ + Long selectIdByDeptName(String deptName); + /** * 通过部门ID串查询部门 * diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java index ca062bee..4606beb1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java @@ -151,6 +151,20 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { return dept; } + /** + * 通过部门名称查询部门ID + * + * @param deptName 部门名称 + * @return 部门ID + */ + @Override + public Long selectIdByDeptName(String deptName) { + SysDept dept = baseMapper.selectOne(new LambdaQueryWrapper() + .select(SysDept::getDeptId) + .eq(SysDept::getDeptName, deptName)); + return dept.getDeptId(); + } + @Override public List selectDeptByIds(List deptIds) { return baseMapper.selectDeptList(new LambdaQueryWrapper() diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/HseRecognizeRecordMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/HseRecognizeRecordMapper.xml new file mode 100644 index 00000000..22e0c444 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/safety/HseRecognizeRecordMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/script/sql/menuInitValue.sql b/xinnengyuan/script/sql/menuInitValue.sql index 9183f346..d3ef12c2 100644 --- a/xinnengyuan/script/sql/menuInitValue.sql +++ b/xinnengyuan/script/sql/menuInitValue.sql @@ -717,3 +717,23 @@ values(1937100268151767046, '进度类别删除', 1937100268151767042, '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(1937100268151767047, '进度类别导出', 1937100268151767042, '5', '#', '', 1, 0, 'F', '0', '0', 'progress:progressCategory: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(1937338721300996098, '识别记录', '1935597155897143297', '1', 'recognizeRecord', 'safety/recognizeRecord/index', 1, 0, 'C', '0', '0', 'safety:recognizeRecord: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(1937338721300996099, '识别记录查询', 1937338721300996098, '1', '#', '', 1, 0, 'F', '0', '0', 'safety:recognizeRecord: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(1937338721300996100, '识别记录新增', 1937338721300996098, '2', '#', '', 1, 0, 'F', '0', '0', 'safety:recognizeRecord: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(1937338721300996101, '识别记录修改', 1937338721300996098, '3', '#', '', 1, 0, 'F', '0', '0', 'safety:recognizeRecord: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(1937338721300996102, '识别记录删除', 1937338721300996098, '4', '#', '', 1, 0, 'F', '0', '0', 'safety:recognizeRecord: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(1937338721300996103, '识别记录导出', 1937338721300996098, '5', '#', '', 1, 0, 'F', '0', '0', 'safety:recognizeRecord:export', '#', 103, 1, sysdate(), null, null, ''); diff --git a/xinnengyuan/script/sql/xinnengyuan.sql b/xinnengyuan/script/sql/xinnengyuan.sql index 980c8280..ffcb2b48 100644 --- a/xinnengyuan/script/sql/xinnengyuan.sql +++ b/xinnengyuan/script/sql/xinnengyuan.sql @@ -1,4 +1,4 @@ -use xinnengyuan; +use xinnengyuandev; drop table if exists bus_project; create table `bus_project` @@ -1144,3 +1144,24 @@ CREATE TABLE `hse_violation_level_post` `post` bigint not null comment '岗位', primary key (`level`, `post`) using btree ) comment = '等级与岗位关联' collate = utf8mb4_unicode_ci; + +DROP TABLE IF EXISTS `hse_recognize_record`; +CREATE TABLE `hse_recognize_record` +( + `id` bigint not null auto_increment comment '主键id', + `project_id` bigint null comment '项目id', + `device_serial` varchar(255) null comment '设备序列号', + `device_name` varchar(255) null comment '设备名称', + `record_category` char(1) null comment '识别类别(1无人机识别 2监控拍摄)', + `violation_type` varchar(255) null comment '违章类型(多个逗号分隔)', + `picture` varchar(512) null comment '图片路径', + `num` int default 0 null comment '违规数量', + `description` varchar(512) null comment '故障描述', + `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' +) comment = '识别记录' COLLATE = utf8mb4_unicode_ci;