Browse Source

2026-07-14

异常规则配置
master
fengyuan_yang 3 weeks ago
parent
commit
93f2082b74
  1. 1
      src/main/java/com/gaotao/modules/schedule/controller/ShiftChangeProductionReportController.java
  2. 66
      src/main/java/com/gaotao/modules/schedule/entity/ScheduleTodoMessageEntity.java
  3. 6
      src/main/java/com/gaotao/modules/schedule/entity/ShiftChangeProductionReportEntity.java
  4. 10
      src/main/java/com/gaotao/modules/schedule/mapper/ScheduleTodoMessageMapper.java
  5. 253
      src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java
  6. 30
      src/main/resources/mapper/schedule/ScheduleTodoMessageMapper.xml
  7. 4
      src/main/resources/mapper/schedule/ShiftChangeProductionReportMapper.xml

1
src/main/java/com/gaotao/modules/schedule/controller/ShiftChangeProductionReportController.java

@ -85,6 +85,7 @@ public class ShiftChangeProductionReportController {
entity.setSurfaceLossQty(rowData.get("surfaceLossQty") != null ? new BigDecimal(rowData.get("surfaceLossQty").toString()) : BigDecimal.ZERO);
entity.setPoorPerformanceQty(rowData.get("poorPerformanceQty") != null ? new BigDecimal(rowData.get("poorPerformanceQty").toString()) : BigDecimal.ZERO);
entity.setRemark(rowData.get("remark") != null ? rowData.get("remark").toString() : "");
entity.setPackingList(rowData.get("packingList") != null ? rowData.get("packingList").toString() : "");
entity.setCreatedBy(createdBy);
entity.setIsProcessed(0);

66
src/main/java/com/gaotao/modules/schedule/entity/ScheduleTodoMessageEntity.java

@ -0,0 +1,66 @@
package com.gaotao.modules.schedule.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 创建分卷异常规则代办消息
*/
@Data
@TableName("schedule_todo_message")
public class ScheduleTodoMessageEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 工厂
*/
private String site;
/**
* 事业部
*/
private String buNo;
/**
* 信息编码
*/
private String infoCode;
/**
* 派工单号
*/
private String seqNo;
/**
* 订单号
*/
private String orderNo;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 消息来源
*/
private String messageSource;
/**
* 审核标识Y/N
*/
private String auditFlag;
/**
* 操作标识Y/N
*/
private String operateFlag;
}

6
src/main/java/com/gaotao/modules/schedule/entity/ShiftChangeProductionReportEntity.java

