新增:利元亨现场,ecn信息刷新机制备用版本代码临时提交
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package com.sdm.project.dao;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.outbridge.mode.SimulationTaskSyncExBo;
|
||||
import com.sdm.project.model.entity.SimulationTaskEcn;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 任务异常信息记录表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-05
|
||||
*/
|
||||
@Mapper
|
||||
public interface SimulationTaskEcnMapper extends BaseMapper<SimulationTaskEcn> {
|
||||
|
||||
List<SimulationTaskEcn> queryAllDataByProjectCodeAndStationCode(@Param("list") List<SimulationTaskSyncExBo> list);
|
||||
|
||||
}
|
||||
@@ -68,4 +68,8 @@ public interface SimulationTaskMapper extends BaseMapper<SimulationTask> {
|
||||
|
||||
int queryUnsyncedExceptionTasksTotal();
|
||||
|
||||
int queryAllasksTotal();
|
||||
|
||||
List<SimulationTaskSyncExBo> queryLyricAllTasksDatas(@Param("offset")int offset, @Param("pageSize")int pageSize);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.sdm.project.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author author
|
||||
* @since 2026-02-05
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("simulation_task_ecn")
|
||||
@ApiModel(value="SimulationTaskEcn对象", description="任务异常信息记录表")
|
||||
public class SimulationTaskEcn implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "主键ID,自增")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "项目号")
|
||||
@TableField("project_code")
|
||||
private String projectCode;
|
||||
|
||||
@ApiModelProperty(value = "工位号")
|
||||
@TableField("station_code")
|
||||
private String stationCode;
|
||||
|
||||
@ApiModelProperty(value = "异常数据,JSON字符串")
|
||||
@TableField("ecn_info")
|
||||
private String ecnInfo;
|
||||
|
||||
@ApiModelProperty(value = "数据来源,默认值 lyric ")
|
||||
@TableField("source")
|
||||
private String source;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
@TableField("update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sdm.project.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sdm.outbridge.mode.LyricExceptionModel;
|
||||
import com.sdm.project.model.entity.SimulationTaskExtra;
|
||||
import com.sdm.project.model.req.SpdmNodeExtraReq;
|
||||
|
||||
@@ -39,4 +40,5 @@ public interface ISimulationTaskExtraService extends IService<SimulationTaskExtr
|
||||
*/
|
||||
int batchUpdate(List<SpdmNodeExtraReq> taskExtras);
|
||||
|
||||
int batchRemoveAndSaveExceptionData(List<LyricExceptionModel> exceptionModels);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.sdm.project.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sdm.outbridge.mode.SimulationTaskSyncExBo;
|
||||
import com.sdm.project.model.entity.SimulationTaskEcn;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 任务异常信息记录表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-05
|
||||
*/
|
||||
public interface SimulationTaskEcnService extends IService<SimulationTaskEcn> {
|
||||
|
||||
List<SimulationTaskEcn> queryAllDataByProjectCodeAndStationCode(List<SimulationTaskSyncExBo> validTasks);
|
||||
|
||||
int batchRemoveSaveTaskEcns(List<SimulationTaskEcn> newTaskEcns);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
package com.sdm.project.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.outbridge.entity.LyricVProjectStationExcepTionToDM;
|
||||
import com.sdm.outbridge.mode.LyricExceptionModel;
|
||||
import com.sdm.outbridge.mode.SimulationTaskSyncExBo;
|
||||
import com.sdm.outbridge.service.lyric.LyricVProjectStationExcepTionToDMService;
|
||||
import com.sdm.project.dao.SimulationNodeMapper;
|
||||
import com.sdm.project.dao.SimulationTaskMapper;
|
||||
import com.sdm.project.model.entity.SimulationNode;
|
||||
import com.sdm.project.model.entity.SimulationTaskEcn;
|
||||
import com.sdm.project.service.ISimulationTaskExtraService;
|
||||
import com.sdm.project.service.SimulationTaskEcnService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class LyricInternalNewServiceImpl {
|
||||
|
||||
// 每批次处理的任务数量,可根据实际业务调整
|
||||
@Value("${lyric.syncException.batchSize:100}")
|
||||
private Integer batchSize;
|
||||
|
||||
@Autowired
|
||||
private SimulationTaskMapper simulationTaskMapper;
|
||||
|
||||
@Autowired
|
||||
private SimulationNodeMapper simulationNodeMapper;
|
||||
|
||||
@Autowired
|
||||
private LyricVProjectStationExcepTionToDMService lyricVProjectStationExcepTionToDMService;
|
||||
|
||||
@Autowired
|
||||
private SimulationTaskEcnService simulationTaskEcnService;
|
||||
|
||||
@Autowired
|
||||
private ISimulationTaskExtraService simulationTaskExtraService;
|
||||
|
||||
|
||||
/**
|
||||
* 同步异常任务信息方法 batchSize
|
||||
*/
|
||||
public SdmResponse syncException() {
|
||||
try {
|
||||
// 1. 查询所有的
|
||||
int total = simulationTaskMapper.queryAllasksTotal();
|
||||
if (total <= 0) {
|
||||
log.warn("同步异常任务:暂无需要同步的任务");
|
||||
return SdmResponse.success("同步异常任务:暂无需要同步的任务");
|
||||
}
|
||||
log.info("同步异常任务:待处理总任务数为{}条,将分批次处理,每批次{}条", total, batchSize);
|
||||
// 2. 初始化批次参数,循环分批处理
|
||||
int processedCount = 0; // 已处理的任务总数
|
||||
int syncTotalCount = 0; // 最终同步成功的异常数据总数
|
||||
int pageNum = 1; // 当前批次页码
|
||||
while (processedCount < total) {
|
||||
log.info("同步异常任务:开始处理第{}批次,已处理{}条,剩余{}条",
|
||||
pageNum, processedCount, total - processedCount);
|
||||
// 计算当前批次的起始和结束索引(分页查询)
|
||||
int fromIndex = processedCount;
|
||||
int endIndex = Math.min(processedCount + batchSize, total);
|
||||
// 3. 分批查询未同步异常任务
|
||||
List<SimulationTaskSyncExBo> unsyncedExceptionTasks = queryAllTasks(fromIndex, endIndex);
|
||||
if (CollectionUtils.isEmpty(unsyncedExceptionTasks)) {
|
||||
log.warn("同步异常任务:第{}批次查询结果为空,跳过该批次", pageNum);
|
||||
processedCount += batchSize;
|
||||
pageNum++;
|
||||
continue;
|
||||
}
|
||||
log.info("同步异常任务:第{}批次查询到{}条待处理任务", pageNum, unsyncedExceptionTasks.size());
|
||||
// 4. 构建标签对应的节点信息映射
|
||||
Map<String, SimulationNode> tag1NodeMap = buildTagNodeMap(unsyncedExceptionTasks, "tag1", "project");
|
||||
Map<String, SimulationNode> tag5NodeMap = buildTagNodeMap(unsyncedExceptionTasks, "tag5", "workspace");
|
||||
if (MapUtils.isEmpty(tag1NodeMap) && MapUtils.isEmpty(tag5NodeMap)) {
|
||||
log.warn("同步异常任务:第{}批次标签对应的节点信息为空,跳过该批次", pageNum);
|
||||
processedCount += unsyncedExceptionTasks.size();
|
||||
pageNum++;
|
||||
continue;
|
||||
}
|
||||
// 5. 为任务赋值对应的节点编码
|
||||
assignNodeCodeToTasks(unsyncedExceptionTasks, tag1NodeMap, tag5NodeMap);
|
||||
// 6. 过滤出编码完整的有效任务
|
||||
List<SimulationTaskSyncExBo> validTasks = filterValidTasks(unsyncedExceptionTasks);
|
||||
if (CollectionUtils.isEmpty(validTasks)) {
|
||||
log.warn("同步异常任务:第{}批次过滤后无有效任务,跳过该批次", pageNum);
|
||||
processedCount += unsyncedExceptionTasks.size();
|
||||
pageNum++;
|
||||
continue;
|
||||
}
|
||||
log.info("同步异常任务:第{}批次过滤后剩余{}条有效任务", pageNum, validTasks.size());
|
||||
|
||||
// 7. 查询异常数据并匹配任务
|
||||
// List<LyricExceptionModel> newExceptionModels = queryAndMatchExceptions(validTasks);
|
||||
Pair<List<LyricExceptionModel>, List<SimulationTaskEcn>> matchPair = queryAndMatchExceptions(validTasks);
|
||||
List<LyricExceptionModel> newExceptionModels = matchPair.getLeft();
|
||||
List<SimulationTaskEcn> newTaskEcns = matchPair.getRight();
|
||||
|
||||
if (CollectionUtils.isEmpty(newExceptionModels)) {
|
||||
log.info("同步异常任务:第{}批次无新增异常数据需要入库", pageNum);
|
||||
processedCount += unsyncedExceptionTasks.size();
|
||||
pageNum++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 8. 批量入库异常数据,累加同步成功数量
|
||||
int syncCount = 0;
|
||||
try {
|
||||
syncCount = simulationTaskExtraService.batchRemoveAndSaveExceptionData(newExceptionModels);
|
||||
} catch (Exception e) {
|
||||
log.error("batchRemoveAndSaveExceptionData error:{}", e.getMessage());
|
||||
continue;
|
||||
}
|
||||
syncTotalCount += syncCount;
|
||||
log.info("同步异常任务:第{}批次同步完成,本次同步{}条,累计同步{}条",
|
||||
pageNum, syncCount, syncTotalCount);
|
||||
// 更新已处理数量和页码
|
||||
processedCount += unsyncedExceptionTasks.size();
|
||||
pageNum++;
|
||||
// 9. batchSaveTaskEcns,记录EP异常的编码信息
|
||||
try {
|
||||
int ecnsCount = simulationTaskEcnService.batchRemoveSaveTaskEcns(newTaskEcns);
|
||||
} catch (Exception e) {
|
||||
log.error("batchRemoveSaveTaskEcns error:{}", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log.info("同步异常任务全部完成,总任务数{}条,累计同步异常数据{}条", total, syncTotalCount);
|
||||
return SdmResponse.success("同步成功,总任务数" + total + "条,累计同步了" + syncTotalCount + "条异常数据");
|
||||
} catch (Exception e) {
|
||||
log.error("同步异常任务执行失败,已处理部分数据", e);
|
||||
return SdmResponse.failed("同步异常任务失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有的任务
|
||||
*/
|
||||
private List<SimulationTaskSyncExBo> queryAllTasks(int fromIndex, int endIndex) {
|
||||
return simulationTaskMapper.queryLyricAllTasksDatas(fromIndex,endIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 构建标签对应的节点信息映射
|
||||
* @param tasks 任务列表
|
||||
* @param tagField 标签字段名(tag1/tag5)
|
||||
* @param nodeType 节点类型(project/workspace)
|
||||
*/
|
||||
private Map<String, SimulationNode> buildTagNodeMap(List<SimulationTaskSyncExBo> tasks,
|
||||
String tagField,
|
||||
String nodeType) {
|
||||
// 提取非空的标签值列表
|
||||
List<String> tagValues = tasks.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(task -> "tag1".equals(tagField) ? task.getTag1() : task.getTag5())
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.distinct() // 去重,减少查询次数
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(tagValues)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// 查询标签对应的节点信息
|
||||
List<SimulationNode> nodes = simulationNodeMapper.queryNodeCodeByTags(tagValues, tagField, nodeType);
|
||||
if (CollectionUtils.isEmpty(nodes)) {
|
||||
log.warn("同步异常任务:{}类型节点查询结果为空,标签列表:{}", nodeType, tagValues);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// 转换为UUID->节点的映射(处理重复UUID,保留第一个)
|
||||
return nodes.stream()
|
||||
.filter(node -> node != null && StringUtils.isNotBlank(node.getUuid()))
|
||||
.collect(Collectors.toMap(
|
||||
SimulationNode::getUuid,
|
||||
node -> node,
|
||||
(existing, replacement) -> existing
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为任务赋值对应的节点编码
|
||||
*/
|
||||
private void assignNodeCodeToTasks(List<SimulationTaskSyncExBo> tasks,
|
||||
Map<String, SimulationNode> tag1NodeMap,
|
||||
Map<String, SimulationNode> tag5NodeMap) {
|
||||
tasks.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(task -> {
|
||||
// 赋值tag1Code
|
||||
if (MapUtils.isNotEmpty(tag1NodeMap) && StringUtils.isNotBlank(task.getTag1())) {
|
||||
SimulationNode node = tag1NodeMap.get(task.getTag1());
|
||||
if (node != null) {
|
||||
task.setTag1Code(node.getNodeCode());
|
||||
}
|
||||
}
|
||||
// 赋值tag5Code
|
||||
if (MapUtils.isNotEmpty(tag5NodeMap) && StringUtils.isNotBlank(task.getTag5())) {
|
||||
SimulationNode node = tag5NodeMap.get(task.getTag5());
|
||||
if (node != null) {
|
||||
task.setTag5Code(node.getNodeCode());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤出tag1Code和tag5Code都不为空的有效任务
|
||||
*/
|
||||
private List<SimulationTaskSyncExBo> filterValidTasks(List<SimulationTaskSyncExBo> tasks) {
|
||||
return tasks.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.filter(task -> StringUtils.isNotBlank(task.getTag1Code())
|
||||
&& StringUtils.isNotBlank(task.getTag5Code()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询异常数据并匹配任务
|
||||
*/
|
||||
private Pair<List<LyricExceptionModel>,List<SimulationTaskEcn>> queryAndMatchExceptions(List<SimulationTaskSyncExBo> validTasks) {
|
||||
// 查询EP视图异常数据
|
||||
List<LyricVProjectStationExcepTionToDM> exceptionList = lyricVProjectStationExcepTionToDMService
|
||||
.queryExceptionsByProjectAndStation(validTasks);
|
||||
// 查询 simulation_task_ecn 异常信息的表数据
|
||||
List<SimulationTaskEcn>taskEcnsList =simulationTaskEcnService.
|
||||
queryAllDataByProjectCodeAndStationCode(validTasks);
|
||||
|
||||
// 匹配异常和任务,返回新增的异常数据
|
||||
return matchExceptionAndTask(exceptionList, validTasks,taskEcnsList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 匹配两个集合,筛选符合条件的数据并封装为 LyricExceptionModel 列表
|
||||
* @param exceptionList 异常信息列表
|
||||
* @param noSyncLists 没有同步的有异常的任务同步列表
|
||||
* @return 匹配后的异常模型列表
|
||||
*/
|
||||
public Pair<List<LyricExceptionModel>,List<SimulationTaskEcn>> matchExceptionAndTask(List<LyricVProjectStationExcepTionToDM> exceptionList,
|
||||
List<SimulationTaskSyncExBo> noSyncLists, List<SimulationTaskEcn>taskEcnsList) {
|
||||
List<LyricExceptionModel> ingDealExceptionList = new ArrayList<>();
|
||||
List<SimulationTaskEcn> ingDealTaskEcnList = new ArrayList<>();
|
||||
// key = ProjectCode_StationCode sdpm系统已经记录的异常信息
|
||||
Map<String, List<String>> spdmDbEcnMap=new HashMap<>();
|
||||
if(CollectionUtils.isNotEmpty(taskEcnsList)) {
|
||||
spdmDbEcnMap = taskEcnsList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
// 生成Key:projectCode + "_" + stationCode
|
||||
ecn -> ecn.getProjectCode() + "_" + ecn.getStationCode(),
|
||||
// 解析ecnInfo JSON字符串为List<String>
|
||||
ecn -> JSON.parseArray(ecn.getEcnInfo(), String.class),
|
||||
// 解决Key冲突:若存在相同projectCode+stationCode,合并两个List
|
||||
(existing, replacement) -> {
|
||||
existing.addAll(replacement);
|
||||
return existing;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
// key = ProjectCode_StationCode ep拉回来的异常信息
|
||||
Map<String, List<String>> epExceptionsMap = new HashMap<>();
|
||||
if(CollectionUtils.isNotEmpty(exceptionList)) {
|
||||
epExceptionsMap = exceptionList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
// 生成 Key:projectNum_stationCode
|
||||
dto -> dto.getProjectNum() + "_" + dto.getStationCode(),
|
||||
// 生成 Value:将单个 ecnCode 封装为 List
|
||||
dto -> {
|
||||
List<String> ecnCodeList = new ArrayList<>();
|
||||
ecnCodeList.add(dto.getEcnCode());
|
||||
return ecnCodeList;
|
||||
},
|
||||
// Key 冲突时,合并 List(将新的 ecnCode 添加到原有 List 中)
|
||||
(existingList, newList) -> {
|
||||
existingList.addAll(newList);
|
||||
return existingList;
|
||||
}
|
||||
));
|
||||
}
|
||||
// spdm db的task
|
||||
Map<String, List<SimulationTaskSyncExBo>> taskDbMap=new HashMap<>();
|
||||
if(CollectionUtils.isNotEmpty(noSyncLists)) {
|
||||
taskDbMap = noSyncLists.stream()
|
||||
.filter(bo -> bo != null
|
||||
&& bo.getTag1Code() != null && !bo.getTag1Code().trim().isEmpty()
|
||||
&& bo.getTag5Code() != null && !bo.getTag5Code().trim().isEmpty())
|
||||
.collect(Collectors.groupingBy(
|
||||
bo -> bo.getTag1Code().trim() + "_" + bo.getTag5Code().trim()
|
||||
));
|
||||
}
|
||||
// 判断是否需要修改
|
||||
// 后面再次拉取异常,假如没有新增,原始的3条不动,即使spdm任务增加到4条,也不动;
|
||||
//假如新增了异常,那拓展的数据需要修改+新增。
|
||||
// 遍历 任务的Map 的 entrySet,同时获取 key 和对应的 List<SimulationTaskSyncExBo>
|
||||
for (Map.Entry<String, List<SimulationTaskSyncExBo>> entry : taskDbMap.entrySet()) {
|
||||
// 获取当前键
|
||||
String key = entry.getKey();
|
||||
// ep异常和spdm task对应上了
|
||||
if(epExceptionsMap.containsKey(key)) {
|
||||
// 这个任务有异常
|
||||
List<String> epEcnCodes = epExceptionsMap.get(key);
|
||||
List<String> spdmEcnCodes = spdmDbEcnMap.get(key);
|
||||
// 调用方法判断是否相等,异常是否有新增
|
||||
boolean isEqual = Objects.equals(epEcnCodes, spdmEcnCodes);
|
||||
// 异常信息变了,重新维护任务异常,及异常编号的记录
|
||||
if(!isEqual) {
|
||||
// 获取当前值(List 集合)
|
||||
List<SimulationTaskSyncExBo> spdmDbtaskList = entry.getValue();
|
||||
// 1. 先判断 List 是否为空(避免空指针,最佳实践)
|
||||
if (CollectionUtils.isNotEmpty(spdmDbtaskList)) {
|
||||
String projectCode="";
|
||||
String stationCode="";
|
||||
// 2. 处理每个任务的异常
|
||||
for (SimulationTaskSyncExBo taskDb : spdmDbtaskList) {
|
||||
LyricExceptionModel model = new LyricExceptionModel();
|
||||
model.setUuid(taskDb.getUuid());
|
||||
ingDealExceptionList.add(model);
|
||||
if(StringUtils.isNotBlank(projectCode)) {projectCode=taskDb.getTag1Code();}
|
||||
if(StringUtils.isNotBlank(stationCode)) {stationCode=taskDb.getTag5Code();}
|
||||
}
|
||||
if(CollectionUtils.isNotEmpty(epEcnCodes)) {
|
||||
// 处理项目+工位下的异常
|
||||
SimulationTaskEcn taskEcn = new SimulationTaskEcn();
|
||||
taskEcn.setEcnInfo(JSONObject.toJSONString(epEcnCodes));
|
||||
taskEcn.setSource("lyric");
|
||||
taskEcn.setProjectCode(projectCode);
|
||||
taskEcn.setStationCode(stationCode);
|
||||
taskEcn.setCreateTime(LocalDateTime.now());
|
||||
taskEcn.setUpdateTime(LocalDateTime.now());
|
||||
ingDealTaskEcnList.add(taskEcn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.of(ingDealExceptionList, ingDealTaskEcnList);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.sdm.project.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sdm.outbridge.mode.SimulationTaskSyncExBo;
|
||||
import com.sdm.project.dao.SimulationTaskEcnMapper;
|
||||
import com.sdm.project.model.entity.SimulationTaskEcn;
|
||||
import com.sdm.project.service.SimulationTaskEcnService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 任务异常信息记录表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-05
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SimulationTaskEcnServiceImpl extends ServiceImpl<SimulationTaskEcnMapper, SimulationTaskEcn> implements SimulationTaskEcnService {
|
||||
|
||||
@Autowired
|
||||
private SimulationTaskEcnMapper simulationTaskEcnMapper;
|
||||
|
||||
@Override
|
||||
public List<SimulationTaskEcn> queryAllDataByProjectCodeAndStationCode(List<SimulationTaskSyncExBo> validTasks) {
|
||||
return simulationTaskEcnMapper.queryAllDataByProjectCodeAndStationCode(validTasks);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int batchRemoveSaveTaskEcns(List<SimulationTaskEcn> newTaskEcns) {
|
||||
// 先删除,再插入
|
||||
// 1. 判空处理:集合为空直接返回,避免全表删除
|
||||
if (CollectionUtils.isEmpty(newTaskEcns)) {
|
||||
return 0;
|
||||
}
|
||||
// 2. 构建 Lambda 查询条件
|
||||
LambdaQueryWrapper<SimulationTaskEcn> queryWrapper = new LambdaQueryWrapper<>();
|
||||
// 3. 遍历集合,拼接多组 (projectCode AND stationCode) 条件
|
||||
for (SimulationTaskEcn taskEcn : newTaskEcns) {
|
||||
// 每一组条件都用 and() 包裹,确保逻辑正确
|
||||
queryWrapper.or(i -> i
|
||||
.eq(SimulationTaskEcn::getProjectCode, taskEcn.getProjectCode())
|
||||
.eq(SimulationTaskEcn::getStationCode, taskEcn.getStationCode())
|
||||
);
|
||||
}
|
||||
// 4. 执行删除
|
||||
boolean remove = this.remove(queryWrapper);
|
||||
log.warn("batchSaveTaskEcns before delete: {}", remove);
|
||||
if(!remove) {
|
||||
log.error("batchSaveTaskEcns before delete failed");
|
||||
throw new RuntimeException("batchSaveTaskEcns before delete failed");
|
||||
}
|
||||
boolean b = this.saveBatch(newTaskEcns);
|
||||
if(!b) {
|
||||
log.error("batchSaveTaskEcns after save failed");
|
||||
throw new RuntimeException("batchSaveTaskEcns after save failed");
|
||||
}
|
||||
log.info("batchSaveTaskEcns after save: {}", b);
|
||||
return newTaskEcns.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,16 +2,19 @@ package com.sdm.project.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sdm.outbridge.mode.LyricExceptionModel;
|
||||
import com.sdm.project.dao.SimulationTaskExtraMapper;
|
||||
import com.sdm.project.model.entity.SimulationTaskExtra;
|
||||
import com.sdm.project.model.req.SpdmNodeExtraReq;
|
||||
import com.sdm.project.service.ISimulationTaskExtraService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -22,9 +25,13 @@ import java.util.stream.Collectors;
|
||||
* @author author
|
||||
* @since 2025-09-16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SimulationTaskExtraServiceImpl extends ServiceImpl<SimulationTaskExtraMapper, SimulationTaskExtra> implements ISimulationTaskExtraService {
|
||||
|
||||
@Autowired
|
||||
private SimulationTaskExtraMapper simulationTaskExtraMapper;
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, SimulationTaskExtra>> batchGetTaskExtraMap(List<String> taskIds, List<String> propertyNames) {
|
||||
if (CollectionUtils.isEmpty(taskIds) || CollectionUtils.isEmpty(propertyNames)) {
|
||||
@@ -68,4 +75,68 @@ public class SimulationTaskExtraServiceImpl extends ServiceImpl<SimulationTaskEx
|
||||
return successCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量保存异常数据到扩展表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int batchRemoveAndSaveExceptionData(List<LyricExceptionModel> exceptionModels) {
|
||||
// 先删除,再插入
|
||||
List<String> taskIdList = exceptionModels.stream()
|
||||
// 提取每个 LyricExceptionModel 对象的 uuid 字段
|
||||
.map(LyricExceptionModel::getUuid)
|
||||
// 过滤掉 null 的 uuid(可选,根据业务需求决定是否保留)
|
||||
.filter(Objects::nonNull)
|
||||
// 收集为新的 List<String>
|
||||
.collect(Collectors.toList());
|
||||
// 2. 构建 Lambda 查询条件
|
||||
LambdaQueryWrapper<SimulationTaskExtra> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(SimulationTaskExtra::getTaskId, taskIdList);
|
||||
// 3. 执行删除
|
||||
boolean remove = this.remove(queryWrapper);
|
||||
log.warn("batchSaveExceptionData before delete: {}", remove);
|
||||
if(!remove) {
|
||||
log.error("batchSaveExceptionData before delete failed");
|
||||
throw new RuntimeException("batchSaveExceptionData before delete failed");
|
||||
}
|
||||
// 构建扩展表数据
|
||||
List<SpdmNodeExtraReq> abnormalExtraList = new ArrayList<>();
|
||||
// List<SpdmNodeExtraReq> abnormalDetailExtraList = new ArrayList<>();
|
||||
for (LyricExceptionModel model : exceptionModels) {
|
||||
if (model == null || StringUtils.isBlank(model.getUuid())) {
|
||||
log.warn("同步异常任务:异常模型数据无效,跳过处理,model={}", model);
|
||||
continue;
|
||||
}
|
||||
// 构建异常标识扩展记录
|
||||
SpdmNodeExtraReq abnormalExtra = new SpdmNodeExtraReq();
|
||||
abnormalExtra.setNodeId(model.getUuid());
|
||||
abnormalExtra.setPropertyName("abnormal");
|
||||
abnormalExtra.setPropertyValue("1");
|
||||
abnormalExtraList.add(abnormalExtra);
|
||||
// // 构建异常详情扩展记录 异常的详情暂时不需要 项目号+工位号 查出来的异常非常多,如果存储的话需要注意
|
||||
// SpdmNodeExtraReq detailExtra = new SpdmNodeExtraReq();
|
||||
// detailExtra.setNodeId(model.getUuid());
|
||||
// detailExtra.setPropertyName("abnormalDetail");
|
||||
// detailExtra.setPropertyValue(JSONObject.toJSONString(model));
|
||||
// abnormalDetailExtraList.add(detailExtra);
|
||||
|
||||
}
|
||||
// 批量插入异常标识
|
||||
if (CollectionUtils.isNotEmpty(abnormalExtraList)) {
|
||||
int abnormalCount = simulationTaskExtraMapper.addTaskExtraBatch(abnormalExtraList);
|
||||
if(abnormalCount <=0) {
|
||||
throw new RuntimeException("batchSaveExceptionData failed");
|
||||
}
|
||||
log.info("同步异常任务:批量插入异常标识{}条,成功{}条", abnormalExtraList.size(), abnormalCount);
|
||||
}
|
||||
|
||||
// 批量插入异常详情
|
||||
// if (CollectionUtils.isNotEmpty(abnormalDetailExtraList)) {
|
||||
// int detailCount = simulationTaskExtraMapper.addTaskExtraBatch(abnormalDetailExtraList);
|
||||
// log.info("同步异常任务:批量插入异常详情{}条,成功{}条", abnormalDetailExtraList.size(), detailCount);
|
||||
// }
|
||||
|
||||
return exceptionModels.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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.sdm.project.dao.SimulationTaskEcnMapper">
|
||||
|
||||
|
||||
<select id="queryAllDataByProjectCodeAndStationCode"
|
||||
resultType="com.sdm.project.model.entity.SimulationTaskEcn">
|
||||
SELECT
|
||||
id AS id,
|
||||
project_code AS projectCode,
|
||||
station_code AS stationCode,
|
||||
ecn_info AS ecnInfo,
|
||||
source AS source,
|
||||
create_time AS createTime,
|
||||
update_time AS updateTime
|
||||
FROM simulation_task_ecn
|
||||
WHERE 1=1
|
||||
AND (
|
||||
<foreach collection="list" item="task" separator="OR">
|
||||
<!-- 核心条件:project_num = tag1Code 且 station_code = tag5Code -->
|
||||
(project_code = #{task.tag1Code} AND station_code = #{task.tag5Code})
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -743,5 +743,18 @@
|
||||
AND t.tag5 IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="queryAllasksTotal" resultType="java.lang.Integer">
|
||||
SELECT COUNT(*)
|
||||
FROM simulation_task t
|
||||
WHERE t.tag1 IS NOT NULL AND t.tag5 IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="queryLyricAllTasksDatas" resultType="com.sdm.outbridge.mode.SimulationTaskSyncExBo">
|
||||
SELECT t.id, t.uuid, t.tag1, t.tag5
|
||||
FROM simulation_task t
|
||||
WHERE t.tag1 IS NOT NULL
|
||||
AND t.tag5 IS NOT NULL
|
||||
ORDER BY create_time ASC LIMIT #{offset}, #{pageSize}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user