Explorar el Código

pms 瑞恒生产异常消息提醒

zhangcl hace 20 horas
padre
commit
b2bd13e9ce

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/constant/PmsConstants.java

@@ -43,4 +43,7 @@ public interface PmsConstants {
 
     // 物料领用单
     String MATERIAL_REQUISITION = "material-requisition";
+
+    // 生产异常消息提醒
+    String PRODUCTION_EXCEPTION = "production-exception";
 }

+ 7 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/message/PmsMessage.java

@@ -110,6 +110,11 @@ public class PmsMessage {
                 msg = "您有新的修井生产日报 " + name + "需要填报,请处理。"+"["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
             }
 
+            // 生产异常
+            if (PmsConstants.PRODUCTION_EXCEPTION.equals(businessType)) {
+                msg = "生产异常 \n" + name + "["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
+            }
+
             // 瑞鹰项目启动设备整改
             if (PmsConstants.RY_IMPROVE_DAILY_REPORT.equals(businessType)) {
                 msg = "您有新的项目启动设备整改日报 " + name + "需要填报,请处理。"+"["+ DateUtil.format(new Date(),"yyyy-MM-dd hh:mm:ss")+"]";
@@ -153,7 +158,8 @@ public class PmsMessage {
                 url=systemUrl + "dingding?id="+businessId+"&type="+businessType+"&userId="+userId;
             }
 
-            if (PmsConstants.FAILURE_NO_PASS.equals(businessType)||PmsConstants.ALARM_MESSAGE.equals(businessType)||PmsConstants.GENERATE_QHSE_CERT.equals(businessType)||PmsConstants.WEEK_ALARM_MESSAGE.equals(businessType)) {
+            if (PmsConstants.FAILURE_NO_PASS.equals(businessType) || PmsConstants.ALARM_MESSAGE.equals(businessType)
+                    || PmsConstants.GENERATE_QHSE_CERT.equals(businessType) || PmsConstants.WEEK_ALARM_MESSAGE.equals(businessType) || PmsConstants.PRODUCTION_EXCEPTION.equals(businessType)) {
                 //通知设备状态变更为观察使用
                 dingtalkSendApi.send(mobile, msg, "text",url,  title);
             } else {

+ 19 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotprojecttaskplan/IotProjectTaskPlanServiceImpl.java

@@ -61,14 +61,31 @@ public class IotProjectTaskPlanServiceImpl implements IotProjectTaskPlanService
     public Long createIotProjectTaskPlan(IotProjectTaskPlanSaveReqVO createReqVO) {
         // 插入
         IotProjectTaskPlanDO iotProjectTaskPlan = BeanUtils.toBean(createReqVO, IotProjectTaskPlanDO.class);
-        if (ObjUtil.isEmpty(createReqVO.getDeptId()) || ObjUtil.isEmpty(createReqVO.getStartTime())) {
+        Long deptId = createReqVO.getDeptId();
+        if (ObjUtil.isEmpty(deptId) || ObjUtil.isEmpty(createReqVO.getStartTime())) {
             throw exception(IOT_PROJECT_TASK_PLAN_NOT_EXISTS);
         }
         // 校验当前队伍部门 指定时间所属月份 是否已经存在 工作量计划记录
-        IotProjectTaskPlanDO existPlan = iotProjectTaskPlanMapper.selectOneByDeptIdAndMonth(createReqVO.getDeptId(), createReqVO.getStartTime(), createReqVO.getBusiness(), null);
+        IotProjectTaskPlanDO existPlan = iotProjectTaskPlanMapper.selectOneByDeptIdAndMonth(deptId, createReqVO.getStartTime(), createReqVO.getBusiness(), null);
         if (ObjUtil.isNotEmpty(existPlan)) {
             throw exception(IOT_PROJECT_TASK_PLAN_EXISTS);
         }
+        DeptDO companyDept = null;
+        int maxLoop = 15;
+        while (maxLoop-- > 0 && ObjUtil.isNotEmpty(deptId)) {
+            DeptDO dept = deptService.getDept(deptId);
+            if (ObjUtil.isEmpty(dept)) {
+                throw exception(IOT_PROJECT_TASK_PLAN_NOT_EXISTS);
+            }
+            if ("1".equals(dept.getType())) {
+                companyDept = dept;
+                break;
+            }
+            deptId = dept.getParentId();
+        }
+        if (ObjUtil.isNotEmpty(companyDept)) {
+            iotProjectTaskPlan.setCompanyId(companyDept.getId());
+        }
         iotProjectTaskPlanMapper.insert(iotProjectTaskPlan);
         // 返回
         return iotProjectTaskPlan.getId();

+ 121 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotrhdailyreport/IotRhDailyReportServiceImpl.java

@@ -26,6 +26,7 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.iotcarzhbd.IotCarZhbdDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdailyreportfuel.IotDailyReportFuelDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicerunlog.IotDeviceRunLogDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojectinfo.IotProjectInfoDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttask.IotProjectTaskDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
@@ -33,6 +34,7 @@ import cn.iocoder.yudao.module.pms.dal.mysql.iotcarzhbd.IotCarZhbdMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotdailyreportfuel.IotDailyReportFuelMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicerunlog.IotDeviceRunLogMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotprojectinfo.IotProjectInfoMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotprojecttask.IotProjectTaskMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotrhdailyreport.IotRhDailyReportMapper;
 import cn.iocoder.yudao.module.pms.enums.common.FailureAuditStatusEnum;
@@ -132,6 +134,9 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
     private DictDataService dictDataService;
     @Resource
     private DeptMapper deptMapper;
+    @Resource
+    private IotProjectInfoMapper iotProjectInfoMapper;
+
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -837,11 +842,11 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
         IotRhDailyReportDO dailyReport = validateIotRhDailyReportExists(updateReqVO.getId());
         dailyReport.setAuditStatus(updateReqVO.getAuditStatus());
         dailyReport.setOpinion(updateReqVO.getOpinion());
+        Long deptId = dailyReport.getDeptId();
+        Long taskId = dailyReport.getTaskId();
         if (SupplierAuditStatusEnum.REJECT.getStatus().equals(updateReqVO.getAuditStatus())) {
             dailyReport.setStatus(0);
             // 审批拒绝后需要向 日报填报人 发送消息提醒 每个队伍暂时只有1人 随机取1人
-            Long deptId = dailyReport.getDeptId();
-            Long taskId = dailyReport.getTaskId();
             DeptDO dept = deptService.getDept(deptId);
             // 消息标题
             String msgTitle = dept.getName();
@@ -864,6 +869,120 @@ public class IotRhDailyReportServiceImpl implements IotRhDailyReportService {
                 }
             }
         }
+        // 审核同意 将生产异常情况 (npt 工程质量) 发送到拥有 生产异常通知 角色的人员
+        BigDecimal accidentTime = dailyReport.getAccidentTime();
+        if (ObjUtil.isNotEmpty(accidentTime) && accidentTime.compareTo(BigDecimal.ZERO) > 0) {
+
+            String companyName = "瑞恒兴域";
+            BigDecimal day = accidentTime.divide(new BigDecimal("24"), 2, RoundingMode.HALF_UP);
+            String accidentDay = day + "T";
+            // 异常情况
+            String malfunction = StrUtil.blankToDefault(dailyReport.getMalfunction(), "无");
+            Long projectId = dailyReport.getProjectId();
+            DeptDO dept = deptService.getDept(deptId);
+            // 查询当前队伍的上级项目部
+            DeptDO projectDept = deptService.getDept(dept.getParentId());
+            // 队伍名称
+            String deptName = ObjUtil.isNotEmpty(dept) ? dept.getName() : StrUtil.EMPTY;
+            // 项目部名称
+            String projectDeptName = ObjUtil.isNotEmpty(projectDept) ? projectDept.getName() : StrUtil.EMPTY;
+            String contract = "无";
+            if (ObjUtil.isNotEmpty(projectId)) {
+                IotProjectInfoDO project = iotProjectInfoMapper.selectById(projectId);
+                if (ObjUtil.isNotEmpty(project)) {
+                    contract = project.getContractName();
+                }
+            }
+            String wellName = "无";
+            if (ObjUtil.isNotEmpty(taskId)) {
+                IotProjectTaskDO task = iotProjectTaskMapper.selectById(taskId);
+                if (ObjUtil.isNotEmpty(task)) {
+                    wellName = task.getWellName();
+                }
+            }
+            // 当前处理进度 当日施工简报
+            String brief = StrUtil.blankToDefault(dailyReport.getProductionStatus(), "无");
+            // 下步计划
+            String nextPlan = StrUtil.blankToDefault(dailyReport.getNextPlan(), "无");
+            // 故障误工时间 accidentTime H
+
+            String msgTemplate = "[公司]:{} - [队伍]:{} - [项目]:{} - [井号]:{}  -[故障描述]:{} -[当前处理进度]:{}-[下步处理计划]:{}-[累计误工时间]:{}";
+
+            String PRODUCTION_EXCEPTION_MSG_TEMPLATE =
+                    "[公司]:{}\n" +
+                    "[项目部]:{}\n" +
+                    "[队伍]:{}\n" +
+                    "[井号]:{}\n" +
+                    "[故障描述]:{}\n" +
+                    "[当前处理进度]:{}\n" +
+                    "[下步处理计划]:{}\n" +
+                    "[累计误工时间]:{}\n";
+
+            String finalMsgTitle = StrUtil.format(PRODUCTION_EXCEPTION_MSG_TEMPLATE,
+                    companyName, projectDeptName, deptName, wellName,
+                    malfunction, brief, nextPlan, accidentDay
+            );
+
+            // 封装以上消息内容 发送到公司 角色 (生产异常通知)
+            // 查询瑞恒 157l 下具有以上角色的人员 查询集团(科瑞石油技术) 拥有以上角色的人员
+            Set<Long> userIds = new HashSet<>();
+            Set<Long> deptIds = new HashSet<>();
+            deptIds.add(157l);
+            List<AdminUserDO> companyUsers = adminUserService.getUserListByDeptIds(deptIds);
+            if (CollUtil.isNotEmpty(companyUsers)) {
+                companyUsers.forEach(user -> {
+                    userIds.add(user.getId());
+                });
+            }
+            deptIds.clear();
+            deptIds.add(156l);
+            List<AdminUserDO> groupUsers = adminUserService.getUserListByDeptIds(deptIds);
+            if (CollUtil.isNotEmpty(groupUsers)) {
+                groupUsers.forEach(user -> {
+                    userIds.add(user.getId());
+                });
+            }
+            RoleDO role = roleService.getRoleByCode("生产异常通知");
+            if (ObjUtil.isNotEmpty(role)) {
+                Set<Long> roleIds = new HashSet<>();
+                roleIds.add(role.getId());
+                List<UserRoleDO> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
+                if (CollUtil.isNotEmpty(userRoles)) {
+                    // 提取有审批角色的所有用户ID(去重+空值过滤)
+                    Set<Long> roleUserIds = userRoles.stream()
+                            .map(UserRoleDO::getUserId)
+                            .filter(Objects::nonNull) // 过滤空userId
+                            .collect(Collectors.toSet());
+                    // 计算两个集合的交集,得到最终目标用户ID
+                    Set<Long> targetUserIds = userIds.stream()
+                            .filter(roleUserIds::contains)
+                            .collect(Collectors.toSet());
+                    // 异步发送 站内信 钉钉消息
+                    if (CollUtil.isNotEmpty(targetUserIds)) {
+                        Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(targetUserIds);
+                        // 给多个用户发送 相同 的 提醒消息
+                        if (CollUtil.isNotEmpty(users)) {
+                            // 生成消息提醒 标题内容
+                            CountDownLatch latch = new CountDownLatch(users.size());
+                            users.forEach((userId, user) -> {
+                                pmsThreadPoolTaskExecutor.execute(() -> {
+                                    try {
+                                        String mobile = user.getMobile();
+                                        // 没有手机号也发送站内信消息
+                                        if (StrUtil.isNotBlank(finalMsgTitle)) {
+                                            pmsMessage.sendMessage(dailyReport.getId(), finalMsgTitle, PmsConstants.PRODUCTION_EXCEPTION,
+                                                    userId, mobile);
+                                        }
+                                    } finally {
+                                        latch.countDown();
+                                    }
+                                });
+                            });
+                        }
+                    }
+                }
+            }
+        }
         // 更新瑞恒日报审核状态
         iotRhDailyReportMapper.updateById(dailyReport);
     }