diff --git a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/dto/WorkOrderInfoDto.java b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/dto/WorkOrderInfoDto.java index 30fdfac..4a58616 100644 --- a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/dto/WorkOrderInfoDto.java +++ b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/dto/WorkOrderInfoDto.java @@ -1,5 +1,6 @@ package org.dromara.platform.domain.dto; +import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; @@ -30,6 +31,16 @@ public class WorkOrderInfoDto implements Serializable { @ExcelProperty(value = "工单ID") private String id; + /** + * 接单超时情况 + */ + @ExcelIgnore + private String orderAcceptTimeOutSituation; + /** + * 处理超时情况 + */ + @ExcelIgnore + private String handleTimeOutSituation; /** * 当前状态 diff --git a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/vo/WorkOrderInfoVo.java b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/vo/WorkOrderInfoVo.java index 055d395..bb1a9d6 100644 --- a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/vo/WorkOrderInfoVo.java +++ b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/domain/vo/WorkOrderInfoVo.java @@ -288,4 +288,15 @@ public class WorkOrderInfoVo implements Serializable { @ExcelProperty(value = "其他扣款原因") private String otherCostReason; + + /** + * 接单超时情况 + */ + @ExcelIgnore + private String orderAcceptTimeOutSituation; + /** + * 处理超时情况 + */ + @ExcelIgnore + private String handleTimeOutSituation; } diff --git a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/service/impl/WorkOrderInfoServiceImpl.java b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/service/impl/WorkOrderInfoServiceImpl.java index 0b8c6bc..91bdf24 100644 --- a/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/service/impl/WorkOrderInfoServiceImpl.java +++ b/ruoyi-modules/guoyan-platform/src/main/java/org/dromara/platform/service/impl/WorkOrderInfoServiceImpl.java @@ -164,7 +164,7 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { if (hasUnitRole){ bo.setMaintenanceUnit(deptName); } - if (hasOwnerRole){ +/* if (hasOwnerRole){ // 通过合同甲方获取对应的合同乙方(运维单位) if (deptName.equals("江北公安")){ List partyBList = Arrays.asList("电信", "移动","盈力"); @@ -173,7 +173,7 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { List partyBList = Arrays.asList("时代"); bo.setMaintenanceUnits(partyBList); } - } + }*/ LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); @@ -587,8 +587,95 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { } /** - * 计算距离响应截止时间的剩余/超时时间 + * 获取剩余处理时间(用于计算罚款金额) + * @param initTime 起始时间 + * @param responseHour 响应时间(小时) + * @param workOrderId 工单id + * @param stages 流程阶段 + * @param orderByFlag 排序方式 asc为升序,desc为降序 + * @return + */ + public String getTimeLeft(Date initTime, Long responseHour, + String workOrderId, List stages, String orderByFlag) { + if (initTime == null || responseHour == null || responseHour <= 0) { + return "无响应时间限制"; + } + // 接单时间转为 LocalDateTime + LocalDateTime initDateTime = initTime.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + + // 截止时间 = 接单时间 + 响应时间(小时) + LocalDateTime dueDateTime = initDateTime.plusHours(responseHour); + + WorkOrderProcess targetProcess = getTargetWorkOrderProcess(workOrderId, stages, orderByFlag); + + if (targetProcess != null) { + Date operationTime = targetProcess.getOperationTime(); + LocalDateTime targetDateTime = operationTime.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + // 目标时间和截止时间相比 + return getLeftTimeResult(dueDateTime, targetDateTime); + } else { + // 当前时间 + LocalDateTime now = LocalDateTime.now(); + // 模板时间为空则当且时间now 和 截止时间相比 + return getLeftTimeResult(dueDateTime, now); + } + + } + + private String getLeftTimeResult(LocalDateTime dueDateTime, LocalDateTime targetDateTime) { + Duration duration; + boolean isOverdue; + if (targetDateTime.isAfter(dueDateTime)) { + duration = Duration.between(dueDateTime, targetDateTime); + isOverdue = true; + } else { + duration = Duration.between(targetDateTime, dueDateTime); + isOverdue = false; + } + + long days = duration.toDays(); + long hours = duration.toHours() % 24; + long minutes = duration.toMinutes() % 60; + + if (isOverdue) { + return String.format("超时%d天%d小时%d分", days, hours, minutes); + } else { + return String.format("剩余%d天%d小时%d分", days, hours, minutes); + } + } + + /** + * 获取指定工单的指定阶段提交记录 * + * @param workOrderId 工单ID + * @param stages 阶段列表 + * @param orderByFlag 排序方式,asc为升序,desc为降序 + * @return 指定工单的指定阶段提交记录 + */ + private WorkOrderProcess getTargetWorkOrderProcess(String workOrderId, List stages, String orderByFlag) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WorkOrderProcess::getWorkOrderId, workOrderId); + queryWrapper.in(WorkOrderProcess::getStage, stages); + // 获取最早的一次提交记录时间 + if (orderByFlag.equals("asc")) { + queryWrapper.orderByAsc(WorkOrderProcess::getCreateTime); + } else if (orderByFlag.equals("desc")) { + // 获取最新的一次提交记录时间 + queryWrapper.orderByDesc(WorkOrderProcess::getCreateTime); + } + queryWrapper.last("LIMIT 1"); + WorkOrderProcess targetProcess = workOrderProcessMapper.selectOne(queryWrapper); + return targetProcess; + } + + + /** + * 计算距离响应截止时间的剩余/超时时间 + * 当前时间和截止时间相比较 * @param acceptTime 接单时间(Date) * @param responseHour 响应时间要求(单位:小时) * @return 格式化的时间字符串,如:"剩余2天3小时4分" 或 "超时5小时6分" @@ -611,7 +698,7 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { Duration duration; boolean isOverdue; - + // 当且时间和截止时间相比 if (now.isAfter(dueDateTime)) { duration = Duration.between(dueDateTime, now); isOverdue = true; @@ -631,7 +718,6 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { } } - public String getTimeLeft(LocalDateTime dueDateTime ) { // 当前时间 LocalDateTime now = LocalDateTime.now(); @@ -1451,85 +1537,32 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { List orderInfoVoList = baseMapper.selectVoList(lqw); for (WorkOrderInfoVo record : orderInfoVoList) { - String handleTimeOutSituation = ""; - String orderAcceptTimeOutSituation = ""; + // 1.罚款信息 String workOrderId = record.getId(); - String projectName = record.getProjectName(); - // 根据项目名称获取接单超期信息 - LambdaQueryWrapper projectQueryWrapper = new LambdaQueryWrapper<>(); - projectQueryWrapper.eq(ProjectInfo::getProjectName, projectName); - projectQueryWrapper.last("LIMIT 1"); - ProjectInfo projectInfo = projectInfoMapper.selectOne(projectQueryWrapper); - String orderTakingOverTime = projectInfo.getOrderTakingOverTime(); - String orderTakingCost = projectInfo.getOrderTakingCost(); - String handleTimeOutCost = projectInfo.getHandleCost(); - - // 1.接单超时 --> 参考时间:事件转派 故障派遣 - LambdaQueryWrapper takeOrderQueryWrapper = new LambdaQueryWrapper<>(); - takeOrderQueryWrapper.eq(WorkOrderProcess::getWorkOrderId, workOrderId); - takeOrderQueryWrapper.in(WorkOrderProcess::getStage, "故障派遣", "事件转派"); - takeOrderQueryWrapper.orderByDesc(WorkOrderProcess::getCreateTime); - takeOrderQueryWrapper.last("LIMIT 1"); - WorkOrderProcess takeOrderProcess = workOrderProcessMapper.selectOne(takeOrderQueryWrapper); - if (takeOrderProcess != null && takeOrderProcess.getOperationTime() != null) { - orderAcceptTimeOutSituation = getTimeLeft(takeOrderProcess.getOperationTime(),Long.valueOf(orderTakingOverTime)); - } - - // 2.响应超时(处理超时) --> 参考时间: 故障接单 - LambdaQueryWrapper dealQueryWrapper = new LambdaQueryWrapper<>(); - dealQueryWrapper.eq(WorkOrderProcess::getWorkOrderId, workOrderId); - dealQueryWrapper.eq(WorkOrderProcess::getStage, "故障接单"); - if (record.getStatus()==9){ - // 如果是派遣的时间还是按照第一个人的接单时间来计算,否则都是按照最后一次接单时间来计算 - dealQueryWrapper.orderByAsc(WorkOrderProcess::getCreateTime); - }else { - dealQueryWrapper.orderByDesc(WorkOrderProcess::getCreateTime); - } - dealQueryWrapper.last("LIMIT 1"); - - WorkOrderProcess dealProcess = workOrderProcessMapper.selectOne(dealQueryWrapper); - if (dealProcess != null && dealProcess.getOperationTime() != null) { - handleTimeOutSituation = getTimeLeft(dealProcess.getOperationTime(),record.getResponseTime() ); - } - - - if (handleTimeOutSituation.startsWith("超时")) { - int timeoutHours = calculateTotalTimeoutHours(handleTimeOutSituation); - record.setHandleTimeOutCount(timeoutHours); - record.setHandleCost(timeoutHours * Double.parseDouble(handleTimeOutCost)); - record.setIsHandleOverTime("是"); - }else { - record.setHandleCost(0.0); - record.setIsHandleOverTime("否"); - } - - if (orderAcceptTimeOutSituation.startsWith("超时")) { - int timeoutHours = calculateTotalTimeoutHours(orderAcceptTimeOutSituation); - record.setOrderAcceptTimeOutCount(timeoutHours); - record.setOrderTakingCost(timeoutHours * Double.parseDouble(orderTakingCost)); - record.setIsOrderTakingOverTime("是"); - }else { - record.setOrderTakingCost(0.0); - record.setIsOrderTakingOverTime("否"); - } - - // 判空 - Double handleCost = record.getHandleCost() == null ? 0.0 : record.getHandleCost(); - Double orderAcceptCost = record.getOrderTakingCost() == null ? 0.0 : record.getOrderTakingCost(); - record.setTotalCost(handleCost + orderAcceptCost); - + WorkOrderInfoDto overTimeCostInfo = this.getOverTimeCost(workOrderId); + // 响应超时罚款 + record.setHandleTimeOutCount(overTimeCostInfo.getHandleTimeOutCount()); + record.setHandleCost(overTimeCostInfo.getHandleCost()); + record.setIsHandleOverTime(overTimeCostInfo.getIsHandleOverTime()); + + // 接单超时罚款 + record.setOrderAcceptTimeOutCount(overTimeCostInfo.getOrderAcceptTimeOutCount()); + record.setOrderTakingCost(overTimeCostInfo.getOrderTakingCost()); + record.setTotalCost(overTimeCostInfo.getTotalCost()); + record.setIsOrderTakingOverTime(overTimeCostInfo.getIsOrderTakingOverTime()); + // 2.处理人信息(最后一次处理的人) String handler = workOrderProcessMapper.getHandlerByWorkOrderId(workOrderId); if (handler != null){ record.setHandler(handler); }else { record.setHandler("无"); } - // 接单时间 + // 3.接单时间(最后一次) Date orderAcceptTime = workOrderProcessMapper.getOrderAcceptTimeByWorkOrderId(workOrderId); if (orderAcceptTime != null){ record.setOrderAcceptTime(orderAcceptTime); } - // 延期 + // 4.是否延期 LambdaQueryWrapper queryDelayWrapper = new LambdaQueryWrapper<>(); queryDelayWrapper.eq(WorkOrderDelay::getId, workOrderId); queryDelayWrapper.eq(WorkOrderDelay::getHandleResult,"审核通过"); @@ -1543,21 +1576,10 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { }else { record.setIsDelay("否"); } - // 审核 - // 默认 实际上要从审批情况中获取 + // 5.工单审核中的其他罚款 record.setOtherCost(0.0); record.setOtherCostReason("无"); - String initAdvice = workReviewInfoMapper.getInitAdvice(workOrderId); - if (StringUtils.isNotBlank(initAdvice)){ - record.setInitAdvice(initAdvice); - } - - String lastAdvice = workReviewInfoMapper.getLastAdvice(workOrderId); - if (StringUtils.isNotBlank(lastAdvice)){ - record.setLastAdvice(lastAdvice); - } - LambdaQueryWrapper reviewInfoQueryWrapper = new LambdaQueryWrapper<>(); reviewInfoQueryWrapper.eq(WorkReviewInfo::getWorkOrderId, workOrderId); reviewInfoQueryWrapper.orderByDesc(WorkReviewInfo::getCreateTime); @@ -1568,6 +1590,18 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { record.setOtherCostReason(lastReviewInfo.getOtherCostReason()); } + // 6.工单审核中的初审建议 + String initAdvice = workReviewInfoMapper.getInitAdvice(workOrderId); + if (StringUtils.isNotBlank(initAdvice)){ + record.setInitAdvice(initAdvice); + } + + // 7.工单审核中的终审建议 + String lastAdvice = workReviewInfoMapper.getLastAdvice(workOrderId); + if (StringUtils.isNotBlank(lastAdvice)){ + record.setLastAdvice(lastAdvice); + } + } return orderInfoVoList; @@ -1578,42 +1612,41 @@ public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService { WorkOrderInfoVo record = baseMapper.selectVoById(workOrderId); String handleTimeOutSituation = ""; String orderAcceptTimeOutSituation = ""; - // 根据项目名称获取接单超期信息 + // 1.根据项目名称构造查询条件 LambdaQueryWrapper projectQueryWrapper = new LambdaQueryWrapper<>(); projectQueryWrapper.eq(ProjectInfo::getProjectName, record.getProjectName()); projectQueryWrapper.last("LIMIT 1"); ProjectInfo projectInfo = projectInfoMapper.selectOne(projectQueryWrapper); + // 2.获取接单超期信息 String orderTakingOverTime = projectInfo.getOrderTakingOverTime(); String orderTakingCost = projectInfo.getOrderTakingCost(); String handleTimeOutCost = projectInfo.getHandleCost(); - // 1.接单超时 --> 参考时间:事件转派 故障派遣 - LambdaQueryWrapper takeOrderQueryWrapper = new LambdaQueryWrapper<>(); - takeOrderQueryWrapper.eq(WorkOrderProcess::getWorkOrderId, workOrderId); - takeOrderQueryWrapper.in(WorkOrderProcess::getStage, "故障派遣", "事件转派"); - takeOrderQueryWrapper.orderByDesc(WorkOrderProcess::getCreateTime); - takeOrderQueryWrapper.last("LIMIT 1"); - WorkOrderProcess takeOrderProcess = workOrderProcessMapper.selectOne(takeOrderQueryWrapper); + // 计算1:接单超时 按照最后是谁接单的来计算 --> 最后的(事件转派, 故障派遣时间 + 接单超期时间) 与 实际接单时间比较 + List stageList1 = Arrays.asList("故障派遣", "事件转派"); + WorkOrderProcess takeOrderProcess = getTargetWorkOrderProcess(workOrderId,stageList1,"desc"); if (takeOrderProcess != null && takeOrderProcess.getOperationTime() != null) { - orderAcceptTimeOutSituation = getTimeLeft(takeOrderProcess.getOperationTime(),Long.valueOf(orderTakingOverTime)); - } + List targetStageList = Arrays.asList("故障接单"); + orderAcceptTimeOutSituation = getTimeLeft(takeOrderProcess.getOperationTime(),Long.valueOf(orderTakingOverTime) + , workOrderId, targetStageList, "desc"); - // 2.响应超时(处理超时) --> 参考时间: 故障接单 - LambdaQueryWrapper dealQueryWrapper = new LambdaQueryWrapper<>(); - dealQueryWrapper.eq(WorkOrderProcess::getWorkOrderId, workOrderId); - dealQueryWrapper.eq(WorkOrderProcess::getStage, "故障接单"); + record.setOrderAcceptTimeOutSituation(orderAcceptTimeOutSituation); + } - if (record.getStatus()==9){ - // 如果是派遣的时间还是按照第一个人的接单时间来计算,否则都是按照最后一次接单时间来计算 - dealQueryWrapper.orderByAsc(WorkOrderProcess::getCreateTime); - }else { - dealQueryWrapper.orderByDesc(WorkOrderProcess::getCreateTime); + // 计算2:响应超时(处理超时) --> 参考时间: 故障接单时间 + 响应时间 与 实际故障处理时间比较 + WorkOrderProcess dealProcess; + List stageList2 = Arrays.asList("故障接单"); + if (record.getStatus() == 9) { + dealProcess = getTargetWorkOrderProcess(workOrderId, stageList2, "asc"); + } else { + dealProcess = getTargetWorkOrderProcess(workOrderId, stageList2, "desc"); } - dealQueryWrapper.last("LIMIT 1"); - WorkOrderProcess dealProcess = workOrderProcessMapper.selectOne(dealQueryWrapper); if (dealProcess != null && dealProcess.getOperationTime() != null) { - handleTimeOutSituation = getTimeLeft(dealProcess.getOperationTime(),record.getResponseTime() ); + List targetStageList = Arrays.asList("故障处理"); + handleTimeOutSituation = getTimeLeft(dealProcess.getOperationTime(),record.getResponseTime(), + workOrderId, targetStageList, "desc" ); + record.setHandleTimeOutSituation(handleTimeOutSituation); }