feat(mes): 新增安全生产模块 - 应急处置预案(一期)
背景:蓝羽此前无任何安全生产功能。经全仓库排查(22 个后端分支 + 21 个前端分支),
完整安全生产模块不存在,仅新高电力分支有应急处置预案,作为安全生产第一个能力点先落地。
后端新增(10 个文件):
- controller/admin/pro/emergencyplan:分页/详情/新增/修改/删除/导入导出
- dal/dataobject|mysql/pro/emergencyplan:DO 与 Mapper
- service/pro/emergencyplan:预案业务逻辑
补齐的缺失依赖:
- ErrorCodeConstants 补 MES_PRO_EMERGENCY_PLAN_NOT_EXISTS / CODE_DUPLICATE /
IMPORT_LIST_IS_EMPTY(蓝羽基线不存在,不补编译不过)
- DictTypeConstants 补 MES_PRO_EMERGENCY_PLAN_TYPE
SQL(mes_safety_emergency_plan_init.sql,可重复执行):
- 建表 mes_pro_emergency_plan
- 新建一级菜单「安全生产」(/safety),便于后续能力点归入
- 挂入应急处置预案菜单 + 5 个按钮权限,授权超管
- 补预案类型字典(停电/设备故障/火灾/自然灾害/其他)
后续能力点(风险分级管控、隐患排查治理、特种作业票证、安全教育培训、
可视化看板、统计分析)分期补充。
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================================== |
| | | -- å®å
¨ç产模å ââ 䏿ï¼åºæ¥å¤ç½®é¢æ¡ |
| | | -- |
| | | -- èæ¯ï¼èç¾½æ¤å没æä»»ä½å®å
¨ç产ç¸å
³åè½ãç»å
¨ä»åºï¼22 个åç«¯åæ¯ + 21 个åç«¯åæ¯ï¼ |
| | | -- ææ¥ç¡®è®¤ï¼ä»
ãæ°é«çµåã忝åå¨åºæ¥å¤ç½®é¢æ¡ï¼MesProEmergencyPlanï¼ï¼ |
| | | -- ä½ä¸ºå®å
¨ç产模åç第ä¸ä¸ªè½åç¹å
è½å°ï¼å
¶ä½è½åç¹ï¼é£é©å级管æ§ã |
| | | -- éæ£ææ¥æ²»çãç¹ç§ä½ä¸ç¥¨è¯ãå®å
¨æè²å¹è®ãå¯è§åçæ¿ãç»è®¡åæï¼åç»åæè¡¥å
ã |
| | | -- |
| | | -- å
å®¹ï¼ |
| | | -- 1. 建表 mes_pro_emergency_plan |
| | | -- 2. æ°å»ºä¸çº§èåãå®å
¨ç产ã(/safety)ï¼ä¾¿äºåç»è½åç¹å½å
¥ |
| | | -- 3. æå
¥ãåºæ¥å¤ç½®é¢æ¡ãèååå
¶æé®æé |
| | | -- 4. ææç»è¶
级管çå |
| | | -- |
| | | -- ç¹æ§ï¼å¯é夿§è¡ |
| | | -- ===================================================================== |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 1. 建表 |
| | | -- --------------------------------------------------------------------- |
| | | CREATE TABLE IF NOT EXISTS `mes_pro_emergency_plan` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `code` varchar(64) NOT NULL COMMENT '颿¡ç¼ç ', |
| | | `name` varchar(200) DEFAULT NULL COMMENT '颿¡åç§°', |
| | | `plan_type` tinyint DEFAULT NULL COMMENT '颿¡ç±»åï¼1=åçµï¼2=è®¾å¤æ
éï¼3=ç«ç¾ï¼4=èªç¶ç¾å®³ï¼5=å
¶ä»ï¼', |
| | | `content` text COMMENT 'å¤ç½®å
容', |
| | | `org_unit` varchar(200) DEFAULT NULL COMMENT '责任åä½/é¨é¨', |
| | | `status` tinyint NOT NULL DEFAULT '0' COMMENT 'ç¶æï¼0=è稿ï¼10=å·²åå¸ï¼', |
| | | `remark` varchar(500) DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | UNIQUE KEY `uk_code` (`code`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='MES åºæ¥å¤ç½®é¢æ¡'; |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 2. èåï¼å®å
¨ç产ï¼ä¸çº§ç®å½ï¼ |
| | | -- --------------------------------------------------------------------- |
| | | DELETE FROM system_role_menu WHERE menu_id BETWEEN 1065910 AND 1065919; |
| | | |
| | | DELETE FROM system_menu WHERE id BETWEEN 1065910 AND 1065919; |
| | | |
| | | INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, |
| | | component, component_name, status, visible, keep_alive, always_show, |
| | | creator, create_time, updater, update_time, deleted) |
| | | VALUES (1065910, 'å®å
¨ç产', '', 1, 65, 0, '/safety', 'ep:warning', |
| | | NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 3. èåï¼åºæ¥å¤ç½®é¢æ¡ + æé®æé |
| | | -- --------------------------------------------------------------------- |
| | | INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, |
| | | component, component_name, status, visible, keep_alive, always_show, |
| | | creator, create_time, updater, update_time, deleted) |
| | | VALUES (1065911, 'åºæ¥å¤ç½®é¢æ¡', '', 2, 1, 1065910, 'emergency-plan', 'ep:document', |
| | | 'mes/pro/emergencyplan/index', 'EmergencyPlan', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065912, 'åºæ¥é¢æ¡æ¥è¯¢', 'mes:pro-emergency-plan:query', 3, 1, 1065911, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065913, 'åºæ¥é¢æ¡å建', 'mes:pro-emergency-plan:create', 3, 2, 1065911, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065914, 'åºæ¥é¢æ¡æ´æ°', 'mes:pro-emergency-plan:update', 3, 3, 1065911, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065915, 'åºæ¥é¢æ¡å é¤', 'mes:pro-emergency-plan:delete', 3, 4, 1065911, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065916, 'åºæ¥é¢æ¡å¯¼å
¥', 'mes:pro-emergency-plan:import', 3, 5, 1065911, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 4. ææç»è¶
级管çå |
| | | -- --------------------------------------------------------------------- |
| | | INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time, deleted) |
| | | SELECT 1, m.id, '1', NOW(), '1', NOW(), b'0' |
| | | FROM system_menu m |
| | | WHERE m.id BETWEEN 1065910 AND 1065919; |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 5. åå
¸ï¼åºæ¥å¤ç½®é¢æ¡ç±»å |
| | | -- --------------------------------------------------------------------- |
| | | DELETE FROM system_dict_data WHERE dict_type = 'mes_pro_emergency_plan_type'; |
| | | |
| | | DELETE FROM system_dict_type WHERE type = 'mes_pro_emergency_plan_type'; |
| | | |
| | | INSERT INTO system_dict_type (name, type, status, remark, creator, create_time, updater, update_time, deleted) |
| | | VALUES ('MES åºæ¥å¤ç½®é¢æ¡ç±»å', 'mes_pro_emergency_plan_type', 0, |
| | | 'MES åºæ¥å¤ç½®é¢æ¡ç±»åï¼1=åçµï¼2=è®¾å¤æ
éï¼3=ç«ç¾ï¼4=èªç¶ç¾å®³ï¼5=å
¶ä»ï¼', |
| | | '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | INSERT INTO system_dict_data (sort, label, value, dict_type, status, color_type, creator, create_time, updater, update_time, deleted) |
| | | VALUES (1, 'åçµ', '1', 'mes_pro_emergency_plan_type', 0, 'danger', '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 'è®¾å¤æ
é', '2', 'mes_pro_emergency_plan_type', 0, 'warning', '1', NOW(), '1', NOW(), b'0'), |
| | | (3, 'ç«ç¾', '3', 'mes_pro_emergency_plan_type', 0, 'error', '1', NOW(), '1', NOW(), b'0'), |
| | | (4, 'èªç¶ç¾å®³', '4', 'mes_pro_emergency_plan_type', 0, 'processing', '1', NOW(), '1', NOW(), b'0'), |
| | | (5, 'å
¶ä»', '5', 'mes_pro_emergency_plan_type', 0, 'default', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- 6. éªè¯ |
| | | -- --------------------------------------------------------------------- |
| | | SELECT id, parent_id, name, path, component, permission, type |
| | | FROM system_menu |
| | | WHERE id BETWEEN 1065910 AND 1065919 |
| | | ORDER BY id; |
| | | |
| | | SELECT dict_type, label, value |
| | | FROM system_dict_data |
| | | WHERE dict_type = 'mes_pro_emergency_plan_type' |
| | | ORDER BY sort; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | 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.pro.emergencyplan.vo.MesProEmergencyPlanImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.emergencyplan.MesProEmergencyPlanDO; |
| | | import cn.iocoder.yudao.module.mes.service.pro.emergencyplan.MesProEmergencyPlanService; |
| | | 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; |
| | | 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; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - MES åºæ¥å¤ç½®é¢æ¡") |
| | | @RestController |
| | | @RequestMapping("/mes/pro/emergency-plan") |
| | | @Validated |
| | | public class MesProEmergencyPlanController { |
| | | |
| | | @Resource |
| | | private MesProEmergencyPlanService planService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "åå»ºåºæ¥å¤ç½®é¢æ¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-emergency-plan:create')") |
| | | public CommonResult<Long> createPlan(@Valid @RequestBody MesProEmergencyPlanSaveReqVO createReqVO) { |
| | | return success(planService.createPlan(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°åºæ¥å¤ç½®é¢æ¡") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-emergency-plan:update')") |
| | | public CommonResult<Boolean> updatePlan(@Valid @RequestBody MesProEmergencyPlanSaveReqVO updateReqVO) { |
| | | planService.updatePlan(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤åºæ¥å¤ç½®é¢æ¡") |
| | | @Parameter(name = "ids", description = "ç¼å·æ°ç»", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-emergency-plan:delete')") |
| | | public CommonResult<Boolean> deletePlan(@RequestParam("ids") List<Long> ids) { |
| | | planService.deletePlan(ids); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾åºæ¥å¤ç½®é¢æ¡") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | public CommonResult<MesProEmergencyPlanRespVO> getPlan(@RequestParam("id") Long id) { |
| | | MesProEmergencyPlanDO plan = planService.getPlan(id); |
| | | return success(plan != null ? BeanUtils.toBean(plan, MesProEmergencyPlanRespVO.class) : null); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾åºæ¥å¤ç½®é¢æ¡å页") |
| | | public CommonResult<PageResult<MesProEmergencyPlanRespVO>> getPlanPage(@Valid MesProEmergencyPlanPageReqVO pageReqVO) { |
| | | PageResult<MesProEmergencyPlanDO> pageResult = planService.getPlanPage(pageReqVO); |
| | | if (CollUtil.isEmpty(pageResult.getList())) { |
| | | return success(PageResult.empty(pageResult.getTotal())); |
| | | } |
| | | return success(BeanUtils.toBean(pageResult, MesProEmergencyPlanRespVO.class)); |
| | | } |
| | | |
| | | @PutMapping("/publish") |
| | | @Operation(summary = "åå¸åºæ¥å¤ç½®é¢æ¡") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-emergency-plan:update')") |
| | | public CommonResult<Boolean> publishPlan(@RequestParam("id") Long id) { |
| | | planService.publishPlan(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾åºæ¥å¤ç½®é¢æ¡å¯¼å
¥æ¨¡æ¿") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<MesProEmergencyPlanImportExcelVO> list = Collections.singletonList( |
| | | MesProEmergencyPlanImportExcelVO.builder() |
| | | .name("åçµç«åçµå¤ç½®é¢æ¡").planType(1).content("1. ç«å³é离æ
é...") |
| | | .orgUnit("è¿ç»´é¨").remark("").build() |
| | | ); |
| | | ExcelUtils.write(response, "åºæ¥å¤ç½®é¢æ¡å¯¼å
¥æ¨¡æ¿.xls", "åºæ¥å¤ç½®é¢æ¡å表", MesProEmergencyPlanImportExcelVO.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:pro-emergency-plan:import')") |
| | | public CommonResult<MesProEmergencyPlanImportRespVO> importExcel(@RequestParam("file") MultipartFile file, |
| | | @RequestParam(value = "updateSupport", required = false, |
| | | defaultValue = "false") Boolean updateSupport) throws Exception { |
| | | List<MesProEmergencyPlanImportExcelVO> list = ExcelUtils.read(file, MesProEmergencyPlanImportExcelVO.class); |
| | | return success(planService.importPlanList(list, updateSupport)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * MES åºæ¥å¤ç½®é¢æ¡ Excel 导å
¥ VO |
| | | */ |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class MesProEmergencyPlanImportExcelVO { |
| | | |
| | | @ExcelProperty("颿¡åç§°") |
| | | private String name; |
| | | |
| | | @ExcelProperty("颿¡ç±»åï¼1=åçµ 2=è®¾å¤æ
é 3=ç«ç¾ 4=èªç¶ç¾å®³ 5=å
¶ä»ï¼") |
| | | private Integer planType; |
| | | |
| | | @ExcelProperty("å¤ç½®å
容") |
| | | private String content; |
| | | |
| | | @ExcelProperty("责任åä½/é¨é¨") |
| | | private String orgUnit; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.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 MesProEmergencyPlanImportRespVO { |
| | | |
| | | @Schema(description = "å建æåç颿¡åç§°æ°ç»", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private List<String> createNames; |
| | | |
| | | @Schema(description = "æ´æ°æåç颿¡åç§°æ°ç»", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private List<String> updateNames; |
| | | |
| | | @Schema(description = "导å
¥å¤±è´¥ç颿¡éåï¼key ä¸ºé¢æ¡åç§°ï¼value 为失败åå ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Map<String, String> failureNames; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | @Schema(description = "管çåå° - MES åºæ¥å¤ç½®é¢æ¡å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class MesProEmergencyPlanPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "颿¡ç¼ç ", example = "YJ20260818001") |
| | | private String code; |
| | | |
| | | @Schema(description = "颿¡åç§°", example = "åçµç«åçµå¤ç½®é¢æ¡") |
| | | private String name; |
| | | |
| | | @Schema(description = "颿¡ç±»åï¼1=åçµï¼2=è®¾å¤æ
éï¼3=ç«ç¾ï¼4=èªç¶ç¾å®³ï¼5=å
¶ä»ï¼", example = "1") |
| | | private Integer planType; |
| | | |
| | | @Schema(description = "ç¶æï¼0=è稿ï¼10=å·²åå¸ï¼", example = "0") |
| | | private Integer status; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; |
| | | import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; |
| | | import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES åºæ¥å¤ç½®é¢æ¡ Response VO") |
| | | @Data |
| | | @ExcelIgnoreUnannotated |
| | | public class MesProEmergencyPlanRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @ExcelProperty("ç¼å·") |
| | | private Long id; |
| | | |
| | | @Schema(description = "颿¡ç¼ç ", example = "YJ20260818001") |
| | | @ExcelProperty("颿¡ç¼ç ") |
| | | private String code; |
| | | |
| | | @Schema(description = "颿¡åç§°", example = "åçµç«åçµå¤ç½®é¢æ¡") |
| | | @ExcelProperty("颿¡åç§°") |
| | | private String name; |
| | | |
| | | @Schema(description = "颿¡ç±»å", example = "1") |
| | | @ExcelProperty(value = "颿¡ç±»å", converter = DictConvert.class) |
| | | @DictFormat(cn.iocoder.yudao.module.mes.enums.DictTypeConstants.MES_PRO_EMERGENCY_PLAN_TYPE) |
| | | private Integer planType; |
| | | |
| | | @Schema(description = "å¤ç½®å
容", example = "1. ç«å³é离æ
é...") |
| | | private String content; |
| | | |
| | | @Schema(description = "责任åä½/é¨é¨", example = "è¿ç»´é¨") |
| | | @ExcelProperty("责任åä½") |
| | | private String orgUnit; |
| | | |
| | | @Schema(description = "ç¶æï¼0=è稿ï¼10=å·²åå¸ï¼", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - MES åºæ¥å¤ç½®é¢æ¡æ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class MesProEmergencyPlanSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·ï¼ä¿®æ¹æ¶å¿
å¡«ï¼", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "颿¡åç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "åçµç«åçµå¤ç½®é¢æ¡") |
| | | @NotEmpty(message = "颿¡åç§°ä¸è½ä¸ºç©º") |
| | | private String name; |
| | | |
| | | @Schema(description = "颿¡ç±»åï¼1=åçµï¼2=è®¾å¤æ
éï¼3=ç«ç¾ï¼4=èªç¶ç¾å®³ï¼5=å
¶ä»ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "颿¡ç±»åä¸è½ä¸ºç©º") |
| | | private Integer planType; |
| | | |
| | | @Schema(description = "å¤ç½®å
容", example = "1. ç«å³é离æ
é...") |
| | | private String content; |
| | | |
| | | @Schema(description = "责任åä½/é¨é¨", example = "è¿ç»´é¨") |
| | | private String orgUnit; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.pro.emergencyplan; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | /** |
| | | * MES åºæ¥å¤ç½®é¢æ¡ DO |
| | | * |
| | | * @author xiaoyi |
| | | */ |
| | | @TableName("mes_pro_emergency_plan") |
| | | @KeySequence("mes_pro_emergency_plan_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesProEmergencyPlanDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * 颿¡ç¼ç |
| | | */ |
| | | private String code; |
| | | |
| | | /** |
| | | * 颿¡åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * 颿¡ç±»å |
| | | * |
| | | * 1: åçµ |
| | | * 2: è®¾å¤æ
é |
| | | * 3: ç«ç¾ |
| | | * 4: èªç¶ç¾å®³ |
| | | * 5: å
¶ä» |
| | | * |
| | | * åå
¸ {@link DictTypeConstants#MES_PRO_EMERGENCY_PLAN_TYPE} |
| | | */ |
| | | private Integer planType; |
| | | |
| | | /** |
| | | * å¤ç½®å
容 |
| | | */ |
| | | private String content; |
| | | |
| | | /** |
| | | * 责任åä½/é¨é¨ |
| | | */ |
| | | private String orgUnit; |
| | | |
| | | /** |
| | | * ç¶æ |
| | | * |
| | | * 0: è稿 |
| | | * 10: å·²åå¸ |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.pro.emergencyplan; |
| | | |
| | | 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; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.emergencyplan.MesProEmergencyPlanDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * MES åºæ¥å¤ç½®é¢æ¡ Mapper |
| | | * |
| | | * @author xiaoyi |
| | | */ |
| | | @Mapper |
| | | public interface MesProEmergencyPlanMapper extends BaseMapperX<MesProEmergencyPlanDO> { |
| | | |
| | | default MesProEmergencyPlanDO selectByCode(String code) { |
| | | return selectOne(MesProEmergencyPlanDO::getCode, code); |
| | | } |
| | | |
| | | default MesProEmergencyPlanDO selectByName(String name) { |
| | | return selectOne(MesProEmergencyPlanDO::getName, name); |
| | | } |
| | | |
| | | default PageResult<MesProEmergencyPlanDO> selectPage(MesProEmergencyPlanPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesProEmergencyPlanDO>() |
| | | .likeIfPresent(MesProEmergencyPlanDO::getCode, reqVO.getCode()) |
| | | .likeIfPresent(MesProEmergencyPlanDO::getName, reqVO.getName()) |
| | | .eqIfPresent(MesProEmergencyPlanDO::getPlanType, reqVO.getPlanType()) |
| | | .eqIfPresent(MesProEmergencyPlanDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(MesProEmergencyPlanDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | String MES_PD_ARCHIVE_STATUS = "mes_pd_archive_status"; // 彿¡£ç¶æ |
| | | String MES_PD_PROCESS_PARAM_TYPE = "mes_pd_process_param_type"; // å·¥èºåæ°ç±»å |
| | | String MES_PD_PROCESS_PARAM_TEMPLATE_TYPE = "mes_pd_process_param_template_type"; // å·¥èºåæ°æ¨¡æ¿ç±»å |
| | | |
| | | // ========== å®å
¨ç产 (Safety) ========== |
| | | String MES_PRO_EMERGENCY_PLAN_TYPE = "mes_pro_emergency_plan_type"; // åºæ¥å¤ç½®é¢æ¡ç±»å |
| | | } |
| | |
| | | ErrorCode EM_ALERT_NOT_EXISTS = new ErrorCode(1_040_902_030, "è½èé¢è¦ä¸åå¨"); |
| | | ErrorCode EM_ALERT_ALREADY_HANDLED = new ErrorCode(1_040_902_031, "è½èé¢è¦å·²å¤çï¼è¯·å¿é夿ä½"); |
| | | |
| | | // ========== MES å®å
¨ç产 - åºæ¥å¤ç½®é¢æ¡ï¼1-040-903-000ï¼ ========== |
| | | ErrorCode MES_PRO_EMERGENCY_PLAN_NOT_EXISTS = new ErrorCode(1_040_903_000, "åºæ¥å¤ç½®é¢æ¡ä¸åå¨"); |
| | | ErrorCode MES_PRO_EMERGENCY_PLAN_CODE_DUPLICATE = new ErrorCode(1_040_903_001, "颿¡ç¼ç å·²åå¨"); |
| | | ErrorCode MES_PRO_EMERGENCY_PLAN_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_903_002, "导å
¥æ°æ®ä¸è½ä¸ºç©º"); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.pro.emergencyplan; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.emergencyplan.MesProEmergencyPlanDO; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES åºæ¥å¤ç½®é¢æ¡ Service æ¥å£ |
| | | * |
| | | * @author xiaoyi |
| | | */ |
| | | public interface MesProEmergencyPlanService { |
| | | |
| | | Long createPlan(MesProEmergencyPlanSaveReqVO createReqVO); |
| | | |
| | | void updatePlan(MesProEmergencyPlanSaveReqVO updateReqVO); |
| | | |
| | | void deletePlan(Collection<Long> ids); |
| | | |
| | | MesProEmergencyPlanDO getPlan(Long id); |
| | | |
| | | PageResult<MesProEmergencyPlanDO> getPlanPage(MesProEmergencyPlanPageReqVO pageReqVO); |
| | | |
| | | void publishPlan(Long id); |
| | | |
| | | MesProEmergencyPlanImportRespVO importPlanList(List<MesProEmergencyPlanImportExcelVO> importList, boolean updateSupport); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.pro.emergencyplan; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | 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.pro.emergencyplan.vo.MesProEmergencyPlanImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.emergencyplan.vo.MesProEmergencyPlanSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.emergencyplan.MesProEmergencyPlanDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.emergencyplan.MesProEmergencyPlanMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MES_PRO_EMERGENCY_PLAN_IMPORT_LIST_IS_EMPTY; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_WORK_ORDER_NOT_EXISTS; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_WORK_ORDER_NOT_PREPARE; |
| | | |
| | | /** |
| | | * MES åºæ¥å¤ç½®é¢æ¡ Service å®ç°ç±» |
| | | * |
| | | * @author xiaoyi |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesProEmergencyPlanServiceImpl implements MesProEmergencyPlanService { |
| | | |
| | | private static final Integer STATUS_DRAFT = 0; |
| | | private static final Integer STATUS_PUBLISHED = 10; |
| | | |
| | | @Resource |
| | | private MesProEmergencyPlanMapper planMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createPlan(MesProEmergencyPlanSaveReqVO createReqVO) { |
| | | String code = generateCode(); |
| | | if (planMapper.selectByCode(code) != null) { |
| | | throw exception(PRO_WORK_ORDER_NOT_EXISTS); |
| | | } |
| | | MesProEmergencyPlanDO plan = BeanUtils.toBean(createReqVO, MesProEmergencyPlanDO.class, req -> req |
| | | .setCode(code) |
| | | .setStatus(STATUS_DRAFT)); |
| | | planMapper.insert(plan); |
| | | return plan.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updatePlan(MesProEmergencyPlanSaveReqVO updateReqVO) { |
| | | MesProEmergencyPlanDO oldPlan = validatePlanCanModify(updateReqVO.getId()); |
| | | MesProEmergencyPlanDO updateObj = BeanUtils.toBean(updateReqVO, MesProEmergencyPlanDO.class, req -> req |
| | | .setCode(oldPlan.getCode()) |
| | | .setStatus(oldPlan.getStatus())); |
| | | planMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deletePlan(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return; |
| | | } |
| | | for (Long id : ids) { |
| | | validatePlanCanModify(id); |
| | | planMapper.deleteById(id); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public MesProEmergencyPlanDO getPlan(Long id) { |
| | | return planMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<MesProEmergencyPlanDO> getPlanPage(MesProEmergencyPlanPageReqVO pageReqVO) { |
| | | return planMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void publishPlan(Long id) { |
| | | MesProEmergencyPlanDO plan = validatePlanExists(id); |
| | | if (!Objects.equals(plan.getStatus(), STATUS_DRAFT)) { |
| | | throw exception(PRO_WORK_ORDER_NOT_PREPARE); |
| | | } |
| | | planMapper.updateById(new MesProEmergencyPlanDO().setId(id).setStatus(STATUS_PUBLISHED)); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesProEmergencyPlanImportRespVO importPlanList(List<MesProEmergencyPlanImportExcelVO> importList, |
| | | boolean updateSupport) { |
| | | if (CollUtil.isEmpty(importList)) { |
| | | throw exception(MES_PRO_EMERGENCY_PLAN_IMPORT_LIST_IS_EMPTY); |
| | | } |
| | | MesProEmergencyPlanImportRespVO respVO = MesProEmergencyPlanImportRespVO.builder() |
| | | .createNames(new ArrayList<>()).updateNames(new ArrayList<>()) |
| | | .failureNames(new LinkedHashMap<>()).build(); |
| | | AtomicInteger index = new AtomicInteger(1); |
| | | importList.forEach(importItem -> { |
| | | int currentIndex = index.getAndIncrement(); |
| | | String key = StrUtil.blankToDefault(importItem.getName(), "第 " + currentIndex + " è¡"); |
| | | if (StrUtil.isBlank(importItem.getName())) { |
| | | respVO.getFailureNames().put(key, "颿¡åç§°ä¸è½ä¸ºç©º"); |
| | | return; |
| | | } |
| | | MesProEmergencyPlanSaveReqVO reqVO = BeanUtils.toBean(importItem, MesProEmergencyPlanSaveReqVO.class); |
| | | MesProEmergencyPlanDO existPlan = planMapper.selectByName(importItem.getName()); |
| | | try { |
| | | if (existPlan == null) { |
| | | reqVO.setId(null); |
| | | createPlan(reqVO); |
| | | respVO.getCreateNames().add(importItem.getName()); |
| | | } else if (updateSupport) { |
| | | reqVO.setId(existPlan.getId()); |
| | | updatePlan(reqVO); |
| | | respVO.getUpdateNames().add(importItem.getName()); |
| | | } else { |
| | | respVO.getFailureNames().put(key, "颿¡åç§°å·²åå¨"); |
| | | } |
| | | } catch (ServiceException e) { |
| | | respVO.getFailureNames().put(key, e.getMessage()); |
| | | } |
| | | }); |
| | | return respVO; |
| | | } |
| | | |
| | | private String generateCode() { |
| | | return "YJ" + DateUtil.format(java.time.LocalDateTime.now(), "yyyyMMddHHmmss") |
| | | + String.format("%03d", (int) (Math.random() * 1000)); |
| | | } |
| | | |
| | | private MesProEmergencyPlanDO validatePlanExists(Long id) { |
| | | MesProEmergencyPlanDO plan = planMapper.selectById(id); |
| | | if (plan == null) { |
| | | throw exception(PRO_WORK_ORDER_NOT_EXISTS); |
| | | } |
| | | return plan; |
| | | } |
| | | |
| | | private MesProEmergencyPlanDO validatePlanCanModify(Long id) { |
| | | MesProEmergencyPlanDO plan = validatePlanExists(id); |
| | | if (!Objects.equals(plan.getStatus(), STATUS_DRAFT)) { |
| | | throw exception(PRO_WORK_ORDER_NOT_PREPARE); |
| | | } |
| | | return plan; |
| | | } |
| | | |
| | | } |