Explorar o código

feat(risk-accident): 事故上报新增处理功能(5字段+归档逻辑)

yangjingjing hai 2 días
pai
achega
2b11b3e698

+ 26 - 0
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/controller/RiskAccidentController.java

@@ -7,6 +7,7 @@ import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.excel.utils.ExcelUtil;
@@ -15,6 +16,7 @@ import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.risk.domain.bo.RiskAccidentBo;
 import org.dromara.risk.domain.vo.AccidentStatsVo;
@@ -86,6 +88,30 @@ public class RiskAccidentController extends BaseController {
         return toAjax(accidentService.updateByBo(bo));
     }
 
+    /**
+     * 处理事故
+     * 提交处理即视为完成:状态强制变更为'归档',不依赖前端传入
+     */
+    @SaCheckPermission("risk:accident:handle")
+    @Log(title = "事故上报", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/handle/{id}")
+    public R<Void> handle(@PathVariable("id") Long id, @RequestBody RiskAccidentBo bo) {
+        // 处理人前端未传时,自动取当前登录用户
+        String handler = StringUtils.isBlank(bo.getHandlerName())
+            ? LoginHelper.getUsername()
+            : bo.getHandlerName();
+        return toAjax(accidentService.handleAccident(
+            id,
+            handler,
+            bo.getHandleResult(),
+            bo.getHandleMeasures(),
+            bo.getHandleDeadline(),
+            bo.getHandleAttachmentUrl(),
+            bo.getHandleAttachmentName()
+        ));
+    }
+
     /**
      * 删除事故
      *

+ 26 - 1
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/domain/RiskAccident.java

@@ -126,10 +126,35 @@ public class RiskAccident extends TenantEntity {
     private String handlerName;
 
     /**
-     * 处理措施
+     * 处理措施(处理意见)
      */
     private String handleMeasures;
 
+    /**
+     * 处理方式(字典:risk_accident_handle_way)
+     */
+    private String handleResult;
+
+    /**
+     * 处理期限
+     */
+    private Date handleDeadline;
+
+    /**
+     * 处理附件URL(MinIO对象存储路径)
+     */
+    private String handleAttachmentUrl;
+
+    /**
+     * 处理附件原始文件名
+     */
+    private String handleAttachmentName;
+
+    /**
+     * 处理时间
+     */
+    private Date handleTime;
+
     /**
      * 调查结果
      */

+ 30 - 2
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/domain/bo/RiskAccidentBo.java

@@ -139,11 +139,39 @@ public class RiskAccidentBo extends BaseEntity {
     private String handlerName;
 
     /**
-     * 处理措施
+     * 处理措施(处理意见)
      */
-    @Size(min = 0, max = 500, message = "处理措施长度不能超过{max}个字符")
+    @Size(min = 0, max = 2000, message = "处理措施长度不能超过{max}个字符")
     private String handleMeasures;
 
+    /**
+     * 处理方式(字典:risk_accident_handle_way)
+     */
+    @Size(min = 0, max = 50, message = "处理方式长度不能超过{max}个字符")
+    private String handleResult;
+
+    /**
+     * 处理期限
+     */
+    private Date handleDeadline;
+
+    /**
+     * 处理附件URL(MinIO对象存储路径)
+     */
+    @Size(min = 0, max = 500, message = "处理附件URL长度不能超过{max}个字符")
+    private String handleAttachmentUrl;
+
+    /**
+     * 处理附件原始文件名
+     */
+    @Size(min = 0, max = 200, message = "处理附件名长度不能超过{max}个字符")
+    private String handleAttachmentName;
+
+    /**
+     * 处理时间
+     */
+    private Date handleTime;
+
     /**
      * 调查结果
      */

+ 33 - 1
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/domain/vo/RiskAccidentVo.java

@@ -149,11 +149,43 @@ public class RiskAccidentVo implements Serializable {
     private String handlerName;
 
     /**
-     * 处理措施
+     * 处理措施(处理意见)
      */
     @ExcelProperty(value = "处理措施")
     private String handleMeasures;
 
+    /**
+     * 处理方式(字典:risk_accident_handle_way)
+     */
+    @ExcelProperty(value = "处理方式")
+    private String handleResult;
+
+    /**
+     * 处理期限
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ExcelProperty(value = "处理期限")
+    private Date handleDeadline;
+
+    /**
+     * 处理附件URL(MinIO对象存储路径)
+     */
+    @ExcelProperty(value = "处理附件URL")
+    private String handleAttachmentUrl;
+
+    /**
+     * 处理附件原始文件名
+     */
+    @ExcelProperty(value = "处理附件名")
+    private String handleAttachmentName;
+
+    /**
+     * 处理时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ExcelProperty(value = "处理时间")
+    private Date handleTime;
+
     /**
      * 调查结果
      */

+ 15 - 0
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/service/IRiskAccidentService.java

@@ -75,4 +75,19 @@ public interface IRiskAccidentService {
      */
     List<AccidentTrendVo> query12MonthTrend();
 
+    /**
+     * 处理事故
+     *
+     * @param id               事故主键
+     * @param handler          处理人(前端未传时由后端取当前登录用户)
+     * @param handleResult     处理方式(字典:risk_accident_handle_way)
+     * @param handleMeasures   处理意见
+     * @param handleDeadline   处理期限
+     * @param attachmentUrl    处理附件URL(MinIO对象存储路径)
+     * @param attachmentName   处理附件原始文件名
+     * @return 结果(状态会被强制更新为"归档",不依赖前端传入)
+     */
+    int handleAccident(Long id, String handler, String handleResult, String handleMeasures,
+                       java.util.Date handleDeadline, String attachmentUrl, String attachmentName);
+
 }

+ 43 - 7
ruoyi-modules/ruoyi-risk/src/main/java/org/dromara/risk/service/impl/RiskAccidentServiceImpl.java

@@ -107,6 +107,10 @@ public class RiskAccidentServiceImpl implements IRiskAccidentService {
         if (bo.getReportTime() == null) {
             bo.setReportTime(new java.util.Date());
         }
+        // 处理状态前端未传时,默认置为'待处理'(新流程只有 待处理/归档 两个状态)
+        if (StringUtils.isBlank(bo.getHandleStatus())) {
+            bo.setHandleStatus("待处理");
+        }
         RiskAccident add = MapstructUtils.convert(bo, RiskAccident.class);
         int row = baseMapper.insert(add);
         bo.setId(add.getId());
@@ -167,23 +171,23 @@ public class RiskAccidentServiceImpl implements IRiskAccidentService {
             .ge(RiskAccident::getAccidentTime, lastMonthStart)
             .lt(RiskAccident::getAccidentTime, lastMonthEnd));
 
-        // 调查中
+        // 待处理(新流程:替代原"调查中")
         Long investigating = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
-            .eq(RiskAccident::getHandleStatus, "调查中"));
+            .eq(RiskAccident::getHandleStatus, "待处理"));
         Long lastMonthInvestigating = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
-            .eq(RiskAccident::getHandleStatus, "调查中")
+            .eq(RiskAccident::getHandleStatus, "待处理")
             .ge(RiskAccident::getAccidentTime, lastMonthStart)
             .lt(RiskAccident::getAccidentTime, lastMonthEnd));
 
-        // 已结束
+        // 归档(新流程:替代原"已结束")
         Long finished = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
-            .eq(RiskAccident::getHandleStatus, "已结束"));
+            .eq(RiskAccident::getHandleStatus, "归档"));
         Long lastMonthFinished = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