@ -98,6 +98,11 @@ public class ShiftChangeProductionReportEntity implements Serializable {
*/
private String remark;
/**
* Packing List
*/
private String packingList;
/**
* 创建人
*/
@ -122,5 +127,6 @@ public class ShiftChangeProductionReportEntity implements Serializable {
* 处理时间
*/
private Date processedTime;
}

10
src/main/java/com/gaotao/modules/schedule/mapper/ScheduleTodoMessageMapper.java

@ -0,0 +1,10 @@
package com.gaotao.modules.schedule.mapper;
import com.gaotao.modules.schedule.entity.ScheduleTodoMessageEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ScheduleTodoMessageMapper {
void insertTodoMessage(ScheduleTodoMessageEntity data);
}

253
src/main/java/com/gaotao/modules/schedule/service/impl/ScheduleServiceImpl.java

@ -16,8 +16,12 @@ import com.gaotao.modules.schedule.data.dto.SfdcNewsfdcDto;
import com.gaotao.modules.schedule.data.dto.ShopOrderRollDto;
import com.gaotao.modules.schedule.data.dto.WorkbenchPostinspection;
import com.gaotao.modules.schedule.entity.ProductionReportData;
import com.gaotao.modules.schedule.entity.ScheduleTodoMessageEntity;
import com.gaotao.modules.schedule.entity.ShiftChangeProductionReportEntity;
import com.gaotao.modules.schedule.mapper.ProcedureMapper;
import com.gaotao.modules.schedule.mapper.ScheduleMapper;
import com.gaotao.modules.schedule.mapper.ScheduleTodoMessageMapper;
import com.gaotao.modules.schedule.mapper.ShiftChangeProductionReportMapper;
import com.gaotao.modules.schedule.mapper.SchedulingMapper;
import com.gaotao.modules.schedule.service.ScheduleService;
import com.gaotao.modules.schedule.service.SchedulingService;
@ -26,6 +30,8 @@ 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 com.gaotao.modules.trans.dao.TransNoControlMapper;
import com.gaotao.modules.trans.entity.TransNoControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -55,6 +61,9 @@ public class ScheduleServiceImpl implements ScheduleService {
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";
private static final String TODO_MSG_TRANS_TYPE = "ExM";
private static final String TODO_MSG_TRANS_TYPE_FALLBACK = "ExR";
private static final String TODO_MSG_SOURCE_PREFIX = "过站采集-创建分卷";
@Autowired
private ScheduleMapper scheduleMapper;
@ -68,6 +77,12 @@ public class ScheduleServiceImpl implements ScheduleService {
private SchedulingService schedulingService;
@Autowired
private SysSceneExceptionRuleMapper sysSceneExceptionRuleMapper;
@Autowired
private ShiftChangeProductionReportMapper shiftChangeProductionReportMapper;
@Autowired
private ScheduleTodoMessageMapper scheduleTodoMessageMapper;
@Autowired
private TransNoControlMapper transNoControlMapper;
@Override
@ -3553,6 +3568,7 @@ public class ScheduleServiceImpl implements ScheduleService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> checkSplitRollExceptionRule(SearchScheduleData inData) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("matched", false);
@ -3569,7 +3585,7 @@ public class ScheduleServiceImpl implements ScheduleService {
return resultMap;
}
Map<String, BigDecimal> metricMap = buildSplitRollMetricMap(inData);
List<SplitRollMetricContext> metricContextList = buildSplitRollMetricContexts(inData);
for (SysSceneExceptionRuleEntity rule : ruleList) {
SysSceneExceptionRuleConditionEntity query = new SysSceneExceptionRuleConditionEntity();
query.setSite(rule.getSite());
@ -3590,21 +3606,26 @@ public class ScheduleServiceImpl implements ScheduleService {
}
}
for (SysSceneExceptionRuleConditionEntity root : rootList) {
List<SysSceneExceptionRuleConditionEntity> childList = childMap.get(root.getConditionNo());
// 仅有头节点时视作不触发
if (CollectionUtils.isEmpty(childList)) {
continue;
}
if (!isConditionMatched(root, metricMap)) {
continue;
}
for (SysSceneExceptionRuleConditionEntity child : childList) {
if (!isConditionMatched(child, metricMap)) {
for (SplitRollMetricContext metricContext : metricContextList) {
Map<String, BigDecimal> metricMap = metricContext.metricMap;
for (SysSceneExceptionRuleConditionEntity root : rootList) {
List<SysSceneExceptionRuleConditionEntity> childList = childMap.get(root.getConditionNo());
// 仅有头节点时视作不触发
if (CollectionUtils.isEmpty(childList)) {
continue;
}
fillSplitRuleMatchResult(resultMap, rule, child);
return resultMap;
if (!isConditionMatched(root, metricMap)) {
continue;
}
for (SysSceneExceptionRuleConditionEntity child : childList) {
if (!isConditionMatched(child, metricMap)) {
continue;
}
fillSplitRuleMatchResult(resultMap, rule, child);
resultMap.put("matchedRollIndex", metricContext.rollIndex);
saveSplitRuleMatchedData(inData);
return resultMap;
}
}
}
}
@ -3612,12 +3633,70 @@ public class ScheduleServiceImpl implements ScheduleService {
return resultMap;
}
private Map<String, BigDecimal> buildSplitRollMetricMap(SearchScheduleData inData) {
Map<String, BigDecimal> metricMap = new HashMap<>();
private List<SplitRollMetricContext> buildSplitRollMetricContexts(SearchScheduleData inData) {
List<SplitRollMetricContext> contextList = new ArrayList<>();
List<Map<String, Object>> rollRows = inData.getRollRows();
if (rollRows == null) {
rollRows = new ArrayList<>();
}
if (rollRows.isEmpty()) {
contextList.add(new SplitRollMetricContext(1, buildMetricMapForSingleRoll(inData, rollRows)));
return contextList;
}
List<Map<String, Object>> sortedRows = new ArrayList<>(rollRows);
sortedRows.sort((left, right) -> {
if (left == null && right == null) {
return 0;
}
if (left == null) {
return 1;
}
if (right == null) {
return -1;
}
Integer leftNo = toInteger(left.get("rowNumber"));
Integer rightNo = toInteger(right.get("rowNumber"));
if (leftNo == null && rightNo == null) {
return 0;
}
if (leftNo == null) {
return 1;
}
if (rightNo == null) {
return -1;
}
return Integer.compare(leftNo, rightNo);
});
int rollCount = inData.getRollCount() > 0 ? inData.getRollCount() : (inData.getRollNums() == null ? 0 : inData.getRollNums());
if (rollCount <= 0) {
contextList.add(new SplitRollMetricContext(1, buildMetricMapForSingleRoll(inData, sortedRows)));
return contextList;
}
int rowsPerRoll = sortedRows.size() / rollCount;
int remainingRows = sortedRows.size() % rollCount;
int currentIndex = 0;
for (int i = 0; i < rollCount; i++) {
int currentRollRows = rowsPerRoll + (i < remainingRows ? 1 : 0);
if (currentRollRows <= 0 || currentIndex >= sortedRows.size()) {
continue;
}
int endIndex = Math.min(currentIndex + currentRollRows, sortedRows.size());
List<Map<String, Object>> currentRows = sortedRows.subList(currentIndex, endIndex);
contextList.add(new SplitRollMetricContext(i + 1, buildMetricMapForSingleRoll(inData, currentRows)));
currentIndex = endIndex;
}
if (contextList.isEmpty()) {
contextList.add(new SplitRollMetricContext(1, buildMetricMapForSingleRoll(inData, sortedRows)));
}
return contextList;
}
private Map<String, BigDecimal> buildMetricMapForSingleRoll(SearchScheduleData inData, List<Map<String, Object>> rollRows) {
Map<String, BigDecimal> metricMap = new HashMap<>();
BigDecimal goodQty = BigDecimal.ZERO;
BigDecimal surfaceLossQty = BigDecimal.ZERO;
@ -3625,13 +3704,16 @@ public class ScheduleServiceImpl implements ScheduleService {
BigDecimal defectQty = BigDecimal.ZERO;
for (Map<String, Object> row : rollRows) {
if (row == null) {
continue;
}
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 rowCount = rollRows.size();
int rollCount = inData.getRollCount() > 0 ? inData.getRollCount() : (inData.getRollNums() == null ? 0 : inData.getRollNums());
BigDecimal totalRollQty = toBigDecimal(inData.getTotalRollQty());
BigDecimal totalQty = goodQty.add(defectQty);
@ -3741,6 +3823,143 @@ public class ScheduleServiceImpl implements ScheduleService {
resultMap.put("message", "触发异常规则,但触发事件未配置。");
}
private void saveSplitRuleMatchedData(SearchScheduleData inData) {
saveSplitRuleCacheData(inData);
saveSplitRuleTodoMessage(inData);
}
private void saveSplitRuleCacheData(SearchScheduleData inData) {
if (inData == null || !StringUtils.hasText(inData.getSite()) || !StringUtils.hasText(inData.getOrderNo())) {
return;
}
Integer seqNo = parseSeqNo(inData.getSeqNo());
if (seqNo == null) {
return;
}
shiftChangeProductionReportMapper.deleteUnprocessedData(
inData.getSite(), inData.getOrderNo(), seqNo);
List<Map<String, Object>> rollRows = inData.getRollRows();
if (CollectionUtils.isEmpty(rollRows)) {
return;
}
List<ShiftChangeProductionReportEntity> cacheList = new ArrayList<>();
String createdBy = StringUtils.hasText(inData.getOperatorId()) ? inData.getOperatorId() : inData.getCreatedBy();
for (Map<String, Object> row : rollRows) {
ShiftChangeProductionReportEntity entity = new ShiftChangeProductionReportEntity();
entity.setSite(inData.getSite());
entity.setBuNo(inData.getBuNo());
entity.setOrderNo(inData.getOrderNo());
entity.setSeqNo(seqNo);
entity.setFixtureNo(inData.getFixture());
entity.setShiftFrom(inData.getShiftNo());
entity.setRowCount(inData.getRowCount() == null ? rollRows.size() : inData.getRowCount());
entity.setRollCount(inData.getRollCount());
Integer rowNumber = toInteger(row.get("rowNumber"));
entity.setRowBumber(rowNumber == null ? 0 : rowNumber);
entity.setGoodQty(toBigDecimal(row.get("goodQty")));
entity.setDefectQty(toBigDecimal(row.get("defectQty")));
entity.setSurfaceLossQty(toBigDecimal(row.get("surfaceLossQty")));
entity.setPoorPerformanceQty(toBigDecimal(row.get("poorPerformanceQty")));
entity.setRemark(row.get("remark") == null ? "" : String.valueOf(row.get("remark")));
entity.setPackingList(row.get("packingList") == null ? "" : String.valueOf(row.get("packingList")));
entity.setCreatedBy(createdBy);
entity.setIsProcessed(0);
cacheList.add(entity);
}
if (!CollectionUtils.isEmpty(cacheList)) {
shiftChangeProductionReportMapper.batchInsert(cacheList);
}
}
private void saveSplitRuleTodoMessage(SearchScheduleData inData) {
if (inData == null || !StringUtils.hasText(inData.getSite()) || !StringUtils.hasText(inData.getBuNo())
|| !StringUtils.hasText(inData.getOrderNo()) || !StringUtils.hasText(inData.getSeqNo())) {
return;
}
TransNoControl transNo = null;
try {
transNo = transNoControlMapper.getTransNo(inData.getSite(), TODO_MSG_TRANS_TYPE, inData.getBuNo());
} catch (Exception ex) {
logger.warn("获取代办消息编码失败,trans_type={}", TODO_MSG_TRANS_TYPE, ex);
}
if (transNo == null || !StringUtils.hasText(transNo.getNewTransNo())) {
transNo = transNoControlMapper.getTransNo(inData.getSite(), TODO_MSG_TRANS_TYPE_FALLBACK, inData.getBuNo());
}
if (transNo == null || !StringUtils.hasText(transNo.getNewTransNo())) {
throw new RuntimeException("代办消息编码生成失败,请先在TransNoControl维护trans_type=" + TODO_MSG_TRANS_TYPE);
}
ScheduleTodoMessageEntity entity = new ScheduleTodoMessageEntity();
entity.setSite(inData.getSite());
entity.setBuNo(inData.getBuNo());
entity.setInfoCode(transNo.getNewTransNo());
entity.setSeqNo(inData.getSeqNo());
entity.setOrderNo(inData.getOrderNo());
entity.setCreatedBy(StringUtils.hasText(inData.getOperatorId()) ? inData.getOperatorId() : inData.getCreatedBy());
entity.setMessageSource(buildTodoMessageSource(inData.getFunctionName()));
entity.setAuditFlag("N");
entity.setOperateFlag("N");
scheduleTodoMessageMapper.insertTodoMessage(entity);
}
private Integer parseSeqNo(String seqNo) {
if (!StringUtils.hasText(seqNo)) {
return null;
}
try {
return Integer.valueOf(seqNo.trim());
} catch (Exception ex) {
return null;
}
}
private Integer toInteger(Object value) {
if (value == null) {
return null;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
try {
String text = String.valueOf(value).trim();
if (!StringUtils.hasText(text)) {
return null;
}
return Integer.valueOf(text);
} catch (Exception ex) {
return null;
}
}
private String buildTodoMessageSource(String functionName) {
String source = TODO_MSG_SOURCE_PREFIX;
if (StringUtils.hasText(functionName)) {
source = source + "-" + functionName.trim();
}
return truncate(source, 100);
}
private String truncate(String text, int maxLength) {
if (text == null || maxLength <= 0 || text.length() <= maxLength) {
return text;
}
return text.substring(0, maxLength);
}
private static final class SplitRollMetricContext {
private final int rollIndex;
private final Map<String, BigDecimal> metricMap;
private SplitRollMetricContext(int rollIndex, Map<String, BigDecimal> metricMap) {
this.rollIndex = rollIndex;
this.metricMap = metricMap;
}
}
/**
* @return java.util.Map<java.lang.String, java.lang.Object>
* @Author LR

30
src/main/resources/mapper/schedule/ScheduleTodoMessageMapper.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gaotao.modules.schedule.mapper.ScheduleTodoMessageMapper">
<insert id="insertTodoMessage">
INSERT INTO schedule_todo_message (
site,
bu_no,
info_code,
seq_no,
order_no,
created_by,
created_time,
message_source,
audit_flag,
operate_flag
) VALUES (
#{site},
#{buNo},
#{infoCode},
#{seqNo},
#{orderNo},
#{createdBy},
GETDATE(),
#{messageSource},
#{auditFlag},
#{operateFlag}
)
</insert>
</mapper>

4
src/main/resources/mapper/schedule/ShiftChangeProductionReportMapper.xml

@ -21,6 +21,7 @@
surface_loss_qty AS surfaceLossQty,
poor_performance_qty AS poorPerformanceQty,
remark,
packing_list AS packingList,
created_by AS createdBy,
created_time AS createdTime,
is_processed AS isProcessed,
@ -48,7 +49,7 @@
INSERT INTO shift_change_production_report (
site, bu_no, order_no, seq_no, fixture_no, shift_from, shift_to,
row_count, roll_count, row_bumber, good_qty, defect_qty,
surface_loss_qty, poor_performance_qty, remark, created_by,
surface_loss_qty, poor_performance_qty, remark, packing_list, created_by,
created_time, is_processed
) VALUES
<foreach collection="list" item="item" separator=",">
@ -68,6 +69,7 @@
#{item.surfaceLossQty},
#{item.poorPerformanceQty},
#{item.remark},
#{item.packingList},
#{item.createdBy},
GETDATE(),
0

Loading…
Cancel
Save