feat(safety): 安全生产四期 - 特种作业票证管理
高风险作业必须先办票、审批通过后才可作业,完工后登记并归档,形成可追溯的作业许可记录。
状态流转:
0 待审批 --审批通过--> 10 已批准 --完工登记--> 20 已完工 --归档--> 30 已归档
└--审批驳回--> 90 已驳回
作业类型:动火 / 受限空间 / 高处 / 吊装 / 临时用电 / 断路 / 盲板抽堵 / 设备检修
作业级别:特殊 / 一级 / 二级 / 三级
后端:
- 作业票 MesSafetyWorkTicket:作业信息、计划/实际时间、申请人、监护人、
作业人员、施工单位、安全措施、安全交底、审批与归档信息
- 关键校验:
* 计划结束时间必须晚于开始时间
* 审批通过后不允许再改作业信息(需作废重开),已归档只读
* 只有「待审批」可审批;驳回必须填原因
* 只有「已批准」可完工、「已完工」可归档
* 已批准及之后的作业票不允许删除(保留追溯记录)
* 被驳回的作业票重新提交时自动回到待审批并清空驳回原因
- 超期判定:已批准但计划结束时间已过
- 反向引用保护:风险单元被作业票引用后禁止删除
- 错误码 1_040_906_xxx;字典常量 MES_SAFETY_TICKET_*
前端:
- 作业票列表:类型/级别字典渲染、计划时间超期红色标记、按状态动态显示可用操作
- 申请表单(含安全措施、监护人、作业人员)
- 审批弹窗(批准/驳回,驳回必填原因)
- 完工登记弹窗(可勾选「完工后直接归档」),已完工时自动切换为归档模式
SQL(mes_safety_ticket_init.sql,可重复执行):
- 建表 1 张、菜单挂到「安全生产」目录、字典 3 组、7 个按钮权限
注:本期只提交代码,未部署。
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================================== |
| | | -- å®å
¨ç产模å ââ åæï¼ç¹ç§ä½ä¸ç¥¨è¯ç®¡ç |
| | | -- |
| | | -- å®ä½ï¼é«é£é©ä½ä¸å¿
é¡»å
å票ã审æ¹éè¿åæå¯ä½ä¸ï¼ä½ä¸æé´éçæ¤äººç¡®è®¤ï¼ |
| | | -- å®å·¥åç»è®°å¹¶å½æ¡£ï¼å½¢æå¯è¿½æº¯çä½ä¸è®¸å¯è®°å½ã |
| | | -- |
| | | -- æ¯æä½ä¸ç±»åï¼å¯æå®¢æ·å®é
å¢ååå
¸å³å¯ï¼ï¼ |
| | | -- 1 å¨ç«ä½ä¸ / 2 åé空é´ä½ä¸ / 3 é«å¤ä½ä¸ / 4 åè£
ä½ä¸ |
| | | -- 5 临æ¶ç¨çµä½ä¸ / 6 æè·¯ä½ä¸ / 7 ç²æ¿æ½å µä½ä¸ / 8 è®¾å¤æ£ä¿®ä½ä¸ |
| | | -- |
| | | -- ç¶ææµè½¬ï¼ |
| | | -- 0 å¾
å®¡æ¹ --审æ¹éè¿--> 10 å·²æ¹å --å®å·¥ç»è®°--> 20 å·²å®å·¥ --彿¡£--> 30 已彿¡£ |
| | | -- â |
| | | -- â--审æ¹é©³å--> 90 已驳å |
| | | -- |
| | | -- 使ç¨çº¦æï¼æå¡ç«¯å¼ºæ ¡éªï¼ï¼ |
| | | -- * ä½ä¸ç»ææ¶é´å¿
é¡»æäºå¼å§æ¶é´ |
| | | -- * 审æ¹éè¿åä¸å
è®¸åæ¹ä½ä¸ä¿¡æ¯ï¼éä½åºéå¼ï¼ |
| | | -- * 已彿¡£çä½ä¸ç¥¨åªè¯» |
| | | -- |
| | | -- å
å®¹ï¼ |
| | | -- 1. 建表 mes_safety_work_ticket |
| | | -- 2. åå
¸ï¼ä½ä¸ç±»å / ä½ä¸çº§å« / ä½ä¸ç¥¨ç¶æ |
| | | -- 3. èåæå¨ãå®å
¨ç产ãç®å½ä¸ |
| | | -- 4. ææè¶
级管çå |
| | | -- |
| | | -- ç¹æ§ï¼å¯é夿§è¡ |
| | | -- ===================================================================== |
| | | |
| | | CREATE TABLE IF NOT EXISTS `mes_safety_work_ticket` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `code` varchar(64) NOT NULL COMMENT 'ä½ä¸ç¥¨å·', |
| | | |
| | | `ticket_type` tinyint NOT NULL COMMENT 'ä½ä¸ç±»åï¼åå
¸ mes_safety_ticket_typeï¼', |
| | | `ticket_level` tinyint DEFAULT NULL COMMENT 'ä½ä¸çº§å«ï¼åå
¸ mes_safety_ticket_levelï¼', |
| | | |
| | | `unit_id` bigint DEFAULT NULL COMMENT 'å
³èé£é©åå
ç¼å·', |
| | | `workshop_id` bigint DEFAULT NULL COMMENT 'æå±è½¦é´ç¼å·', |
| | | `work_location` varchar(255) DEFAULT NULL COMMENT 'ä½ä¸å°ç¹', |
| | | `work_content` varchar(1000) DEFAULT NULL COMMENT 'ä½ä¸å
容', |
| | | |
| | | `plan_start_time` datetime DEFAULT NULL COMMENT '计åå¼å§æ¶é´', |
| | | `plan_end_time` datetime DEFAULT NULL COMMENT '计åç»ææ¶é´', |
| | | `actual_start_time` datetime DEFAULT NULL COMMENT 'å®é
å¼å§æ¶é´', |
| | | `actual_end_time` datetime DEFAULT NULL COMMENT 'å®é
ç»ææ¶é´', |
| | | |
| | | `applicant_user_id` bigint DEFAULT NULL COMMENT 'ç³è¯·äººç¼å·', |
| | | `applicant_dept_id` bigint DEFAULT NULL COMMENT 'ç³è¯·é¨é¨ç¼å·', |
| | | `contractor` varchar(200) DEFAULT NULL COMMENT 'æ½å·¥åä½/æ¿å
å', |
| | | `worker_names` varchar(500) DEFAULT NULL COMMENT 'ä½ä¸äººåï¼å¤ä¸ªç¨éå·åéï¼', |
| | | `guardian_user_id` bigint DEFAULT NULL COMMENT 'çæ¤äººç¼å·', |
| | | `guardian_confirm` bit(1) DEFAULT b'0' COMMENT 'çæ¤äººæ¯å¦å·²ç¡®è®¤', |
| | | |
| | | `safety_measures` varchar(2000) DEFAULT NULL COMMENT 'å®å
¨æªæ½', |
| | | `safety_check_result` varchar(1000) DEFAULT NULL COMMENT 'å®å
¨äº¤åº/æ£æ¥ç»æ', |
| | | |
| | | `approver_user_id` bigint DEFAULT NULL COMMENT '审æ¹äººç¼å·', |
| | | `approve_time` datetime DEFAULT NULL COMMENT 'å®¡æ¹æ¶é´', |
| | | `approve_comment` varchar(500) DEFAULT NULL COMMENT 'å®¡æ¹æè§', |
| | | `reject_reason` varchar(500) DEFAULT NULL COMMENT '驳ååå ', |
| | | |
| | | `status` tinyint NOT NULL DEFAULT '0' COMMENT 'ç¶æï¼0å¾
å®¡æ¹ 10å·²æ¹å 20å·²å®å·¥ 30已彿¡£ 90已驳å', |
| | | |
| | | `close_time` datetime DEFAULT NULL COMMENT '彿¡£æ¶é´', |
| | | `close_user_id` bigint DEFAULT NULL COMMENT '彿¡£äººç¼å·', |
| | | `close_remark` varchar(500) DEFAULT NULL COMMENT 'å®å·¥/彿¡£è¯´æ', |
| | | |
| | | `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, |
| | | KEY `idx_status` (`status`) USING BTREE, |
| | | KEY `idx_type` (`ticket_type`) USING BTREE, |
| | | KEY `idx_plan_start` (`plan_start_time`) USING BTREE |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='å®å
¨ç产-ç¹ç§ä½ä¸ç¥¨è¯'; |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- åå
¸ |
| | | -- --------------------------------------------------------------------- |
| | | DELETE FROM system_dict_data WHERE dict_type IN |
| | | ('mes_safety_ticket_type', 'mes_safety_ticket_level', 'mes_safety_ticket_status'); |
| | | |
| | | DELETE FROM system_dict_type WHERE type IN |
| | | ('mes_safety_ticket_type', 'mes_safety_ticket_level', 'mes_safety_ticket_status'); |
| | | |
| | | INSERT INTO system_dict_type (name, type, status, remark, creator, create_time, updater, update_time, deleted) |
| | | VALUES ('å®å
¨ç产-ä½ä¸ç±»å', 'mes_safety_ticket_type', 0, 'ç¹ç§ä½ä¸ç¥¨è¯ç±»å', '1', NOW(), '1', NOW(), b'0'), |
| | | ('å®å
¨ç产-ä½ä¸çº§å«', 'mes_safety_ticket_level', 0, 'å¨ç«/é«å¤çæé£é©å级çä½ä¸çº§å«', '1', NOW(), '1', NOW(), b'0'), |
| | | ('å®å
¨ç产-ä½ä¸ç¥¨ç¶æ', 'mes_safety_ticket_status', 0, 'ä½ä¸ç¥¨å®¡æ¹ä¸å½æ¡£ç¶æ', '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_safety_ticket_type', 0, 'error', '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 'åé空é´ä½ä¸', '2', 'mes_safety_ticket_type', 0, 'warning', '1', NOW(), '1', NOW(), b'0'), |
| | | (3, 'é«å¤ä½ä¸', '3', 'mes_safety_ticket_type', 0, 'warning', '1', NOW(), '1', NOW(), b'0'), |
| | | (4, 'åè£
ä½ä¸', '4', 'mes_safety_ticket_type', 0, 'processing', '1', NOW(), '1', NOW(), b'0'), |
| | | (5, '临æ¶ç¨çµä½ä¸', '5', 'mes_safety_ticket_type', 0, 'processing', '1', NOW(), '1', NOW(), b'0'), |
| | | (6, 'æè·¯ä½ä¸', '6', 'mes_safety_ticket_type', 0, 'default', '1', NOW(), '1', NOW(), b'0'), |
| | | (7, 'ç²æ¿æ½å µä½ä¸', '7', 'mes_safety_ticket_type', 0, 'warning', '1', NOW(), '1', NOW(), b'0'), |
| | | (8, 'è®¾å¤æ£ä¿®ä½ä¸', '8', 'mes_safety_ticket_type', 0, 'default', '1', NOW(), '1', NOW(), b'0'), |
| | | -- ä½ä¸çº§å« |
| | | (1, 'ç¹æ®ä½ä¸', '1', 'mes_safety_ticket_level', 0, 'error', '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 'ä¸çº§ä½ä¸', '2', 'mes_safety_ticket_level', 0, 'warning', '1', NOW(), '1', NOW(), b'0'), |
| | | (3, 'äºçº§ä½ä¸', '3', 'mes_safety_ticket_level', 0, 'processing', '1', NOW(), '1', NOW(), b'0'), |
| | | (4, 'ä¸çº§ä½ä¸', '4', 'mes_safety_ticket_level', 0, 'success', '1', NOW(), '1', NOW(), b'0'), |
| | | -- ä½ä¸ç¥¨ç¶æ |
| | | (1, 'å¾
审æ¹', '0', 'mes_safety_ticket_status', 0, 'processing', '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 'å·²æ¹å', '10', 'mes_safety_ticket_status', 0, 'success', '1', NOW(), '1', NOW(), b'0'), |
| | | (3, 'å·²å®å·¥', '20', 'mes_safety_ticket_status', 0, 'default', '1', NOW(), '1', NOW(), b'0'), |
| | | (4, '已彿¡£', '30', 'mes_safety_ticket_status', 0, 'default', '1', NOW(), '1', NOW(), b'0'), |
| | | (5, '已驳å', '90', 'mes_safety_ticket_status', 0, 'error', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- èåï¼æå¨ 1065910 å®å
¨ç产ä¸ï¼ |
| | | -- --------------------------------------------------------------------- |
| | | DELETE FROM system_role_menu WHERE menu_id BETWEEN 1065934 AND 1065950; |
| | | |
| | | DELETE FROM system_menu WHERE id BETWEEN 1065934 AND 1065950; |
| | | |
| | | 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 |
| | | (1065934, 'ç¹ç§ä½ä¸ç¥¨è¯', '', 2, 5, 1065910, 'work-ticket', 'ep:tickets', |
| | | 'safety/ticket/index', 'SafetyWorkTicket', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065935, 'ä½ä¸ç¥¨æ¥è¯¢', 'mes:safety-ticket:query', 3, 1, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065936, 'ä½ä¸ç¥¨ç³è¯·', 'mes:safety-ticket:create', 3, 2, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065937, 'ä½ä¸ç¥¨ä¿®æ¹', 'mes:safety-ticket:update', 3, 3, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065938, 'ä½ä¸ç¥¨å é¤', 'mes:safety-ticket:delete', 3, 4, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065939, 'ä½ä¸ç¥¨å®¡æ¹', 'mes:safety-ticket:approve', 3, 5, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065940, 'å®å·¥å½æ¡£', 'mes:safety-ticket:close', 3, 6, 1065934, '', '', NULL, NULL, 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | 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 1065934 AND 1065950; |
| | | |
| | | -- --------------------------------------------------------------------- |
| | | -- éªè¯ |
| | | -- --------------------------------------------------------------------- |
| | | SELECT id, parent_id, name, path, component, permission, type |
| | | FROM system_menu WHERE id BETWEEN 1065910 AND 1065950 ORDER BY id; |
| | | |
| | | SELECT dict_type, label, value FROM system_dict_data |
| | | WHERE dict_type LIKE 'mes_safety_ticket%' ORDER BY dict_type, sort; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety; |
| | | |
| | | 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.security.core.util.SecurityFrameworkUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketApproveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketCloseReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkshopDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyRiskUnitDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyWorkTicketDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkshopMapper; |
| | | import cn.iocoder.yudao.module.mes.service.safety.MesSafetyRiskUnitService; |
| | | import cn.iocoder.yudao.module.mes.service.safety.MesSafetyWorkTicketService; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | /** |
| | | * å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ Controller |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Tag(name = "管çåå° - å®å
¨ç产-ç¹ç§ä½ä¸ç¥¨è¯") |
| | | @RestController |
| | | @RequestMapping("/mes/safety/work-ticket") |
| | | @Validated |
| | | public class MesSafetyWorkTicketController { |
| | | |
| | | @Resource |
| | | private MesSafetyWorkTicketService ticketService; |
| | | |
| | | @Resource |
| | | private MesSafetyRiskUnitService riskUnitService; |
| | | |
| | | @Resource |
| | | private MesMdWorkshopMapper workshopMapper; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "ç³è¯·ä½ä¸ç¥¨") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:create')") |
| | | public CommonResult<Long> createTicket(@Valid @RequestBody MesSafetyWorkTicketSaveReqVO createReqVO) { |
| | | return success(ticketService.createTicket(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "ä¿®æ¹ä½ä¸ç¥¨") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:update')") |
| | | public CommonResult<Boolean> updateTicket(@Valid @RequestBody MesSafetyWorkTicketSaveReqVO updateReqVO) { |
| | | ticketService.updateTicket(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤ä½ä¸ç¥¨") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:delete')") |
| | | public CommonResult<Boolean> deleteTicket(@RequestParam("id") Long id) { |
| | | ticketService.deleteTicket(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/approve") |
| | | @Operation(summary = "审æ¹ä½ä¸ç¥¨") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:approve')") |
| | | public CommonResult<Boolean> approveTicket(@Valid @RequestBody MesSafetyWorkTicketApproveReqVO reqVO) { |
| | | ticketService.approveTicket(SecurityFrameworkUtils.getLoginUserId(), reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/close") |
| | | @Operation(summary = "å®å·¥ç»è®° / 彿¡£") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:close')") |
| | | public CommonResult<Boolean> closeTicket(@Valid @RequestBody MesSafetyWorkTicketCloseReqVO reqVO) { |
| | | ticketService.closeTicket(SecurityFrameworkUtils.getLoginUserId(), reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾ä½ä¸ç¥¨") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:query')") |
| | | public CommonResult<MesSafetyWorkTicketRespVO> getTicket(@RequestParam("id") Long id) { |
| | | MesSafetyWorkTicketDO ticket = ticketService.getTicket(id); |
| | | if (ticket == null) { |
| | | return success(null); |
| | | } |
| | | List<MesSafetyWorkTicketRespVO> list = buildRespList(Collections.singletonList(ticket)); |
| | | return success(list.isEmpty() ? null : list.get(0)); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾ä½ä¸ç¥¨å页") |
| | | @PreAuthorize("@ss.hasPermission('mes:safety-ticket:query')") |
| | | public CommonResult<PageResult<MesSafetyWorkTicketRespVO>> getTicketPage(@Valid MesSafetyWorkTicketPageReqVO pageReqVO) { |
| | | PageResult<MesSafetyWorkTicketDO> pageResult = ticketService.getTicketPage(pageReqVO); |
| | | List<MesSafetyWorkTicketRespVO> list = buildRespList(pageResult.getList()); |
| | | return success(new PageResult<>(list, pageResult.getTotal())); |
| | | } |
| | | |
| | | /** |
| | | * 转æ¢ä¸º VO å¹¶å¡«å
车é´ã人åãé£é©åå
åç§°ãè¶
ææ è®° |
| | | */ |
| | | private List<MesSafetyWorkTicketRespVO> buildRespList(List<MesSafetyWorkTicketDO> list) { |
| | | if (list == null || list.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<MesSafetyWorkTicketRespVO> respList = BeanUtils.toBean(list, MesSafetyWorkTicketRespVO.class); |
| | | |
| | | // 车é´åç§° |
| | | Set<Long> workshopIds = list.stream().map(MesSafetyWorkTicketDO::getWorkshopId) |
| | | .filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> workshopNameMap = new HashMap<>(); |
| | | if (!workshopIds.isEmpty()) { |
| | | List<MesMdWorkshopDO> workshops = workshopMapper.selectByIds(workshopIds); |
| | | workshops.forEach(w -> workshopNameMap.put(w.getId(), w.getName())); |
| | | } |
| | | |
| | | // 人åå§å |
| | | Set<Long> userIds = new HashSet<>(); |
| | | list.forEach(t -> { |
| | | if (t.getApplicantUserId() != null) userIds.add(t.getApplicantUserId()); |
| | | if (t.getGuardianUserId() != null) userIds.add(t.getGuardianUserId()); |
| | | if (t.getApproverUserId() != null) userIds.add(t.getApproverUserId()); |
| | | }); |
| | | Map<Long, AdminUserRespDTO> userMap = userIds.isEmpty() |
| | | ? Collections.emptyMap() : adminUserApi.getUserMap(userIds); |
| | | |
| | | // é£é©åå
åç§° |
| | | Set<Long> unitIds = list.stream().map(MesSafetyWorkTicketDO::getUnitId) |
| | | .filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, MesSafetyRiskUnitDO> unitMap = riskUnitService.getRiskUnitMap(unitIds); |
| | | |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | for (MesSafetyWorkTicketRespVO vo : respList) { |
| | | vo.setWorkshopName(workshopNameMap.get(vo.getWorkshopId())); |
| | | vo.setApplicantUserName(nickname(userMap, vo.getApplicantUserId())); |
| | | vo.setGuardianUserName(nickname(userMap, vo.getGuardianUserId())); |
| | | vo.setApproverUserName(nickname(userMap, vo.getApproverUserId())); |
| | | MesSafetyRiskUnitDO unit = unitMap.get(vo.getUnitId()); |
| | | if (unit != null) { |
| | | vo.setUnitName(unit.getName()); |
| | | } |
| | | // è¶
æï¼å·²æ¹åä½è®¡åç»ææ¶é´å·²è¿ |
| | | vo.setOverdue(MesSafetyWorkTicketDO.STATUS_APPROVED.equals(vo.getStatus()) |
| | | && vo.getPlanEndTime() != null |
| | | && vo.getPlanEndTime().isBefore(now)); |
| | | } |
| | | return respList; |
| | | } |
| | | |
| | | private String nickname(Map<Long, AdminUserRespDTO> userMap, Long userId) { |
| | | if (userId == null) { |
| | | return null; |
| | | } |
| | | AdminUserRespDTO user = userMap.get(userId); |
| | | return user != null ? user.getNickname() : null; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | @Schema(description = "管çåå° - å®å
¨ç产-ä½ä¸ç¥¨å®¡æ¹ Request VO") |
| | | @Data |
| | | public class MesSafetyWorkTicketApproveReqVO { |
| | | |
| | | @Schema(description = "ä½ä¸ç¥¨ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "ä½ä¸ç¥¨ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æ¯å¦éè¿", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") |
| | | @NotNull(message = "审æ¹ç»è®ºä¸è½ä¸ºç©º") |
| | | private Boolean pass; |
| | | |
| | | @Schema(description = "å®¡æ¹æè§", example = "å®å
¨æªæ½å°ä½ï¼åæä½ä¸") |
| | | private String approveComment; |
| | | |
| | | @Schema(description = "驳ååå ï¼ä¸éè¿æ¶å¿
å¡«ï¼", example = "å®å
¨æªæ½ä¸å®åï¼ç¼ºå°æ°ä½æ£æµ") |
| | | private String rejectReason; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - å®å
¨ç产-ä½ä¸ç¥¨å®å·¥/彿¡£ Request VO") |
| | | @Data |
| | | public class MesSafetyWorkTicketCloseReqVO { |
| | | |
| | | @Schema(description = "ä½ä¸ç¥¨ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "ä½ä¸ç¥¨ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æ¯å¦ç´æ¥å½æ¡£ï¼false=ä»
ç»è®°å®å·¥ï¼å·²æ¹åâå·²å®å·¥ï¼ï¼true=å®å·¥å¹¶å½æ¡£ï¼â已彿¡£ï¼", |
| | | example = "false") |
| | | private Boolean archive; |
| | | |
| | | @Schema(description = "å®é
å¼å§æ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime actualStartTime; |
| | | |
| | | @Schema(description = "å®é
ç»ææ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime actualEndTime; |
| | | |
| | | @Schema(description = "å®å·¥ / 彿¡£è¯´æ", example = "ä½ä¸å®æï¼ç°åºå·²æ¸
ç") |
| | | private String closeRemark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket; |
| | | |
| | | 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; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - å®å
¨ç产-ä½ä¸ç¥¨å页 Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class MesSafetyWorkTicketPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "ä½ä¸ç¥¨å·", example = "ZY-2026-001") |
| | | private String code; |
| | | |
| | | @Schema(description = "ä½ä¸ç±»å", example = "1") |
| | | private Integer ticketType; |
| | | |
| | | @Schema(description = "ä½ä¸çº§å«", example = "2") |
| | | private Integer ticketLevel; |
| | | |
| | | @Schema(description = "ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "æå±è½¦é´ç¼å·", example = "7") |
| | | private Long workshopId; |
| | | |
| | | @Schema(description = "ç³è¯·äººç¼å·", example = "1") |
| | | private Long applicantUserId; |
| | | |
| | | @Schema(description = "ä½ä¸å°ç¹", example = "é 纸车é´") |
| | | private String workLocation; |
| | | |
| | | @Schema(description = "计åå¼å§æ¶é´-èµ·") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime planStartTimeStart; |
| | | |
| | | @Schema(description = "计åå¼å§æ¶é´-æ¢") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime planStartTimeEnd; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - å®å
¨ç产-ä½ä¸ç¥¨ Response VO") |
| | | @Data |
| | | public class MesSafetyWorkTicketRespVO { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1024") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ä½ä¸ç¥¨å·", example = "ZY-2026-001") |
| | | private String code; |
| | | |
| | | @Schema(description = "ä½ä¸ç±»å", example = "1") |
| | | private Integer ticketType; |
| | | |
| | | @Schema(description = "ä½ä¸çº§å«", example = "2") |
| | | private Integer ticketLevel; |
| | | |
| | | @Schema(description = "å
³èé£é©åå
ç¼å·", example = "1") |
| | | private Long unitId; |
| | | |
| | | @Schema(description = "å
³èé£é©åå
åç§°") |
| | | private String unitName; |
| | | |
| | | @Schema(description = "æå±è½¦é´ç¼å·", example = "7") |
| | | private Long workshopId; |
| | | |
| | | @Schema(description = "æå±è½¦é´åç§°") |
| | | private String workshopName; |
| | | |
| | | @Schema(description = "ä½ä¸å°ç¹") |
| | | private String workLocation; |
| | | |
| | | @Schema(description = "ä½ä¸å
容") |
| | | private String workContent; |
| | | |
| | | @Schema(description = "计åå¼å§æ¶é´") |
| | | private LocalDateTime planStartTime; |
| | | |
| | | @Schema(description = "计åç»ææ¶é´") |
| | | private LocalDateTime planEndTime; |
| | | |
| | | @Schema(description = "å®é
å¼å§æ¶é´") |
| | | private LocalDateTime actualStartTime; |
| | | |
| | | @Schema(description = "å®é
ç»ææ¶é´") |
| | | private LocalDateTime actualEndTime; |
| | | |
| | | @Schema(description = "ç³è¯·äººç¼å·", example = "1") |
| | | private Long applicantUserId; |
| | | |
| | | @Schema(description = "ç³è¯·äººå§å") |
| | | private String applicantUserName; |
| | | |
| | | @Schema(description = "ç³è¯·é¨é¨ç¼å·", example = "120") |
| | | private Long applicantDeptId; |
| | | |
| | | @Schema(description = "æ½å·¥åä½ / æ¿å
å") |
| | | private String contractor; |
| | | |
| | | @Schema(description = "ä½ä¸äººå") |
| | | private String workerNames; |
| | | |
| | | @Schema(description = "çæ¤äººç¼å·", example = "1") |
| | | private Long guardianUserId; |
| | | |
| | | @Schema(description = "çæ¤äººå§å") |
| | | private String guardianUserName; |
| | | |
| | | @Schema(description = "çæ¤äººæ¯å¦å·²ç¡®è®¤") |
| | | private Boolean guardianConfirm; |
| | | |
| | | @Schema(description = "å®å
¨æªæ½") |
| | | private String safetyMeasures; |
| | | |
| | | @Schema(description = "å®å
¨äº¤åº / æ£æ¥ç»æ") |
| | | private String safetyCheckResult; |
| | | |
| | | @Schema(description = "审æ¹äººç¼å·", example = "1") |
| | | private Long approverUserId; |
| | | |
| | | @Schema(description = "审æ¹äººå§å") |
| | | private String approverUserName; |
| | | |
| | | @Schema(description = "å®¡æ¹æ¶é´") |
| | | private LocalDateTime approveTime; |
| | | |
| | | @Schema(description = "å®¡æ¹æè§") |
| | | private String approveComment; |
| | | |
| | | @Schema(description = "驳ååå ") |
| | | private String rejectReason; |
| | | |
| | | @Schema(description = "ç¶æ", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "æ¯å¦å·²è¶
è¿è®¡åç»ææ¶é´ä»æªå®å·¥", example = "false") |
| | | private Boolean overdue; |
| | | |
| | | @Schema(description = "彿¡£æ¶é´") |
| | | private LocalDateTime closeTime; |
| | | |
| | | @Schema(description = "彿¡£äººç¼å·", example = "1") |
| | | private Long closeUserId; |
| | | |
| | | @Schema(description = "å®å·¥ / 彿¡£è¯´æ") |
| | | private String closeRemark; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | |
| | | @Schema(description = "管çåå° - å®å
¨ç产-ä½ä¸ç¥¨ç³è¯·/ä¿®æ¹ Request VO") |
| | | @Data |
| | | public class MesSafetyWorkTicketSaveReqVO { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1024") |
| | | private Long id; |
| | | |
| | | @Schema(description = "ä½ä¸ç¥¨å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "ZY-2026-001") |
| | | @NotEmpty(message = "ä½ä¸ç¥¨å·ä¸è½ä¸ºç©º") |
| | | private String code; |
| | | |
| | | @Schema(description = "ä½ä¸ç±»å", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "ä½ä¸ç±»åä¸è½ä¸ºç©º") |
| | | private Integer ticketType; |
| | | |
| | | @Schema(description = "ä½ä¸çº§å«", example = "2") |
| | | private Integer ticketLevel; |
| | | |
| | | @Schema(description = "å
³èé£é©åå
ç¼å·", example = "1") |
| | | private Long unitId; |
| | | |
| | | @Schema(description = "æå±è½¦é´ç¼å·", example = "7") |
| | | private Long workshopId; |
| | | |
| | | @Schema(description = "ä½ä¸å°ç¹", example = "é 纸车é´ä¸ä¾§ç®¡é") |
| | | private String workLocation; |
| | | |
| | | @Schema(description = "ä½ä¸å
容", example = "管éçæ¥") |
| | | private String workContent; |
| | | |
| | | @Schema(description = "计åå¼å§æ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime planStartTime; |
| | | |
| | | @Schema(description = "计åç»ææ¶é´") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime planEndTime; |
| | | |
| | | @Schema(description = "ç³è¯·é¨é¨ç¼å·", example = "120") |
| | | private Long applicantDeptId; |
| | | |
| | | @Schema(description = "æ½å·¥åä½ / æ¿å
å", example = "XX å®è£
å
¬å¸") |
| | | private String contractor; |
| | | |
| | | @Schema(description = "ä½ä¸äººåï¼å¤ä¸ªç¨éå·åéï¼", example = "å¼ ä¸,æå") |
| | | private String workerNames; |
| | | |
| | | @Schema(description = "çæ¤äººç¼å·", example = "1") |
| | | private Long guardianUserId; |
| | | |
| | | @Schema(description = "å®å
¨æªæ½", example = "1.æ¸
çå¨ç«ç¹å¨è¾¹å¯çç©ï¼2.é
å¤çç«å¨") |
| | | private String safetyMeasures; |
| | | |
| | | @Schema(description = "å®å
¨äº¤åº / æ£æ¥ç»æ") |
| | | private String safetyCheckResult; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.safety; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ DO |
| | | * |
| | | * ç¶ææµè½¬ï¼ |
| | | * 0 å¾
å®¡æ¹ --审æ¹éè¿--> 10 å·²æ¹å --å®å·¥ç»è®°--> 20 å·²å®å·¥ --彿¡£--> 30 已彿¡£ |
| | | * â--审æ¹é©³å--> 90 已驳å |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @TableName("mes_safety_work_ticket") |
| | | @KeySequence("mes_safety_work_ticket_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesSafetyWorkTicketDO extends BaseDO { |
| | | |
| | | /** ç¶æï¼å¾
å®¡æ¹ */ |
| | | public static final Integer STATUS_PENDING = 0; |
| | | /** ç¶æï¼å·²æ¹åï¼å¯ä½ä¸ï¼ */ |
| | | public static final Integer STATUS_APPROVED = 10; |
| | | /** ç¶æï¼å·²å®å·¥ */ |
| | | public static final Integer STATUS_FINISHED = 20; |
| | | /** ç¶æï¼å·²å½æ¡£ */ |
| | | public static final Integer STATUS_ARCHIVED = 30; |
| | | /** ç¶æï¼å·²é©³å */ |
| | | public static final Integer STATUS_REJECTED = 90; |
| | | |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * ä½ä¸ç¥¨å· |
| | | */ |
| | | private String code; |
| | | |
| | | /** |
| | | * ä½ä¸ç±»å |
| | | * |
| | | * åå
¸ mes_safety_ticket_typeï¼1å¨ç« 2åéç©ºé´ 3é«å¤ 4åè£
5临æ¶ç¨çµ 6æè·¯ 7ç²æ¿æ½å µ 8è®¾å¤æ£ä¿® |
| | | */ |
| | | private Integer ticketType; |
| | | |
| | | /** |
| | | * ä½ä¸çº§å« |
| | | * |
| | | * åå
¸ mes_safety_ticket_levelï¼1ç¹æ® 2ä¸çº§ 3äºçº§ 4ä¸çº§ |
| | | */ |
| | | private Integer ticketLevel; |
| | | |
| | | /** |
| | | * å
³èé£é©åå
ç¼å· |
| | | */ |
| | | private Long unitId; |
| | | |
| | | /** |
| | | * æå±è½¦é´ç¼å· |
| | | */ |
| | | private Long workshopId; |
| | | |
| | | /** |
| | | * ä½ä¸å°ç¹ |
| | | */ |
| | | private String workLocation; |
| | | |
| | | /** |
| | | * ä½ä¸å
容 |
| | | */ |
| | | private String workContent; |
| | | |
| | | /** |
| | | * 计åå¼å§æ¶é´ |
| | | */ |
| | | private LocalDateTime planStartTime; |
| | | |
| | | /** |
| | | * 计åç»ææ¶é´ |
| | | */ |
| | | private LocalDateTime planEndTime; |
| | | |
| | | /** |
| | | * å®é
å¼å§æ¶é´ |
| | | */ |
| | | private LocalDateTime actualStartTime; |
| | | |
| | | /** |
| | | * å®é
ç»ææ¶é´ |
| | | */ |
| | | private LocalDateTime actualEndTime; |
| | | |
| | | /** |
| | | * ç³è¯·äººç¼å· |
| | | */ |
| | | private Long applicantUserId; |
| | | |
| | | /** |
| | | * ç³è¯·é¨é¨ç¼å· |
| | | */ |
| | | private Long applicantDeptId; |
| | | |
| | | /** |
| | | * æ½å·¥åä½ / æ¿å
å |
| | | */ |
| | | private String contractor; |
| | | |
| | | /** |
| | | * ä½ä¸äººåï¼å¤ä¸ªç¨éå·åéï¼ |
| | | */ |
| | | private String workerNames; |
| | | |
| | | /** |
| | | * çæ¤äººç¼å· |
| | | */ |
| | | private Long guardianUserId; |
| | | |
| | | /** |
| | | * çæ¤äººæ¯å¦å·²ç¡®è®¤ |
| | | */ |
| | | private Boolean guardianConfirm; |
| | | |
| | | /** |
| | | * å®å
¨æªæ½ |
| | | */ |
| | | private String safetyMeasures; |
| | | |
| | | /** |
| | | * å®å
¨äº¤åº / æ£æ¥ç»æ |
| | | */ |
| | | private String safetyCheckResult; |
| | | |
| | | /** |
| | | * 审æ¹äººç¼å· |
| | | */ |
| | | private Long approverUserId; |
| | | |
| | | /** |
| | | * å®¡æ¹æ¶é´ |
| | | */ |
| | | private LocalDateTime approveTime; |
| | | |
| | | /** |
| | | * å®¡æ¹æè§ |
| | | */ |
| | | private String approveComment; |
| | | |
| | | /** |
| | | * 驳ååå |
| | | */ |
| | | private String rejectReason; |
| | | |
| | | /** |
| | | * ç¶æï¼0å¾
å®¡æ¹ 10å·²æ¹å 20å·²å®å·¥ 30已彿¡£ 90已驳å |
| | | */ |
| | | private Integer status; |
| | | |
| | | /** |
| | | * 彿¡£æ¶é´ |
| | | */ |
| | | private LocalDateTime closeTime; |
| | | |
| | | /** |
| | | * 彿¡£äººç¼å· |
| | | */ |
| | | private Long closeUserId; |
| | | |
| | | /** |
| | | * å®å·¥ / 彿¡£è¯´æ |
| | | */ |
| | | private String closeRemark; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.safety; |
| | | |
| | | 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.safety.vo.ticket.MesSafetyWorkTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyWorkTicketDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ Mapper |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Mapper |
| | | public interface MesSafetyWorkTicketMapper extends BaseMapperX<MesSafetyWorkTicketDO> { |
| | | |
| | | default PageResult<MesSafetyWorkTicketDO> selectPage(MesSafetyWorkTicketPageReqVO reqVO) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesSafetyWorkTicketDO>() |
| | | .likeIfPresent(MesSafetyWorkTicketDO::getCode, reqVO.getCode()) |
| | | .eqIfPresent(MesSafetyWorkTicketDO::getTicketType, reqVO.getTicketType()) |
| | | .eqIfPresent(MesSafetyWorkTicketDO::getTicketLevel, reqVO.getTicketLevel()) |
| | | .eqIfPresent(MesSafetyWorkTicketDO::getStatus, reqVO.getStatus()) |
| | | .eqIfPresent(MesSafetyWorkTicketDO::getWorkshopId, reqVO.getWorkshopId()) |
| | | .eqIfPresent(MesSafetyWorkTicketDO::getApplicantUserId, reqVO.getApplicantUserId()) |
| | | .likeIfPresent(MesSafetyWorkTicketDO::getWorkLocation, reqVO.getWorkLocation()) |
| | | .geIfPresent(MesSafetyWorkTicketDO::getPlanStartTime, reqVO.getPlanStartTimeStart()) |
| | | .leIfPresent(MesSafetyWorkTicketDO::getPlanStartTime, reqVO.getPlanStartTimeEnd()) |
| | | .orderByDesc(MesSafetyWorkTicketDO::getId)); |
| | | } |
| | | |
| | | default MesSafetyWorkTicketDO selectByCode(String code) { |
| | | return selectOne(MesSafetyWorkTicketDO::getCode, code); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢å½åå¤äºãå·²æ¹åãä½å·²è¶
è¿è®¡åç»ææ¶é´çä½ä¸ç¥¨ï¼ç¨äºè¶
ææªå®å·¥æéï¼ |
| | | */ |
| | | default List<MesSafetyWorkTicketDO> selectApprovedOverdueList(LocalDateTime now) { |
| | | return selectList(new LambdaQueryWrapperX<MesSafetyWorkTicketDO>() |
| | | .eq(MesSafetyWorkTicketDO::getStatus, MesSafetyWorkTicketDO.STATUS_APPROVED) |
| | | .lt(MesSafetyWorkTicketDO::getPlanEndTime, now) |
| | | .orderByAsc(MesSafetyWorkTicketDO::getPlanEndTime)); |
| | | } |
| | | |
| | | default Long selectCountByStatus(Integer status) { |
| | | return selectCount(new LambdaQueryWrapperX<MesSafetyWorkTicketDO>() |
| | | .eq(MesSafetyWorkTicketDO::getStatus, status)); |
| | | } |
| | | |
| | | default Long selectCountByUnitId(Long unitId) { |
| | | return selectCount(new LambdaQueryWrapperX<MesSafetyWorkTicketDO>() |
| | | .eq(MesSafetyWorkTicketDO::getUnitId, unitId)); |
| | | } |
| | | |
| | | default List<MesSafetyWorkTicketDO> selectAllList() { |
| | | return selectList(new LambdaQueryWrapperX<MesSafetyWorkTicketDO>() |
| | | .orderByDesc(MesSafetyWorkTicketDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | String MES_SAFETY_HAZARD_SOURCE = "mes_safety_hazard_source"; // éæ£æ¥æº |
| | | String MES_SAFETY_HAZARD_LEVEL = "mes_safety_hazard_level"; // 鿣ç级ï¼1ä¸è¬ 2éå¤§ï¼ |
| | | String MES_SAFETY_HAZARD_STATUS = "mes_safety_hazard_status"; // éæ£ç¶æ |
| | | |
| | | // ç¹ç§ä½ä¸ç¥¨è¯ |
| | | String MES_SAFETY_TICKET_TYPE = "mes_safety_ticket_type"; // ä½ä¸ç±»å |
| | | String MES_SAFETY_TICKET_LEVEL = "mes_safety_ticket_level"; // ä½ä¸çº§å« |
| | | String MES_SAFETY_TICKET_STATUS = "mes_safety_ticket_status"; // ä½ä¸ç¥¨ç¶æ |
| | | } |
| | |
| | | ErrorCode MES_SAFETY_HAZARD_REJECT_REASON_REQUIRED = new ErrorCode(1_040_905_003, "éªæ¶ä¸éè¿æ¶å¿
须填å驳ååå "); |
| | | ErrorCode MES_SAFETY_HAZARD_HAS_REFERENCE = new ErrorCode(1_040_905_004, "该记å½å·²è¢«éæ£å¼ç¨ï¼æ æ³å é¤"); |
| | | |
| | | // ========== MES å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ï¼1-040-906-000ï¼ ========== |
| | | ErrorCode MES_SAFETY_TICKET_NOT_EXISTS = new ErrorCode(1_040_906_000, "ä½ä¸ç¥¨ä¸åå¨"); |
| | | ErrorCode MES_SAFETY_TICKET_CODE_DUPLICATE = new ErrorCode(1_040_906_001, "ä½ä¸ç¥¨å·å·²åå¨"); |
| | | ErrorCode MES_SAFETY_TICKET_STATUS_INVALID = new ErrorCode(1_040_906_002, "å½åä½ä¸ç¥¨ç¶æä¸å
许该æä½"); |
| | | ErrorCode MES_SAFETY_TICKET_TIME_INVALID = new ErrorCode(1_040_906_003, "计åç»ææ¶é´å¿
é¡»æäºè®¡åå¼å§æ¶é´"); |
| | | ErrorCode MES_SAFETY_TICKET_REJECT_REASON_REQUIRED = new ErrorCode(1_040_906_004, "审æ¹é©³åæ¶å¿
须填å驳ååå "); |
| | | ErrorCode MES_SAFETY_TICKET_HAS_REFERENCE = new ErrorCode(1_040_906_005, "该记å½å·²è¢«ä½ä¸ç¥¨å¼ç¨ï¼æ æ³å é¤"); |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyHazardMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyRiskMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyRiskUnitMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyWorkTicketMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | |
| | | |
| | | @Resource |
| | | private MesSafetyHazardMapper hazardMapper; |
| | | |
| | | @Resource |
| | | private MesSafetyWorkTicketMapper ticketMapper; |
| | | |
| | | @Override |
| | | public PageResult<MesSafetyRiskUnitDO> getRiskUnitPage(MesSafetyRiskUnitPageReqVO pageReqVO) { |
| | |
| | | if (hazardCount != null && hazardCount > 0) { |
| | | throw exception(MES_SAFETY_HAZARD_HAS_REFERENCE); |
| | | } |
| | | // 已被ä½ä¸ç¥¨å¼ç¨çåå
ä¹ä¸å
许å é¤ |
| | | Long ticketCount = ticketMapper.selectCountByUnitId(id); |
| | | if (ticketCount != null && ticketCount > 0) { |
| | | throw exception(MES_SAFETY_TICKET_HAS_REFERENCE); |
| | | } |
| | | riskUnitMapper.deleteById(id); |
| | | } |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.safety; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketApproveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketCloseReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyWorkTicketDO; |
| | | |
| | | /** |
| | | * å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ Service æ¥å£ |
| | | * |
| | | * ç¶ææµè½¬ï¼0å¾
å®¡æ¹ â 10å·²æ¹å â 20å·²å®å·¥ â 30已彿¡£ï¼0 â 90已驳å |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface MesSafetyWorkTicketService { |
| | | |
| | | PageResult<MesSafetyWorkTicketDO> getTicketPage(MesSafetyWorkTicketPageReqVO pageReqVO); |
| | | |
| | | MesSafetyWorkTicketDO getTicket(Long id); |
| | | |
| | | Long createTicket(MesSafetyWorkTicketSaveReqVO createReqVO); |
| | | |
| | | void updateTicket(MesSafetyWorkTicketSaveReqVO updateReqVO); |
| | | |
| | | void deleteTicket(Long id); |
| | | |
| | | /** |
| | | * 审æ¹ï¼0å¾
å®¡æ¹ â 10å·²æ¹åï¼æ â 90已驳å |
| | | * |
| | | * @param userId 审æ¹äººç¼å· |
| | | */ |
| | | void approveTicket(Long userId, MesSafetyWorkTicketApproveReqVO reqVO); |
| | | |
| | | /** |
| | | * å®å·¥ç»è®° / 彿¡£ï¼10å·²æ¹å â 20å·²å®å·¥ï¼20å·²å®å·¥ â 30已彿¡£ |
| | | * |
| | | * @param userId æä½äººç¼å· |
| | | */ |
| | | void closeTicket(Long userId, MesSafetyWorkTicketCloseReqVO reqVO); |
| | | |
| | | MesSafetyWorkTicketDO validateTicketExists(Long id); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.safety; |
| | | |
| | | 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.safety.vo.ticket.MesSafetyWorkTicketApproveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketCloseReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.safety.vo.ticket.MesSafetyWorkTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.safety.MesSafetyWorkTicketDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.safety.MesSafetyWorkTicketMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * å®å
¨ç产 - ç¹ç§ä½ä¸ç¥¨è¯ Service å®ç° |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesSafetyWorkTicketServiceImpl implements MesSafetyWorkTicketService { |
| | | |
| | | @Resource |
| | | private MesSafetyWorkTicketMapper ticketMapper; |
| | | |
| | | @Override |
| | | public PageResult<MesSafetyWorkTicketDO> getTicketPage(MesSafetyWorkTicketPageReqVO pageReqVO) { |
| | | return ticketMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | | @Override |
| | | public MesSafetyWorkTicketDO getTicket(Long id) { |
| | | return ticketMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public Long createTicket(MesSafetyWorkTicketSaveReqVO createReqVO) { |
| | | validateCodeUnique(null, createReqVO.getCode()); |
| | | validateTimeRange(createReqVO.getPlanStartTime(), createReqVO.getPlanEndTime()); |
| | | MesSafetyWorkTicketDO ticket = BeanUtils.toBean(createReqVO, MesSafetyWorkTicketDO.class); |
| | | // æ°å»ºå³å¾
å®¡æ¹ |
| | | ticket.setStatus(MesSafetyWorkTicketDO.STATUS_PENDING); |
| | | ticket.setGuardianConfirm(false); |
| | | ticketMapper.insert(ticket); |
| | | return ticket.getId(); |
| | | } |
| | | |
| | | @Override |
| | | public void updateTicket(MesSafetyWorkTicketSaveReqVO updateReqVO) { |
| | | MesSafetyWorkTicketDO exists = validateTicketExists(updateReqVO.getId()); |
| | | // 审æ¹éè¿åä¸å
è®¸åæ¹ä½ä¸ä¿¡æ¯ï¼éä½åºéå¼ |
| | | if (!MesSafetyWorkTicketDO.STATUS_PENDING.equals(exists.getStatus()) |
| | | && !MesSafetyWorkTicketDO.STATUS_REJECTED.equals(exists.getStatus())) { |
| | | throw exception(MES_SAFETY_TICKET_STATUS_INVALID); |
| | | } |
| | | validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); |
| | | validateTimeRange(updateReqVO.getPlanStartTime(), updateReqVO.getPlanEndTime()); |
| | | MesSafetyWorkTicketDO updateObj = BeanUtils.toBean(updateReqVO, MesSafetyWorkTicketDO.class); |
| | | // ç¶æä¸å®¡æ¹/彿¡£ä¿¡æ¯ä¸èµ°æ¤æ¥å£ |
| | | updateObj.setStatus(null); |
| | | updateObj.setApproverUserId(null); |
| | | updateObj.setApproveTime(null); |
| | | updateObj.setApproveComment(null); |
| | | updateObj.setRejectReason(null); |
| | | updateObj.setCloseTime(null); |
| | | updateObj.setCloseUserId(null); |
| | | updateObj.setCloseRemark(null); |
| | | updateObj.setActualStartTime(null); |
| | | updateObj.setActualEndTime(null); |
| | | // éæ°æäº¤æ¶æ¸
空驳ååå |
| | | if (MesSafetyWorkTicketDO.STATUS_REJECTED.equals(exists.getStatus())) { |
| | | updateObj.setStatus(MesSafetyWorkTicketDO.STATUS_PENDING); |
| | | updateObj.setRejectReason(""); |
| | | } |
| | | ticketMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteTicket(Long id) { |
| | | MesSafetyWorkTicketDO exists = validateTicketExists(id); |
| | | // å·²æ¹ååä¹åçä½ä¸ç¥¨ä¸å
许å é¤ï¼éä¿ç追溯记å½ï¼ |
| | | if (MesSafetyWorkTicketDO.STATUS_APPROVED.equals(exists.getStatus()) |
| | | || MesSafetyWorkTicketDO.STATUS_FINISHED.equals(exists.getStatus()) |
| | | || MesSafetyWorkTicketDO.STATUS_ARCHIVED.equals(exists.getStatus())) { |
| | | throw exception(MES_SAFETY_TICKET_STATUS_INVALID); |
| | | } |
| | | ticketMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | | public void approveTicket(Long userId, MesSafetyWorkTicketApproveReqVO reqVO) { |
| | | MesSafetyWorkTicketDO ticket = validateTicketExists(reqVO.getId()); |
| | | if (!MesSafetyWorkTicketDO.STATUS_PENDING.equals(ticket.getStatus())) { |
| | | throw exception(MES_SAFETY_TICKET_STATUS_INVALID); |
| | | } |
| | | MesSafetyWorkTicketDO updateObj = new MesSafetyWorkTicketDO(); |
| | | updateObj.setId(reqVO.getId()); |
| | | updateObj.setApproverUserId(userId); |
| | | updateObj.setApproveTime(LocalDateTime.now()); |
| | | updateObj.setApproveComment(reqVO.getApproveComment()); |
| | | if (Boolean.TRUE.equals(reqVO.getPass())) { |
| | | updateObj.setStatus(MesSafetyWorkTicketDO.STATUS_APPROVED); |
| | | updateObj.setRejectReason(""); |
| | | } else { |
| | | if (reqVO.getRejectReason() == null || reqVO.getRejectReason().trim().isEmpty()) { |
| | | throw exception(MES_SAFETY_TICKET_REJECT_REASON_REQUIRED); |
| | | } |
| | | updateObj.setStatus(MesSafetyWorkTicketDO.STATUS_REJECTED); |
| | | updateObj.setRejectReason(reqVO.getRejectReason()); |
| | | } |
| | | ticketMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public void closeTicket(Long userId, MesSafetyWorkTicketCloseReqVO reqVO) { |
| | | MesSafetyWorkTicketDO ticket = validateTicketExists(reqVO.getId()); |
| | | Integer status = ticket.getStatus(); |
| | | // å·²æ¹å â å®å·¥ï¼å·²å®å·¥ â 彿¡£ |
| | | boolean canFinish = MesSafetyWorkTicketDO.STATUS_APPROVED.equals(status); |
| | | boolean canArchive = MesSafetyWorkTicketDO.STATUS_FINISHED.equals(status); |
| | | if (!canFinish && !canArchive) { |
| | | throw exception(MES_SAFETY_TICKET_STATUS_INVALID); |
| | | } |
| | | MesSafetyWorkTicketDO updateObj = new MesSafetyWorkTicketDO(); |
| | | updateObj.setId(reqVO.getId()); |
| | | updateObj.setActualStartTime(reqVO.getActualStartTime()); |
| | | updateObj.setActualEndTime(reqVO.getActualEndTime()); |
| | | if (reqVO.getCloseRemark() != null) { |
| | | updateObj.setCloseRemark(reqVO.getCloseRemark()); |
| | | } |
| | | if (canFinish) { |
| | | // å®å·¥ç»è®°ï¼è¥åæ¶éæ©å½æ¡£åç´æ¥è¿å
¥å·²å½æ¡£ |
| | | boolean archiveNow = Boolean.TRUE.equals(reqVO.getArchive()); |
| | | updateObj.setStatus(archiveNow |
| | | ? MesSafetyWorkTicketDO.STATUS_ARCHIVED |
| | | : MesSafetyWorkTicketDO.STATUS_FINISHED); |
| | | if (archiveNow) { |
| | | updateObj.setCloseTime(LocalDateTime.now()); |
| | | updateObj.setCloseUserId(userId); |
| | | } |
| | | } else { |
| | | // å·²å®å·¥ â 彿¡£ |
| | | updateObj.setStatus(MesSafetyWorkTicketDO.STATUS_ARCHIVED); |
| | | updateObj.setCloseTime(LocalDateTime.now()); |
| | | updateObj.setCloseUserId(userId); |
| | | } |
| | | ticketMapper.updateById(updateObj); |
| | | } |
| | | |
| | | @Override |
| | | public MesSafetyWorkTicketDO validateTicketExists(Long id) { |
| | | if (id == null) { |
| | | throw exception(MES_SAFETY_TICKET_NOT_EXISTS); |
| | | } |
| | | MesSafetyWorkTicketDO ticket = ticketMapper.selectById(id); |
| | | if (ticket == null) { |
| | | throw exception(MES_SAFETY_TICKET_NOT_EXISTS); |
| | | } |
| | | return ticket; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªè®¡åæ¶é´åºé´åæ³ |
| | | */ |
| | | private void validateTimeRange(LocalDateTime start, LocalDateTime end) { |
| | | if (start != null && end != null && !end.isAfter(start)) { |
| | | throw exception(MES_SAFETY_TICKET_TIME_INVALID); |
| | | } |
| | | } |
| | | |
| | | private void validateCodeUnique(Long id, String code) { |
| | | MesSafetyWorkTicketDO exists = ticketMapper.selectByCode(code); |
| | | if (exists == null) { |
| | | return; |
| | | } |
| | | if (id == null || !Objects.equals(exists.getId(), id)) { |
| | | throw exception(MES_SAFETY_TICKET_CODE_DUPLICATE); |
| | | } |
| | | } |
| | | |
| | | } |