-            .eq(RiskAccident::getHandleStatus, "已结束")
+            .eq(RiskAccident::getHandleStatus, "归档")
             .ge(RiskAccident::getAccidentTime, lastMonthStart)
             .lt(RiskAccident::getAccidentTime, lastMonthEnd));
 
-        // 待考核
+        // 待考核(预留,新流程下无此状态,统计值为 0)
         Long pendingAssess = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
             .eq(RiskAccident::getHandleStatus, "待考核"));
         Long lastMonthPendingAssess = baseMapper.selectCount(Wrappers.<RiskAccident>lambdaQuery()
@@ -209,6 +213,38 @@ public class RiskAccidentServiceImpl implements IRiskAccidentService {
         return vo;
     }
 
+    /**
+     * 处理事故(状态强制变为"归档")
+     *
+     * @param id               事故主键
+     * @param handler          处理人
+     * @param handleResult     处理方式
+     * @param handleMeasures   处理意见
+     * @param handleDeadline   处理期限
+     * @param attachmentUrl    处理附件URL
+     * @param attachmentName   处理附件名
+     */
+    @Override
+    public int handleAccident(Long id, String handler, String handleResult, String handleMeasures,
+                              java.util.Date handleDeadline, String attachmentUrl, String attachmentName) {
+        RiskAccident update = new RiskAccident();
+        update.setId(id);
+        // 提交处理即视为完成:状态强制置为'归档'(不依赖前端传入)
+        update.setHandleStatus("归档");
+        update.setHandlerName(handler);
+        update.setHandleResult(handleResult);
+        update.setHandleMeasures(handleMeasures);
+        if (handleDeadline != null) {
+            update.setHandleDeadline(handleDeadline);
+        }
+        if (StringUtils.isNotBlank(attachmentUrl)) {
+            update.setHandleAttachmentUrl(attachmentUrl);
+            update.setHandleAttachmentName(attachmentName);
+        }
+        update.setHandleTime(new java.util.Date());
+        return baseMapper.updateById(update);
+    }
+
     /**
      * 计算环比变化率(单位 %)。上月为 0 时:本月为正返回 100,否则返回 0。
      */

+ 138 - 0
sql/risk_accident_handle.sql

@@ -0,0 +1,138 @@
+-- =============================================================
+-- 风控平台 数据库增量脚本  事故上报 - 处理功能增强
+-- 适用版本: 任何已部署 risk_accident 的环境
+-- 兼容: 全部 SQL 幂等,可重复执行(基于 INFORMATION_SCHEMA 判断)
+-- 新环境用 risk_control_platform.sql 部署;已有环境用本脚本增量升级
+-- =============================================================
+
+SET NAMES utf8mb4;
+
+-- =============================================================
+-- 1. 事故表 risk_accident 加处理相关字段
+-- =============================================================
+
+-- 1.1 handle_result(处理方式,字典 risk_accident_handle_way)
+SET @sql = (SELECT IF(
+  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+     WHERE TABLE_SCHEMA = DATABASE()
+       AND TABLE_NAME   = 'risk_accident'
+       AND COLUMN_NAME  = 'handle_result') = 0,
+  'ALTER TABLE `risk_accident` ADD COLUMN `handle_result` VARCHAR(50) DEFAULT NULL COMMENT ''处理方式(字典:risk_accident_handle_way)'' AFTER `handle_measures`',
+  'SELECT 1'));
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+-- 1.2 handle_deadline(处理期限)
+SET @sql = (SELECT IF(
+  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+     WHERE TABLE_SCHEMA = DATABASE()
+       AND TABLE_NAME   = 'risk_accident'
+       AND COLUMN_NAME  = 'handle_deadline') = 0,
+  'ALTER TABLE `risk_accident` ADD COLUMN `handle_deadline` DATE DEFAULT NULL COMMENT ''处理期限'' AFTER `handle_result`',
+  'SELECT 1'));
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+-- 1.3 handle_attachment_url(处理附件URL,MinIO对象存储路径)
+SET @sql = (SELECT IF(
+  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+     WHERE TABLE_SCHEMA = DATABASE()
+       AND TABLE_NAME   = 'risk_accident'
+       AND COLUMN_NAME  = 'handle_attachment_url') = 0,
+  'ALTER TABLE `risk_accident` ADD COLUMN `handle_attachment_url` VARCHAR(500) DEFAULT NULL COMMENT ''处理附件URL(MinIO对象存储路径)'' AFTER `handle_deadline`',
+  'SELECT 1'));
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+-- 1.4 handle_attachment_name(处理附件原始文件名)
+SET @sql = (SELECT IF(
+  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+     WHERE TABLE_SCHEMA = DATABASE()
+       AND TABLE_NAME   = 'risk_accident'
+       AND COLUMN_NAME  = 'handle_attachment_name') = 0,
+  'ALTER TABLE `risk_accident` ADD COLUMN `handle_attachment_name` VARCHAR(200) DEFAULT NULL COMMENT ''处理附件原始文件名'' AFTER `handle_attachment_url`',
+  'SELECT 1'));
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+-- 1.5 handle_time(处理时间)
+SET @sql = (SELECT IF(
+  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
+     WHERE TABLE_SCHEMA = DATABASE()
+       AND TABLE_NAME   = 'risk_accident'
+       AND COLUMN_NAME  = 'handle_time') = 0,
+  'ALTER TABLE `risk_accident` ADD COLUMN `handle_time` DATETIME DEFAULT NULL COMMENT ''处理时间'' AFTER `handle_attachment_name`',
+  'SELECT 1'));
+PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
+
+
+-- =============================================================
+-- 2. 字典 risk_accident_status(事故状态)清理与新增
+--    已有值: 待处理(21300)/调查中(21301)/已结束(21302)/待考核(21303)
+--    新流程只用: 待处理(保留) + 归档(新增)
+--    历史数据迁移: 调查中/已结束/待考核 -> 待处理(确保状态合法)
+-- =============================================================
+
+-- 2.1 删除旧流程状态(调查中/已结束/待考核),只保留 待处理 + 归档
+DELETE FROM `sys_dict_data`
+ WHERE `dict_type` = 'risk_accident_status'
+   AND `dict_label` IN ('调查中', '已结束', '待考核');
+
+-- 2.2 确保"待处理"存在(若已被上面 delete 误删则恢复)
+INSERT INTO `sys_dict_data`
+    (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
+SELECT 1, '待处理', '待处理', 'risk_accident_status', '', 'danger', 'Y', '0', 103, 1, NOW(), '事故已上报,等待处理'
+  FROM DUAL
+ WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'risk_accident_status' AND `dict_value` = '待处理');
+
+-- 2.3 新增"归档"
+INSERT INTO `sys_dict_data`
+    (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
+SELECT 2, '归档', '归档', 'risk_accident_status', '', 'success', 'N', '0', 103, 1, NOW(), '事故已处理完成,可归档'
+  FROM DUAL
+ WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'risk_accident_status' AND `dict_value` = '归档');
+
+
+-- =============================================================
+-- 3. 字典 seed: 事故处理方式 risk_accident_handle_way
+-- =============================================================
+
+-- 3.1 字典类型(若不存在则补)
+INSERT INTO `sys_dict_type`
+    (`dict_name`, `dict_type`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
+VALUES
+    ('事故处理方式', 'risk_accident_handle_way', '0', 103, 1, NOW(), '事故处理方式字典(现场处置/整改完成/教育培训/其他)')
+ON DUPLICATE KEY UPDATE `update_time` = NOW();
+
+-- 3.2 字典数据 seed(默认 4 项: 现场处置/整改完成/教育培训/其他)
+-- 先清空再 seed(用户可在字典管理界面自行扩展)
+DELETE FROM `sys_dict_data`
+ WHERE `dict_type` = 'risk_accident_handle_way';
+
+INSERT INTO `sys_dict_data`
+    (`dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
+VALUES
+    (1, '现场处置', '现场处置', 'risk_accident_handle_way', '', 'primary', 'N', '0', 103, 1, NOW(), '现场紧急处置完成'),
+    (2, '整改完成', '整改完成', 'risk_accident_handle_way', '', 'success', 'N', '0', 103, 1, NOW(), '根本原因已整改'),
+    (3, '教育培训', '教育培训', 'risk_accident_handle_way', '', 'warning', 'N', '0', 103, 1, NOW(), '组织相关人员培训'),
+    (4, '其他',     '其他',     'risk_accident_handle_way', '', 'info',    'N', '0', 103, 1, NOW(), '其他处理方式');
+
+
+-- =============================================================
+-- 4. (可选)历史事故状态清洗
+--    把历史'调查中'/'已结束'/'待考核'状态归并为'待处理'
+--    适配新流程(只有 待处理 / 归档 两个状态)
+-- =============================================================
+
+UPDATE `risk_accident`
+   SET `handle_status` = '待处理'
+ WHERE `handle_status` IN ('调查中', '已结束', '待考核');
+
+
+-- =============================================================
+-- 5. 验证清单(可手动 SELECT 确认)
+-- =============================================================
+-- SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
+--   WHERE TABLE_SCHEMA = DATABASE()
+--     AND TABLE_NAME = 'risk_accident'
+--     AND COLUMN_NAME IN ('handle_result','handle_deadline','handle_attachment_url','handle_attachment_name','handle_time');
+--
+-- SELECT dict_type, dict_label, dict_value FROM sys_dict_data
+--  WHERE dict_type IN ('risk_accident_status','risk_accident_handle_way')
+--  ORDER BY dict_type, dict_sort;

+ 8 - 3
sql/risk_control_platform.sql

@@ -922,10 +922,15 @@ CREATE TABLE `risk_accident` (
   `reporter_id` bigint DEFAULT NULL COMMENT '上报人ID',
   `reporter_name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上报人',
   `report_time` datetime NOT NULL COMMENT '上报时间',
-  `handle_status` varchar(20) COLLATE utf8mb4_general_ci DEFAULT '调查中' COMMENT '处理状态',
+  `handle_status` varchar(20) COLLATE utf8mb4_general_ci DEFAULT '待处理' COMMENT '处理状态(待处理/归档)',
   `handler_id` bigint DEFAULT NULL COMMENT '处理人ID',
   `handler_name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理人',
-  `handle_measures` text COLLATE utf8mb4_general_ci COMMENT '处理措施',
+  `handle_measures` text COLLATE utf8mb4_general_ci COMMENT '处理措施(处理意见)',
+  `handle_result` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理方式(字典:risk_accident_handle_way)',
+  `handle_deadline` date DEFAULT NULL COMMENT '处理期限',
+  `handle_attachment_url` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理附件URL(MinIO对象存储路径)',
+  `handle_attachment_name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '处理附件原始文件名',
+  `handle_time` datetime DEFAULT NULL COMMENT '处理时间',
   `investigation_result` text COLLATE utf8mb4_general_ci COMMENT '调查结果',
   `improvement_measures` text COLLATE utf8mb4_general_ci COMMENT '改进措施',
   `remark` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
@@ -952,7 +957,7 @@ CREATE TABLE `risk_accident` (
 
 LOCK TABLES `risk_accident` WRITE;
 /*!40000 ALTER TABLE `risk_accident` DISABLE KEYS */;
-INSERT INTO `risk_accident` VALUES (2071227132013293570,'000000','AC20260628214004315','test','人身伤害','特别重大',NULL,NULL,'test','2026-06-28 21:39:30','test','test',0,1,0.00,NULL,'test','2026-06-28 21:40:04','待处理',NULL,NULL,NULL,NULL,NULL,NULL,'test','[\"http://106.55.100.207:9000/rjzytest/risk/2026/06/28/43656b6bc5df447ba08976859bec7116.jpg\"]',103,1,'2026-06-28 21:40:04',1,'2026-06-28 21:40:04','0');
+INSERT INTO `risk_accident` VALUES (2071227132013293570,'000000','AC20260628214004315','test','人身伤害','特别重大',NULL,NULL,'test','2026-06-28 21:39:30','test','test',0,1,0.00,NULL,'test','2026-06-28 21:40:04','待处理',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'test','[\"http://106.55.100.207:9000/rjzytest/risk/2026/06/28/43656b6bc5df447ba08976859bec7116.jpg\"]',103,1,'2026-06-28 21:40:04',1,'2026-06-28 21:40:04','0');
 /*!40000 ALTER TABLE `risk_accident` ENABLE KEYS */;
 UNLOCK TABLES;