From 9890fa716e35507dda0221f95e05c6de0bdc62ac Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Apr 2026 22:27:11 +0800 Subject: [PATCH] ✨ feat(mes): 新增设备台账导入功能及相关接口 --- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java | 31 +++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java | 46 ++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java | 24 ++++++++++++++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanMachineryMapper.java | 4 ++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanSubjectMapper.java | 4 ++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkrecord/MesDvCheckRecordMapper.java | 4 ++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/machinery/MesDvMachineryMapper.java | 2 ++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/maintenrecord/MesDvMaintenRecordMapper.java | 6 +++++- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/repair/MesDvRepairMapper.java | 4 ++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 6 ++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryServiceImpl.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectServiceImpl.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryService.java | 12 ++++++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryTypeServiceImpl.java | 33 +++++++++++++++++++-------------- yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairService.java | 8 ++++++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairServiceImpl.java | 5 +++++ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/subject/MesDvSubjectServiceImpl.java | 11 +++++++++++ 25 files changed, 378 insertions(+), 19 deletions(-) create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java create mode 100644 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java index 542cd88..e6d89e5 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/MesDvMachineryController.java @@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryRespVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO; @@ -19,6 +21,7 @@ import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryTypeServic import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; @@ -26,6 +29,7 @@ import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.Collections; @@ -116,6 +120,33 @@ public class MesDvMachineryController { return success(BeanUtils.toBean(list, MesDvMachineryRespVO.class)); } + @GetMapping("/get-import-template") + @Operation(summary = "获得设备导入模板") + public void importTemplate(HttpServletResponse response) throws IOException { + // 手动创建导出 demo + List list = Collections.singletonList( + MesDvMachineryImportExcelVO.builder().code("EQ-001").name("示例设备") + .brand("示例品牌").spec("型号A").machineryTypeCode("MT-001") + .workshopCode("WS-001").status(0).build() + ); + // 输出 + ExcelUtils.write(response, "设备导入模板.xls", "设备列表", MesDvMachineryImportExcelVO.class, list); + } + + @PostMapping("/import") + @Operation(summary = "导入设备") + @Parameters({ + @Parameter(name = "file", description = "Excel 文件", required = true), + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") + }) + @PreAuthorize("@ss.hasPermission('mes:dv-machinery:import')") + public CommonResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(value = "updateSupport", required = false, + defaultValue = "false") Boolean updateSupport) throws Exception { + List list = ExcelUtils.read(file, MesDvMachineryImportExcelVO.class); + return success(machineryService.importMachineryList(list, updateSupport)); + } + // ==================== 拼接 VO ==================== private List buildMachineryRespVOList(List list) { diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java new file mode 100644 index 0000000..64f8d82 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportExcelVO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 设备台账 Excel 导入 VO + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MesDvMachineryImportExcelVO { + + @ExcelProperty("设备编码") + private String code; + + @ExcelProperty("设备名称") + private String name; + + @ExcelProperty("品牌") + private String brand; + + @ExcelProperty("规格型号") + private String spec; + + @ExcelProperty("设备类型编码") + private String machineryTypeCode; + + @ExcelProperty("所属车间编码") + private String workshopCode; + + @ExcelProperty(value = "设备状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.MES_DV_MACHINERY_STATUS) + private Integer status; + + @ExcelProperty("备注") + private String remark; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java new file mode 100644 index 0000000..aef4a69 --- /dev/null +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryImportRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Schema(description = "管理后台 - MES 设备台账导入 Response VO") +@Data +@Builder +public class MesDvMachineryImportRespVO { + + @Schema(description = "创建成功的设备编码数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List createCodes; + + @Schema(description = "更新成功的设备编码数组", requiredMode = Schema.RequiredMode.REQUIRED) + private List updateCodes; + + @Schema(description = "导入失败的设备集合,key 为设备编码,value 为失败原因", requiredMode = Schema.RequiredMode.REQUIRED) + private Map failureCodes; + +} diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java index 0383a46..aefad44 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dv/machinery/vo/MesDvMachineryPageReqVO.java @@ -6,6 +6,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import java.util.Set; + @Schema(description = "管理后台 - MES 设备台账分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @@ -24,6 +26,9 @@ public class MesDvMachineryPageReqVO extends PageParam { @Schema(description = "设备类型编号", example = "100") private Long machineryTypeId; + @Schema(description = "设备类型编号列表(含子类型,由后端自动填充)", hidden = true) + private Set machineryTypeIds; + @Schema(description = "所属车间编号", example = "200") private Long workshopId; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanMachineryMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanMachineryMapper.java index fb2f1c0..e426964 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanMachineryMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/checkplan/MesDvCheckPlanMachineryMapper.java @@ -28,4 +28,8 @@ public interface MesDvCheckPlanMachineryMapper extends BaseMapperX .orderByDesc(MesDvCheckRecordDO::getId)); } + default Long selectCountByMachineryId(Long machineryId) { + return selectCount(MesDvCheckRecordDO::getMachineryId, machineryId); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/machinery/MesDvMachineryMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/machinery/MesDvMachineryMapper.java index e96bf59..5e39c3d 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/machinery/MesDvMachineryMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/machinery/MesDvMachineryMapper.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -21,6 +22,7 @@ public interface MesDvMachineryMapper extends BaseMapperX { .likeIfPresent(MesDvMachineryDO::getName, reqVO.getName()) .likeIfPresent(MesDvMachineryDO::getBrand, reqVO.getBrand()) .eqIfPresent(MesDvMachineryDO::getMachineryTypeId, reqVO.getMachineryTypeId()) + .inIfPresent(MesDvMachineryDO::getMachineryTypeId, reqVO.getMachineryTypeIds()) .eqIfPresent(MesDvMachineryDO::getWorkshopId, reqVO.getWorkshopId()) .eqIfPresent(MesDvMachineryDO::getStatus, reqVO.getStatus()) .orderByDesc(MesDvMachineryDO::getId)); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/maintenrecord/MesDvMaintenRecordMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/maintenrecord/MesDvMaintenRecordMapper.java index 56adadc..1fcac78 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/maintenrecord/MesDvMaintenRecordMapper.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dv/maintenrecord/MesDvMaintenRecordMapper.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.mes.controller.admin.dv.maintenrecord.vo.MesDvMaintenRecordPageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.maintenrecord.MesDvMaintenRecordDO; -import cn.hutool.core.util.StrUtil; import org.apache.ibatis.annotations.Mapper; /** @@ -18,6 +17,7 @@ public interface MesDvMaintenRecordMapper extends BaseMapperX selectPage(MesDvMaintenRecordPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() + // TODO @AI:对齐分析下,哪里有问题! // .apply(StrUtil.isNotBlank(reqVO.getPlanName()), // "plan_id IN (SELECT id FROM mes_dv_check_plan WHERE name LIKE CONCAT('%', {0}, '%') AND deleted = 0)", // reqVO.getPlanName()) @@ -34,4 +34,8 @@ public interface MesDvMaintenRecordMapper extends BaseMapperX { .orderByDesc(MesDvRepairDO::getId)); } + default Long selectCountByMachineryId(Long machineryId) { + return selectCount(MesDvRepairDO::getMachineryId, machineryId); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index 52c66d8..28ada97 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -149,10 +149,16 @@ public interface ErrorCodeConstants { // ========== MES 设备管理-设备台账(1-040-301-000) ========== ErrorCode DV_MACHINERY_NOT_EXISTS = new ErrorCode(1_040_301_000, "设备不存在"); ErrorCode DV_MACHINERY_CODE_DUPLICATE = new ErrorCode(1_040_301_001, "设备编码已存在"); + ErrorCode DV_MACHINERY_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_301_002, "导入设备数据不能为空"); + ErrorCode DV_MACHINERY_HAS_CHECK_PLAN = new ErrorCode(1_040_301_003, "设备已关联点检计划,无法删除"); + ErrorCode DV_MACHINERY_HAS_CHECK_RECORD = new ErrorCode(1_040_301_004, "设备已关联点检记录,无法删除"); + ErrorCode DV_MACHINERY_HAS_MAINTEN_RECORD = new ErrorCode(1_040_301_005, "设备已关联保养记录,无法删除"); + ErrorCode DV_MACHINERY_HAS_REPAIR = new ErrorCode(1_040_301_006, "设备已关联维修工单,无法删除"); // ========== MES 设备管理-点检保养项目(1-040-304-000) ========== ErrorCode DV_SUBJECT_NOT_EXISTS = new ErrorCode(1_040_304_000, "点检保养项目不存在"); ErrorCode DV_SUBJECT_CODE_DUPLICATE = new ErrorCode(1_040_304_001, "项目编码已存在"); + ErrorCode DV_SUBJECT_USED_BY_CHECK_PLAN = new ErrorCode(1_040_304_002, "点检保养项目已被点检保养方案使用,无法删除"); // ========== MES 设备管理-点检计划(1-040-302-000) ========== ErrorCode DV_CHECK_PLAN_NOT_EXISTS = new ErrorCode(1_040_302_000, "点检计划不存在"); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryService.java index 7a7abc3..7bea3f3 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryService.java @@ -51,4 +51,12 @@ public interface MesDvCheckPlanMachineryService { */ void deleteByPlanId(Long planId); + /** + * 获得指定设备关联的方案设备数量 + * + * @param machineryId 设备编号 + * @return 方案设备数量 + */ + Long getCheckPlanMachineryCountByMachineryId(Long machineryId); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryServiceImpl.java index 2b6c886..4ec685a 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanMachineryServiceImpl.java @@ -74,4 +74,9 @@ public class MesDvCheckPlanMachineryServiceImpl implements MesDvCheckPlanMachine checkPlanMachineryMapper.deleteByPlanId(planId); } + @Override + public Long getCheckPlanMachineryCountByMachineryId(Long machineryId) { + return checkPlanMachineryMapper.selectCountByMachineryId(machineryId); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectService.java index e9f26a3..710d55b 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectService.java @@ -51,4 +51,12 @@ public interface MesDvCheckPlanSubjectService { */ void deleteByPlanId(Long planId); + /** + * 获得指定项目的方案项目关联数量 + * + * @param subjectId 项目编号 + * @return 项目关联数量 + */ + Long getCheckPlanSubjectCountBySubjectId(Long subjectId); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectServiceImpl.java index 9e1488c..6c2cef8 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkplan/MesDvCheckPlanSubjectServiceImpl.java @@ -74,4 +74,9 @@ public class MesDvCheckPlanSubjectServiceImpl implements MesDvCheckPlanSubjectSe checkPlanSubjectMapper.deleteByPlanId(planId); } + @Override + public Long getCheckPlanSubjectCountBySubjectId(Long subjectId) { + return checkPlanSubjectMapper.selectCountBySubjectId(subjectId); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordService.java index d043429..27198b9 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordService.java @@ -51,6 +51,14 @@ public interface MesDvCheckRecordService { void validateCheckRecordExists(Long id); /** + * 获得指定设备的点检记录数量 + * + * @param machineryId 设备编号 + * @return 点检记录数量 + */ + Long getCheckRecordCountByMachineryId(Long machineryId); + + /** * 获得设备点检记录 * * @param id 编号 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java index 04b53f1..f19d525 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/checkrecord/MesDvCheckRecordServiceImpl.java @@ -125,6 +125,11 @@ public class MesDvCheckRecordServiceImpl implements MesDvCheckRecordService { } @Override + public Long getCheckRecordCountByMachineryId(Long machineryId) { + return checkRecordMapper.selectCountByMachineryId(machineryId); + } + + @Override public MesDvCheckRecordDO getCheckRecord(Long id) { return checkRecordMapper.selectById(id); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryService.java index 3bfb877..cc4dac3 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryService.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.mes.service.dv.machinery; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; @@ -97,4 +99,14 @@ public interface MesDvMachineryService { return convertMap(getMachineryList(ids), MesDvMachineryDO::getId); } + /** + * 导入设备列表 + * + * @param importMachineryList 导入设备列表 + * @param updateSupport 是否支持更新 + * @return 导入结果 + */ + MesDvMachineryImportRespVO importMachineryList(List importMachineryList, + boolean updateSupport); + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java index 98a6691..9da51df 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryServiceImpl.java @@ -2,23 +2,33 @@ package cn.iocoder.yudao.module.mes.service.dv.machinery; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportExcelVO; +import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryImportRespVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachineryPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.MesDvMachinerySaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryTypeDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO; import cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery.MesDvMachineryMapper; import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; +import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanMachineryService; +import cn.iocoder.yudao.module.mes.service.dv.checkrecord.MesDvCheckRecordService; +import cn.iocoder.yudao.module.mes.service.dv.maintenrecord.MesDvMaintenRecordService; +import cn.iocoder.yudao.module.mes.service.dv.repair.MesDvRepairService; import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkshopService; import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; @@ -46,6 +56,22 @@ public class MesDvMachineryServiceImpl implements MesDvMachineryService { @Resource private MesWmBarcodeService barcodeService; + @Resource + @Lazy + private MesDvCheckPlanMachineryService checkPlanMachineryService; + + @Resource + @Lazy + private MesDvCheckRecordService checkRecordService; + + @Resource + @Lazy + private MesDvMaintenRecordService maintenRecordService; + + @Resource + @Lazy + private MesDvRepairService repairService; + @Override public Long createMachinery(MesDvMachinerySaveReqVO createReqVO) { // 校验设备类型存在 @@ -85,7 +111,19 @@ public class MesDvMachineryServiceImpl implements MesDvMachineryService { public void deleteMachinery(Long id) { // 校验存在 validateMachineryExists(id); - // TODO @芋艿:后续补充点检计划、保养记录、维修工单等引用校验 + // 校验关联数据 + if (checkPlanMachineryService.getCheckPlanMachineryCountByMachineryId(id) > 0) { + throw exception(DV_MACHINERY_HAS_CHECK_PLAN); + } + if (checkRecordService.getCheckRecordCountByMachineryId(id) > 0) { + throw exception(DV_MACHINERY_HAS_CHECK_RECORD); + } + if (maintenRecordService.getMaintenRecordCountByMachineryId(id) > 0) { + throw exception(DV_MACHINERY_HAS_MAINTEN_RECORD); + } + if (repairService.getRepairCountByMachineryId(id) > 0) { + throw exception(DV_MACHINERY_HAS_REPAIR); + } // 删除 machineryMapper.deleteById(id); @@ -118,6 +156,15 @@ public class MesDvMachineryServiceImpl implements MesDvMachineryService { @Override public PageResult getMachineryPage(MesDvMachineryPageReqVO pageReqVO) { + // 处理设备类型树形查询:选择父类型时,同时查询所有子类型下的设备 + if (pageReqVO.getMachineryTypeId() != null) { + List children = machineryTypeService.getMachineryTypeChildrenList( + pageReqVO.getMachineryTypeId()); + Set typeIds = new HashSet<>(); + typeIds.add(pageReqVO.getMachineryTypeId()); + children.forEach(child -> typeIds.add(child.getId())); + pageReqVO.setMachineryTypeIds(typeIds); + } return machineryMapper.selectPage(pageReqVO); } @@ -139,4 +186,89 @@ public class MesDvMachineryServiceImpl implements MesDvMachineryService { return machineryMapper.selectByIds(ids); } + @Override + @Transactional(rollbackFor = Exception.class) + public MesDvMachineryImportRespVO importMachineryList(List importMachineryList, + boolean updateSupport) { + // 1. 参数校验 + if (CollUtil.isEmpty(importMachineryList)) { + throw exception(DV_MACHINERY_IMPORT_LIST_IS_EMPTY); + } + + // 2. 批量加载设备类型和车间,构建编码到实体的映射 + List allTypes = machineryTypeService.getMachineryTypeList( + new cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeListReqVO()); + Map typeCodeMap = allTypes.stream() + .collect(Collectors.toMap(MesDvMachineryTypeDO::getCode, t -> t, (a, b) -> a)); + List allWorkshops = workshopService.getWorkshopListByStatus( + cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus()); + Map workshopCodeMap = allWorkshops.stream() + .collect(Collectors.toMap(MesMdWorkshopDO::getCode, w -> w, (a, b) -> a)); + + // 3. 遍历,逐个创建 or 更新 + MesDvMachineryImportRespVO respVO = MesDvMachineryImportRespVO.builder() + .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>()) + .failureCodes(new LinkedHashMap<>()).build(); + AtomicInteger index = new AtomicInteger(1); + importMachineryList.forEach(importItem -> { + int currentIndex = index.getAndIncrement(); + // 3.1 校验必填字段 + String key = StrUtil.blankToDefault(importItem.getCode(), "第 " + currentIndex + " 行"); + if (StrUtil.isBlank(importItem.getCode())) { + respVO.getFailureCodes().put(key, "设备编码不能为空"); + return; + } + if (StrUtil.isBlank(importItem.getName())) { + respVO.getFailureCodes().put(key, "设备名称不能为空"); + return; + } + // 3.2 校验设备类型编码 + if (StrUtil.isBlank(importItem.getMachineryTypeCode())) { + respVO.getFailureCodes().put(key, "设备类型编码不能为空"); + return; + } + MesDvMachineryTypeDO machineryType = typeCodeMap.get(importItem.getMachineryTypeCode()); + if (machineryType == null) { + respVO.getFailureCodes().put(key, "设备类型编码[" + importItem.getMachineryTypeCode() + "]不存在"); + return; + } + // 3.3 校验车间编码 + if (StrUtil.isBlank(importItem.getWorkshopCode())) { + respVO.getFailureCodes().put(key, "车间编码不能为空"); + return; + } + MesMdWorkshopDO workshop = workshopCodeMap.get(importItem.getWorkshopCode()); + if (workshop == null) { + respVO.getFailureCodes().put(key, "车间编码[" + importItem.getWorkshopCode() + "]不存在"); + return; + } + + // 3.4 判断:创建 or 更新 + MesDvMachineryDO existMachinery = machineryMapper.selectByCode(importItem.getCode()); + if (existMachinery == null) { + // 3.4.1 创建 + MesDvMachineryDO machinery = BeanUtils.toBean(importItem, MesDvMachineryDO.class); + machinery.setMachineryTypeId(machineryType.getId()); + machinery.setWorkshopId(workshop.getId()); + machineryMapper.insert(machinery); + // 自动生成条码 + barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(), + machinery.getId(), machinery.getCode(), machinery.getName()); + respVO.getCreateCodes().add(importItem.getCode()); + } else if (updateSupport) { + // 3.4.2 更新 + MesDvMachineryDO updateObj = BeanUtils.toBean(importItem, MesDvMachineryDO.class); + updateObj.setId(existMachinery.getId()); + updateObj.setMachineryTypeId(machineryType.getId()); + updateObj.setWorkshopId(workshop.getId()); + machineryMapper.updateById(updateObj); + respVO.getUpdateCodes().add(importItem.getCode()); + } else { + // 不支持更新 + respVO.getFailureCodes().put(key, "设备编码已存在"); + } + }); + return respVO; + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryTypeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryTypeServiceImpl.java index 6ccae60..aa6eb83 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryTypeServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/machinery/MesDvMachineryTypeServiceImpl.java @@ -164,23 +164,28 @@ public class MesDvMachineryTypeServiceImpl implements MesDvMachineryTypeService @Override public List getMachineryTypeChildrenList(Long parentId) { List allList = machineryTypeMapper.selectList(); // 类型总量小,全量查 - // 递归收集所有子类型 + // 1. 构建 parentId -> children 的 Map(类似 menu 的 treeNodeMap 思路) + Map> parentChildrenMap = new LinkedHashMap<>(); + allList.forEach(type -> parentChildrenMap + .computeIfAbsent(type.getParentId(), k -> new ArrayList<>()).add(type)); + // 2. 收集所有后代节点 List result = new ArrayList<>(); - collectMachineryTypeChildren(result, parentId, allList); - return result; - } - - /** - * 递归收集所有子类型 - */ - private void collectMachineryTypeChildren(List result, Long parentId, - List allList) { - for (MesDvMachineryTypeDO machineryType : allList) { - if (Objects.equals(machineryType.getParentId(), parentId)) { - result.add(machineryType); - collectMachineryTypeChildren(result, machineryType.getId(), allList); + List parentIds = new ArrayList<>(); + parentIds.add(parentId); + for (int i = 0; i < Short.MAX_VALUE; i++) { + if (i >= parentIds.size()) { + break; + } + List children = parentChildrenMap.get(parentIds.get(i)); + if (children == null) { + continue; + } + for (MesDvMachineryTypeDO child : children) { + result.add(child); + parentIds.add(child.getId()); } } + return result; } } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordService.java index 20500ca..d1ee6d5 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordService.java @@ -51,6 +51,14 @@ public interface MesDvMaintenRecordService { void validateMaintenRecordExists(Long id); /** + * 获得指定设备的保养记录数量 + * + * @param machineryId 设备编号 + * @return 保养记录数量 + */ + Long getMaintenRecordCountByMachineryId(Long machineryId); + + /** * 获得设备保养记录 * * @param id 编号 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java index e4be7c3..c4e94e0 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/maintenrecord/MesDvMaintenRecordServiceImpl.java @@ -110,6 +110,11 @@ public class MesDvMaintenRecordServiceImpl implements MesDvMaintenRecordService } } + @Override + public Long getMaintenRecordCountByMachineryId(Long machineryId) { + return maintenRecordMapper.selectCountByMachineryId(machineryId); + } + /** * 校验设备保养记录是否为草稿状态 * diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairService.java index d762962..5a7717c 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairService.java @@ -44,6 +44,14 @@ public interface MesDvRepairService { void validateRepairExists(Long id); /** + * 获得指定设备的维修工单数量 + * + * @param machineryId 设备编号 + * @return 维修工单数量 + */ + Long getRepairCountByMachineryId(Long machineryId); + + /** * 获得维修工单 * * @param id 编号 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairServiceImpl.java index 13b4474..eac66a0 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/repair/MesDvRepairServiceImpl.java @@ -83,6 +83,11 @@ public class MesDvRepairServiceImpl implements MesDvRepairService { } } + @Override + public Long getRepairCountByMachineryId(Long machineryId) { + return repairMapper.selectCountByMachineryId(machineryId); + } + /** * 校验维修工单是否为草稿状态 * diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/subject/MesDvSubjectServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/subject/MesDvSubjectServiceImpl.java index 9d98f38..d47fb07 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/subject/MesDvSubjectServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/dv/subject/MesDvSubjectServiceImpl.java @@ -8,7 +8,9 @@ import cn.iocoder.yudao.module.mes.controller.admin.dv.subject.vo.MesDvSubjectPa import cn.iocoder.yudao.module.mes.controller.admin.dv.subject.vo.MesDvSubjectSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.dv.subject.MesDvSubjectDO; import cn.iocoder.yudao.module.mes.dal.mysql.dv.subject.MesDvSubjectMapper; +import cn.iocoder.yudao.module.mes.service.dv.checkplan.MesDvCheckPlanSubjectService; import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -30,6 +32,10 @@ public class MesDvSubjectServiceImpl implements MesDvSubjectService { @Resource private MesDvSubjectMapper subjectMapper; + // DONE @AI:调用对方的 service + @Resource + @Lazy + private MesDvCheckPlanSubjectService checkPlanSubjectService; @Override public Long createSubject(MesDvSubjectSaveReqVO createReqVO) { @@ -58,6 +64,11 @@ public class MesDvSubjectServiceImpl implements MesDvSubjectService { public void deleteSubject(Long id) { // 校验存在 validateSubjectExists(id); + // 校验是否被点检保养方案引用 + if (checkPlanSubjectService.getCheckPlanSubjectCountBySubjectId(id) > 0) { + throw exception(DV_SUBJECT_USED_BY_CHECK_PLAN); + } + // 删除 subjectMapper.deleteById(id); } -- libgit2 0.21.4