|
|
@@ -1,5 +1,6 @@
|
|
|
package com.ygtx.gxt.task;
|
|
|
|
|
|
+import com.github.pagehelper.util.StringUtil;
|
|
|
import com.ygtx.common.core.domain.entity.SysUser;
|
|
|
import com.ygtx.common.core.domain.model.LoginUser;
|
|
|
import com.ygtx.common.utils.DateUtils;
|
|
|
@@ -8,6 +9,7 @@ import com.ygtx.framework.web.service.SysPermissionService;
|
|
|
import com.ygtx.gxt.domain.*;
|
|
|
import com.ygtx.gxt.service.*;
|
|
|
import com.ygtx.system.mapper.SysUserMapper;
|
|
|
+import com.ygtx.system.service.ISysConfigService;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -66,6 +68,9 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
@Autowired
|
|
|
private IGxtWorkOrderFlowService workOrderFlowService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+
|
|
|
// 限制每次查询的最大工单数量,防止数据量过大导致性能问题
|
|
|
private static final int MAX_ORDERS_PER_QUERY = 1;
|
|
|
|
|
|
@@ -480,7 +485,7 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
*
|
|
|
* @param workOrder 维保工单
|
|
|
*/
|
|
|
- /*private void processWorkOrderDeduction(GxtWorkOrder workOrder) {
|
|
|
+ /*private void processWorkOrderDeductionV0(GxtWorkOrder workOrder) {
|
|
|
try {
|
|
|
List<GxtWorkOrderPerson> persons = workOrder.getWorkOrderPersonList();
|
|
|
if (persons == null || persons.isEmpty()) {
|
|
|
@@ -1202,82 +1207,86 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 获取奖励配置(包含扣分阈值和扣分值)
|
|
|
- GxtSafeOperationReward rewardQuery = new GxtSafeOperationReward();
|
|
|
- rewardQuery.setStatus(0);
|
|
|
- List<GxtSafeOperationReward> rewardConfigs = safeOperationRewardService.selectGxtSafeOperationRewardList(rewardQuery);
|
|
|
- if (rewardConfigs.isEmpty()) {
|
|
|
- log.warn("未找到任何启用的安全运行奖励配置,无法进行扣分");
|
|
|
- return;
|
|
|
+ int stopDaysOver = 7;
|
|
|
+ String num = configService.selectConfigByKey("gxt.order.stopDaysOver");
|
|
|
+ if (StringUtil.isNotEmpty(num)) {
|
|
|
+ stopDaysOver = Integer.valueOf(num);
|
|
|
}
|
|
|
|
|
|
- // 按照safeDuration升序排序
|
|
|
- rewardConfigs.sort(Comparator.comparingInt(GxtSafeOperationReward::getSafeDuration));
|
|
|
-
|
|
|
- // 获取对应的扣分配置
|
|
|
- GxtSafeOperationReward applicableDeduction = getApplicableRewardConfig(rewardConfigs, stopDays);
|
|
|
- if (applicableDeduction == null) {
|
|
|
- log.debug("待结单维修工单 {} 停机 {} 天,未找到对应的扣分配置", repairOrder.getWorkOrderProjectNo(), stopDays);
|
|
|
+ if (stopDays < stopDaysOver) {
|
|
|
+ log.debug("待结单维修工单 {} 的停机时长 {} 小于超时停机时长为 {} 天,无需扣分", repairOrder.getWorkOrderProjectNo(), stopDays,stopDaysOver);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 获取停机扣分
|
|
|
- BigDecimal deductionScore = applicableDeduction.getDowntimeScore();
|
|
|
- if (deductionScore != null && deductionScore.compareTo(BigDecimal.ZERO) < 0) { // 确保是负数
|
|
|
- log.info("待结单维修工单 {} 停机 {} 天,达到扣罚档位 {} 天,共扣分 {}",
|
|
|
- repairOrder.getWorkOrderProjectNo(), stopDays, applicableDeduction.getSafeDuration(), deductionScore);
|
|
|
-
|
|
|
+ // 检查 overStopStatus 状态
|
|
|
+ Integer overStopStatus = repairOrder.getOverStopStatus();
|
|
|
+ if (overStopStatus == null) {
|
|
|
+ overStopStatus = 0; // 默认为 0
|
|
|
+ }
|
|
|
+
|
|
|
+ // 当维修工单 overStopStatus 为 0 时,更新 overStopStatus 为 1,并返回,不继续扣分
|
|
|
+ // 其他地方可以根据 overStopStatus=1 来进行添加人员的操作
|
|
|
+ if (overStopStatus == 0) {
|
|
|
+ repairOrder.setOverStopStatus(1);
|
|
|
+ repairOrderService.updateGxtRepairOrder(repairOrder);
|
|
|
+ log.info("待结单维修工单 {} overStopStatus 从 0 更新为 1", repairOrder.getWorkOrderProjectNo());
|
|
|
+ //overStopStatus = 1;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 获取奖励配置和扣分分数(公共逻辑)
|
|
|
+ BigDecimal deductionScore = getDeductionScore(repairOrder, stopDays);
|
|
|
+ if (deductionScore == null) {
|
|
|
+ return; // 没有找到合适的扣分配置或分数无效
|
|
|
+ }
|
|
|
+ if (overStopStatus == 2) {
|
|
|
+ // 当维修工单 overStopStatus 为 2 时,代表有真正的工作人员,进行真实扣分
|
|
|
+ log.debug("待结单维修工单 {} overStopStatus 为 2,已填写工作人员", repairOrder.getWorkOrderProjectNo());
|
|
|
+
|
|
|
// 获取工单作业人数
|
|
|
List<GxtRepairOrderPerson> persons = repairOrder.getRepairOrderPersonList();
|
|
|
if (persons == null || persons.isEmpty()) {
|
|
|
// 如果工单中的人员列表为空,尝试从数据库查询
|
|
|
persons = repairOrderService.selectRepairOrderPersonListByOrderId(repairOrder.getId());
|
|
|
}
|
|
|
-
|
|
|
- // 过滤出isLeader等于1的人员
|
|
|
- if (persons != null && !persons.isEmpty()) {
|
|
|
- List<GxtRepairOrderPerson> leaderPersons = new ArrayList<>();
|
|
|
- for (GxtRepairOrderPerson person : persons) {
|
|
|
- if (person.getIsLeader() != null && person.getIsLeader() == 1) {
|
|
|
- leaderPersons.add(person);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- persons = leaderPersons;
|
|
|
- }
|
|
|
-
|
|
|
- // 如果没有找到工作负责人,创建虚拟负责人继续处理
|
|
|
+
|
|
|
+ // 真实扣分过程实现:直接对所有人员进行扣分
|
|
|
if (persons == null || persons.isEmpty()) {
|
|
|
- log.warn("待结单维修工单 {} 没有找到工作负责人,创建虚拟负责人继续处理", repairOrder.getWorkOrderProjectNo());
|
|
|
- persons = createVirtualLeaderPerson(repairOrder);
|
|
|
+ log.warn("待结单维修工单 {} 没有找到工作人员,无法进行扣分", repairOrder.getWorkOrderProjectNo());
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 计算每人扣分 = (配置扣分值 ÷ 该工单作业人数)
|
|
|
int personCount = persons.size();
|
|
|
- //BigDecimal perPersonDeduction = deductionScore.divide(new BigDecimal(personCount), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
-
|
|
|
BigDecimal divisionResult = deductionScore.divide(new BigDecimal(personCount), 10, BigDecimal.ROUND_HALF_UP);
|
|
|
-
|
|
|
+
|
|
|
// 根据小数位数决定最终结果
|
|
|
BigDecimal perPersonDeduction;
|
|
|
if (divisionResult.scale() <= 6) {
|
|
|
- // 小数位数不超过6位,保持原值
|
|
|
+ // 小数位数不超过 6 位,保持原值
|
|
|
perPersonDeduction = divisionResult;
|
|
|
} else {
|
|
|
- // 小数位数超过6位,截取到6位小数
|
|
|
+ // 小数位数超过 6 位,截取到 6 位小数
|
|
|
perPersonDeduction = divisionResult.setScale(6, BigDecimal.ROUND_HALF_UP);
|
|
|
}
|
|
|
-
|
|
|
- log.info("待结单维修工单 {} 共 {} 人参与,每人扣分 {}",
|
|
|
- repairOrder.getWorkOrderProjectNo(), personCount, perPersonDeduction);
|
|
|
-
|
|
|
+
|
|
|
+ log.info("待结单维修工单 {} 共 {} 人参与,每人扣分 {}",
|
|
|
+ repairOrder.getWorkOrderProjectNo(), personCount, perPersonDeduction);
|
|
|
+
|
|
|
// 对相关工单人员进行扣分操作
|
|
|
- //updatePersonStopScoreForRepairOrder(repairOrder, perPersonDeduction, currentTime);
|
|
|
+ updatePersonStopScoreForRepairOrder(repairOrder, perPersonDeduction, currentTime);
|
|
|
// 更新月度统计数据
|
|
|
- //updateMonthlyScoreDataForStopScore(repairOrder, perPersonDeduction, currentTime);
|
|
|
- addOrderScoreDetailsForStopScoreRepairNotCompllete(repairOrder, persons, deductionScore, 3); // 3代表停机扣分
|
|
|
- } else {
|
|
|
- log.debug("待结单维修工单 {} 找到扣分配置但分数无效: {}", repairOrder.getWorkOrderProjectNo(), deductionScore);
|
|
|
+ updateMonthlyScoreDataForStopScore(repairOrder, perPersonDeduction, currentTime);
|
|
|
+
|
|
|
+ } else if (overStopStatus == 1) {
|
|
|
+ // 当维修工单 overStopStatus 为 1 时,表示已超停但没有真实工作人员,使用虚拟扣分
|
|
|
+ // 虚拟扣分过程实现:只添加明细记录,不实际更新人员得分
|
|
|
+ log.debug("待结单维修工单 {} overStopStatus 为 1,使用虚拟扣分", repairOrder.getWorkOrderProjectNo());
|
|
|
+
|
|
|
+ // 创建虚拟负责人进行扣分记录
|
|
|
+ List<GxtRepairOrderPerson> virtualPersons = createVirtualLeaderPerson(repairOrder);
|
|
|
+
|
|
|
+ // 添加虚拟扣分明细记录(状态为 1,表示挂起)
|
|
|
+ addOrderScoreDetailsForStopScoreRepairNotCompllete(repairOrder, virtualPersons, deductionScore, 3); // 3 代表停机扣分
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1286,7 +1295,7 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
*
|
|
|
* @param workOrder 维保工单
|
|
|
*/
|
|
|
- private void processWorkOrderDeduction(GxtWorkOrder workOrder) {
|
|
|
+ /*private void processWorkOrderDeduction(GxtWorkOrder workOrder) {
|
|
|
log.debug("开始处理维保工单 {} 的扣分", workOrder.getWorkOrderProjectNo());
|
|
|
|
|
|
// 计算停运天数:复运时间 - 停机时间(pauseTime)
|
|
|
@@ -1306,11 +1315,6 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /*Date archiveTime = getArchiveTimeForWorkOrder(workOrder.getId());
|
|
|
- if (archiveTime == null) {
|
|
|
- log.warn("维保工单 {} 未找到归档时间", workOrder.getWorkOrderProjectNo());
|
|
|
- return;
|
|
|
- }*/
|
|
|
Date realEndTime = workOrder.getRealEndTime();
|
|
|
if (realEndTime == null) {
|
|
|
log.warn("维保工单 {} 未找到结束时间", workOrder.getWorkOrderProjectNo());
|
|
|
@@ -1347,7 +1351,7 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
} else {
|
|
|
log.debug("维保工单 {} 找到扣分配置但分数无效: {}", workOrder.getWorkOrderProjectNo(), deductionScore);
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
/**
|
|
|
* 获取设备最近一次中断事件的工单
|
|
|
@@ -1845,4 +1849,46 @@ public class EquipmentSafeOperationRewardTask {
|
|
|
|
|
|
return virtualPersons;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取扣分分数(公共方法)
|
|
|
+ *
|
|
|
+ * @param repairOrder 维修工单
|
|
|
+ * @param stopDays 停机天数
|
|
|
+ * @return 扣分分数,如果未找到合适的配置则返回 null
|
|
|
+ */
|
|
|
+ private BigDecimal getDeductionScore(GxtRepairOrder repairOrder, int stopDays) {
|
|
|
+ try {
|
|
|
+ // 获取奖励配置(包含扣分阈值和扣分值)
|
|
|
+ GxtSafeOperationReward rewardQuery = new GxtSafeOperationReward();
|
|
|
+ rewardQuery.setStatus(0);
|
|
|
+ List<GxtSafeOperationReward> rewardConfigs = safeOperationRewardService.selectGxtSafeOperationRewardList(rewardQuery);
|
|
|
+ if (rewardConfigs.isEmpty()) {
|
|
|
+ log.warn("未找到任何启用的安全运行奖励配置,无法进行扣分");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按照 safeDuration 升序排序
|
|
|
+ rewardConfigs.sort(Comparator.comparingInt(GxtSafeOperationReward::getSafeDuration));
|
|
|
+
|
|
|
+ // 获取对应的扣分配置
|
|
|
+ GxtSafeOperationReward applicableDeduction = getApplicableRewardConfig(rewardConfigs, stopDays);
|
|
|
+ if (applicableDeduction == null) {
|
|
|
+ log.debug("待结单维修工单 {} 停机 {} 天,未找到对应的扣分配置", repairOrder.getWorkOrderProjectNo(), stopDays);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取停机扣分
|
|
|
+ BigDecimal deductionScore = applicableDeduction.getDowntimeScore();
|
|
|
+ if (deductionScore != null && deductionScore.compareTo(BigDecimal.ZERO) < 0) { // 确保是负数
|
|
|
+ return deductionScore;
|
|
|
+ } else {
|
|
|
+ log.debug("待结单维修工单 {} 找到扣分配置但分数无效:{}", repairOrder.getWorkOrderProjectNo(), deductionScore);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("获取扣分分数时发生异常", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|