From 29731b463adc9de4a247e5dcfe8b78705966b715 Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Tue, 14 Jul 2026 15:16:36 +0800 Subject: [PATCH] =?UTF-8?q?2026-07-14=20=E5=BC=82=E5=B8=B8=E8=A7=84?= =?UTF-8?q?=E5=88=99=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ScheduleController.java | 12 ++ .../schedule/data/SearchScheduleData.java | 9 + .../schedule/service/ScheduleService.java | 8 + .../service/impl/ScheduleServiceImpl.java | 202 ++++++++++++++++++ .../mapper/SysSceneExceptionRuleMapper.java | 5 + .../sys/SysSceneExceptionRuleMapper.xml | 22 ++ 6 files changed, 258 insertions(+) diff --git a/src/main/java/com/gaotao/modules/schedule/controller/ScheduleController.java b/src/main/java/com/gaotao/modules/schedule/controller/ScheduleController.java index 49cd6e4..3fc7ed2 100644 --- a/src/main/java/com/gaotao/modules/schedule/controller/ScheduleController.java +++ b/src/main/java/com/gaotao/modules/schedule/controller/ScheduleController.java @@ -1295,6 +1295,18 @@ public class ScheduleController extends AbstractController { .put("resultMap", resultMap); } + /** + * 创建分卷前:异常规则校验(应用页面=过站采集,应用按钮=创建分卷) + */ + @PostMapping(value = "checkSplitRollExceptionRule") + public R checkSplitRollExceptionRule(@RequestBody SearchScheduleData inData) { + Map resultMap = scheduleService.checkSplitRollExceptionRule(inData); + return R.ok() + .put("code", 200) + .put("msg", getLanguageMsg(SysMsgConstant.OBJECT_ID_200000)) + .put("resultMap", resultMap); + } + /** * @Author LR * @Description 执行创建分卷的业务逻辑 diff --git a/src/main/java/com/gaotao/modules/schedule/data/SearchScheduleData.java b/src/main/java/com/gaotao/modules/schedule/data/SearchScheduleData.java index b96b8da..1c27912 100644 --- a/src/main/java/com/gaotao/modules/schedule/data/SearchScheduleData.java +++ b/src/main/java/com/gaotao/modules/schedule/data/SearchScheduleData.java @@ -173,6 +173,7 @@ public class SearchScheduleData extends BaseData { private String exportFlag;//导出的标记 private int rollCount; + private Float totalRollQty; private Float lotSize;//具体对应的字段 2022-08-17 @@ -227,6 +228,14 @@ public class SearchScheduleData extends BaseData { this.rollCount = rollCount; } + public Float getTotalRollQty() { + return totalRollQty; + } + + public void setTotalRollQty(Float totalRollQty) { + this.totalRollQty = totalRollQty; + } + public String isDirectRepackageflag() { return directRepackageflag; } diff --git a/src/main/java/com/gaotao/modules/schedule/service/ScheduleService.java b/src/main/java/com/gaotao/modules/schedule/service/ScheduleService.java index b97090e..203ee47 100644 --- a/src/main/java/com/gaotao/modules/schedule/service/ScheduleService.java +++ b/src/main/java/com/gaotao/modules/schedule/service/ScheduleService.java @@ -756,6 +756,14 @@ public interface ScheduleService { **/ Map checkCreateSplitSfdcRoll(SearchScheduleData inData); + /** + * 创建分卷前的异常规则校验(应用页面/应用按钮) + * + * @param inData 分卷页面数据 + * @return 校验结果 + */ + Map checkSplitRollExceptionRule(SearchScheduleData inData); + /** * @return void * @Author LR diff --git a/src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java b/src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java index 9639919..e6558e3 100644 --- a/src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java +++ b/src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java @@ -22,6 +22,9 @@ import com.gaotao.modules.schedule.mapper.SchedulingMapper; import com.gaotao.modules.schedule.service.ScheduleService; import com.gaotao.modules.schedule.service.SchedulingService; import com.gaotao.modules.shopOrder.entity.OperatorData; +import com.gaotao.modules.sys.entity.SysSceneExceptionRuleConditionEntity; +import com.gaotao.modules.sys.entity.SysSceneExceptionRuleEntity; +import com.gaotao.modules.sys.mapper.SysSceneExceptionRuleMapper; import com.gaotao.modules.sys.service.SysMsgService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,6 +35,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.ParseException; import java.util.*; @@ -45,6 +49,13 @@ import java.util.*; public class ScheduleServiceImpl implements ScheduleService { private static final Logger logger = LoggerFactory.getLogger(InboundNotificationServiceImpl.class); + private static final String SPLIT_RULE_APPLY_PAGE = "过站采集"; + private static final String SPLIT_RULE_APPLY_BUTTON = "创建分卷"; + private static final String ACTION_NONE = "NONE"; + private static final String ACTION_OPEN_DEFECT = "OPEN_DEFECT"; + private static final String ACTION_OPEN_DOWNTIME = "OPEN_DOWNTIME"; + private static final String ACTION_LOCK_PAGE = "LOCK_PAGE"; + @Autowired private ScheduleMapper scheduleMapper; @Autowired @@ -55,6 +66,8 @@ public class ScheduleServiceImpl implements ScheduleService { private SysMsgService sysMsgService; @Autowired private SchedulingService schedulingService; + @Autowired + private SysSceneExceptionRuleMapper sysSceneExceptionRuleMapper; @Override @@ -3539,6 +3552,195 @@ public class ScheduleServiceImpl implements ScheduleService { return resultMap; } + @Override + public Map checkSplitRollExceptionRule(SearchScheduleData inData) { + Map resultMap = new HashMap<>(); + resultMap.put("matched", false); + resultMap.put("lockPage", "N"); + resultMap.put("action", ACTION_NONE); + + if (inData == null || !StringUtils.hasText(inData.getSite()) || !StringUtils.hasText(inData.getBuNo())) { + return resultMap; + } + + List ruleList = sysSceneExceptionRuleMapper.getEnabledRuleListByApply( + inData.getSite(), inData.getBuNo(), SPLIT_RULE_APPLY_PAGE, SPLIT_RULE_APPLY_BUTTON); + if (CollectionUtils.isEmpty(ruleList)) { + return resultMap; + } + + Map metricMap = buildSplitRollMetricMap(inData); + for (SysSceneExceptionRuleEntity rule : ruleList) { + SysSceneExceptionRuleConditionEntity query = new SysSceneExceptionRuleConditionEntity(); + query.setSite(rule.getSite()); + query.setBuNo(rule.getBuNo()); + query.setRuleCode(rule.getRuleCode()); + List conditionList = sysSceneExceptionRuleMapper.getConditionList(query); + if (CollectionUtils.isEmpty(conditionList)) { + continue; + } + + Map> childMap = new LinkedHashMap<>(); + List rootList = new ArrayList<>(); + for (SysSceneExceptionRuleConditionEntity condition : conditionList) { + if (!StringUtils.hasText(condition.getParentConditionNo())) { + rootList.add(condition); + } else { + childMap.computeIfAbsent(condition.getParentConditionNo(), k -> new ArrayList<>()).add(condition); + } + } + + for (SysSceneExceptionRuleConditionEntity root : rootList) { + List childList = childMap.get(root.getConditionNo()); + // 仅有头节点时视作不触发 + if (CollectionUtils.isEmpty(childList)) { + continue; + } + if (!isConditionMatched(root, metricMap)) { + continue; + } + for (SysSceneExceptionRuleConditionEntity child : childList) { + if (!isConditionMatched(child, metricMap)) { + continue; + } + fillSplitRuleMatchResult(resultMap, rule, child); + return resultMap; + } + } + } + + return resultMap; + } + + private Map buildSplitRollMetricMap(SearchScheduleData inData) { + Map metricMap = new HashMap<>(); + List> rollRows = inData.getRollRows(); + if (rollRows == null) { + rollRows = new ArrayList<>(); + } + + BigDecimal goodQty = BigDecimal.ZERO; + BigDecimal surfaceLossQty = BigDecimal.ZERO; + BigDecimal poorPerformanceQty = BigDecimal.ZERO; + BigDecimal defectQty = BigDecimal.ZERO; + + for (Map row : rollRows) { + goodQty = goodQty.add(toBigDecimal(row.get("goodQty"))); + surfaceLossQty = surfaceLossQty.add(toBigDecimal(row.get("surfaceLossQty"))); + poorPerformanceQty = poorPerformanceQty.add(toBigDecimal(row.get("poorPerformanceQty"))); + defectQty = defectQty.add(toBigDecimal(row.get("defectQty"))); + } + + int rowCount = inData.getRowCount() == null ? rollRows.size() : inData.getRowCount(); + int rollCount = inData.getRollCount() > 0 ? inData.getRollCount() : (inData.getRollNums() == null ? 0 : inData.getRollNums()); + BigDecimal totalRollQty = toBigDecimal(inData.getTotalRollQty()); + BigDecimal totalQty = goodQty.add(defectQty); + BigDecimal yieldRate = BigDecimal.ZERO; + BigDecimal defectRate = BigDecimal.ZERO; + if (totalQty.compareTo(BigDecimal.ZERO) > 0) { + yieldRate = goodQty.multiply(BigDecimal.valueOf(100)).divide(totalQty, 6, RoundingMode.HALF_UP); + defectRate = defectQty.multiply(BigDecimal.valueOf(100)).divide(totalQty, 6, RoundingMode.HALF_UP); + } + + metricMap.put("排数", BigDecimal.valueOf(Math.max(rowCount, 0))); + metricMap.put("分切卷数", BigDecimal.valueOf(Math.max(rollCount, 0))); + metricMap.put("总卷数", totalRollQty); + metricMap.put("良品数", goodQty); + metricMap.put("面损", surfaceLossQty); + metricMap.put("性能不良", poorPerformanceQty); + metricMap.put("不良数", defectQty); + metricMap.put("总数", totalQty); + metricMap.put("良率", yieldRate); + metricMap.put("不良率", defectRate); + return metricMap; + } + + private boolean isConditionMatched(SysSceneExceptionRuleConditionEntity condition, Map metricMap) { + if (condition == null || !StringUtils.hasText(condition.getRelationField()) + || !StringUtils.hasText(condition.getCompareSymbol()) || condition.getConditionParam() == null) { + return false; + } + BigDecimal leftValue = metricMap.get(condition.getRelationField().trim()); + if (leftValue == null) { + return false; + } + BigDecimal rightValue = condition.getConditionParam(); + int compare = leftValue.compareTo(rightValue); + switch (condition.getCompareSymbol().trim()) { + case ">": + return compare > 0; + case "=": + return compare == 0; + case "<": + return compare < 0; + case ">=": + return compare >= 0; + case "<=": + return compare <= 0; + default: + return false; + } + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + if (value instanceof Number) { + return BigDecimal.valueOf(((Number) value).doubleValue()); + } + try { + String text = String.valueOf(value).trim().replace("%", ""); + if (!StringUtils.hasText(text)) { + return BigDecimal.ZERO; + } + return new BigDecimal(text); + } catch (Exception ex) { + return BigDecimal.ZERO; + } + } + + private void fillSplitRuleMatchResult(Map resultMap, + SysSceneExceptionRuleEntity rule, + SysSceneExceptionRuleConditionEntity condition) { + String triggerEvent = condition.getTriggerEvent(); + String forceType = condition.getForceType(); + + resultMap.put("matched", true); + resultMap.put("ruleCode", rule.getRuleCode()); + resultMap.put("ruleName", rule.getRuleName()); + resultMap.put("conditionNo", condition.getConditionNo()); + resultMap.put("triggerEvent", triggerEvent); + resultMap.put("forceType", forceType); + + if ("异常代码".equals(triggerEvent)) { + resultMap.put("action", ACTION_OPEN_DEFECT); + resultMap.put("lockPage", "N"); + resultMap.put("message", "触发异常规则,请先执行【报告不良】。"); + return; + } + + if ("异常单".equals(triggerEvent)) { + if ("强制".equals(forceType)) { + resultMap.put("action", ACTION_LOCK_PAGE); + resultMap.put("lockPage", "Y"); + resultMap.put("message", "触发强制异常单规则,当前页面已锁定。"); + } else { + resultMap.put("action", ACTION_OPEN_DOWNTIME); + resultMap.put("lockPage", "N"); + resultMap.put("message", "触发异常规则,请先执行【异常停机】。"); + } + return; + } + + resultMap.put("action", ACTION_NONE); + resultMap.put("lockPage", "N"); + resultMap.put("message", "触发异常规则,但触发事件未配置。"); + } + /** * @return java.util.Map * @Author LR diff --git a/src/main/java/com/gaotao/modules/sys/mapper/SysSceneExceptionRuleMapper.java b/src/main/java/com/gaotao/modules/sys/mapper/SysSceneExceptionRuleMapper.java index 8cf6c09..55ce9b0 100644 --- a/src/main/java/com/gaotao/modules/sys/mapper/SysSceneExceptionRuleMapper.java +++ b/src/main/java/com/gaotao/modules/sys/mapper/SysSceneExceptionRuleMapper.java @@ -15,6 +15,11 @@ public interface SysSceneExceptionRuleMapper { IPage searchRule(Page page, @Param("query") SysSceneExceptionRuleEntity data); + List getEnabledRuleListByApply(@Param("site") String site, + @Param("buNo") String buNo, + @Param("applyPage") String applyPage, + @Param("applyButton") String applyButton); + void saveRule(SysSceneExceptionRuleEntity data); void updateRule(SysSceneExceptionRuleEntity data); diff --git a/src/main/resources/mapper/sys/SysSceneExceptionRuleMapper.xml b/src/main/resources/mapper/sys/SysSceneExceptionRuleMapper.xml index 92bb858..99b01df 100644 --- a/src/main/resources/mapper/sys/SysSceneExceptionRuleMapper.xml +++ b/src/main/resources/mapper/sys/SysSceneExceptionRuleMapper.xml @@ -36,6 +36,28 @@ ORDER BY ISNULL(update_date, create_date) DESC, rule_code DESC + + INSERT INTO sys_scene_exception_rule (site, bu_no, rule_code, rule_name, apply_page, apply_button, enable_flag, create_by, create_date, update_by, update_date)