package cn.iocoder.yudao.module.mes.service.collect; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.mes.dal.dataobject.collect.*; import cn.iocoder.yudao.module.mes.dal.mysql.collect.*; import cn.iocoder.yudao.module.mes.enums.collect.MesCollectAlarmStatusEnum; import cn.iocoder.yudao.module.mes.enums.collect.MesCollectMsgTypeEnum; import tools.jackson.databind.JsonNode; import jakarta.annotation.Resource; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import java.time.LocalDateTime; /** * MES 数采数据落库 Service * * @author 超级管理员 */ @Service public class MesCollectDataService { @Resource private MesCollectDataParser parser; @Resource private MesCollectMessageMapper messageMapper; @Resource private MesCollectRealtimeMapper realtimeMapper; @Resource private MesCollectRealtimeHistoryMapper realtimeHistoryMapper; @Resource private MesCollectCycleMapper cycleMapper; @Resource private MesCollectTechMapper techMapper; @Resource private MesCollectOperateLogMapper collectOperateLogMapper; @Resource private MesCollectAlarmMapper alarmMapper; public Long saveRawMessage(String deviceCode, Long machineryId, String mqttTopic, MesCollectMsgTypeEnum msgType, LocalDateTime eventTime, String payload) { MesCollectMessageDO message = MesCollectMessageDO.builder() .deviceCode(deviceCode).machineryId(machineryId).mqttTopic(mqttTopic) .msgType(msgType.getType()).eventTime(eventTime).rawPayload(payload) .processStatus(0).receiveTime(LocalDateTime.now()).build(); messageMapper.insert(message); return message.getId(); } public void markRawMessageFailed(Long id, String error) { if (id == null) { return; } messageMapper.updateById(MesCollectMessageDO.builder() .id(id).processStatus(1).errorMsg(StrUtil.maxLength(error, 1000)).build()); } public void saveRealtime(String deviceCode, Long machineryId, Long taskId, Long workOrderId, LocalDateTime eventTime, JsonNode data) { MesCollectRealtimeDO snapshot = MesCollectRealtimeDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .collectTime(eventTime) .sts(parser.getInteger(data, "STS")) .opm(parser.getInteger(data, "OPM")) .asts(parser.getInteger(data, "ASTS")) .ot(parser.getDecimal(data, "OT")) .temps(parser.extractNumberedFields(data, "T")) .dataJson(data.toString()) .build(); MesCollectRealtimeDO existing = realtimeMapper.selectByDeviceCode(deviceCode); if (existing != null) { snapshot.setId(existing.getId()); realtimeMapper.updateById(snapshot); } else { try { realtimeMapper.insert(snapshot); } catch (DuplicateKeyException e) { MesCollectRealtimeDO current = realtimeMapper.selectByDeviceCode(deviceCode); if (current != null) { snapshot.setId(current.getId()); realtimeMapper.updateById(snapshot); } } } MesCollectRealtimeHistoryDO history = MesCollectRealtimeHistoryDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .collectTime(eventTime) .sts(snapshot.getSts()) .opm(snapshot.getOpm()) .asts(snapshot.getAsts()) .ot(snapshot.getOt()) .temps(snapshot.getTemps()) .dataJson(snapshot.getDataJson()) .build(); try { realtimeHistoryMapper.insert(history); } catch (DuplicateKeyException ignored) { // 同一设备同一秒的重复报文,直接忽略 } } public void saveCycle(String deviceCode, Long machineryId, Long taskId, Long workOrderId, LocalDateTime eventTime, JsonNode data) { Long cycleNo = parser.getLong(data, "CYCN"); MesCollectCycleDO cycle = MesCollectCycleDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .cycleNo(cycleNo == null ? 0L : cycleNo) .collectTime(eventTime) .ecyct(parser.getDecimal(data, "ECYCT")) .eiss(parser.getDecimal(data, "EISS")) .eivm(parser.getDecimal(data, "EIVM")) .eipm(parser.getDecimal(data, "EIPM")) .esipt(parser.getDecimal(data, "ESIPT")) .esipp(parser.getDecimal(data, "ESIPP")) .esips(parser.getDecimal(data, "ESIPS")) .eipt(parser.getDecimal(data, "EIPT")) .eipse(parser.getDecimal(data, "EIPSE")) .eplst(parser.getDecimal(data, "EPLST")) .eplsse(parser.getDecimal(data, "EPLSSE")) .eplspm(parser.getDecimal(data, "EPLSPM")) .etTemps(parser.extractNumberedFields(data, "ET")) .dataJson(data.toString()) .build(); try { cycleMapper.insert(cycle); } catch (DuplicateKeyException ignored) { // 同一周期重复上报,直接忽略 } } public void saveTech(String deviceCode, Long machineryId, Long taskId, Long workOrderId, LocalDateTime eventTime, JsonNode data) { MesCollectTechDO tech = MesCollectTechDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .collectTime(eventTime).dataJson(data.toString()).build(); MesCollectTechDO existing = techMapper.selectByDeviceCode(deviceCode); if (existing != null) { tech.setId(existing.getId()); techMapper.updateById(tech); } else { try { techMapper.insert(tech); } catch (DuplicateKeyException e) { MesCollectTechDO current = techMapper.selectByDeviceCode(deviceCode); if (current != null) { tech.setId(current.getId()); techMapper.updateById(tech); } } } } public void saveOperateLog(String deviceCode, Long machineryId, Long taskId, Long workOrderId, LocalDateTime eventTime, JsonNode data) { LocalDateTime modifyTime = parser.parseTimeText(parser.getText(data, "modifyTime")); collectOperateLogMapper.insert(MesCollectOperateLogDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .varId(parser.getText(data, "varId")) .oldValue(StrUtil.maxLength(parser.valueToString(data.get("lastValue")), 500)) .newValue(StrUtil.maxLength(parser.valueToString(data.get("value")), 500)) .modifyTime(modifyTime == null ? eventTime : modifyTime) .collectTime(eventTime).dataJson(data.toString()) .build()); } public void saveAlarm(String deviceCode, Long machineryId, Long taskId, Long workOrderId, LocalDateTime eventTime, JsonNode data) { Integer wmId = parser.getInteger(data, "wmId"); LocalDateTime wmTime = parser.parseTimeText(parser.getText(data, "wmTime")); if (wmTime == null) { wmTime = eventTime; } if (wmId != null && wmId == 0) { alarmMapper.clearActiveByDeviceCode(deviceCode, wmTime); return; } alarmMapper.insert(MesCollectAlarmDO.builder() .machineryId(machineryId).deviceCode(deviceCode).taskId(taskId).workOrderId(workOrderId) .wmId(wmId) .wmMsg(StrUtil.maxLength(parser.getText(data, "wmMsg"), 500)) .wmTime(wmTime) .status(MesCollectAlarmStatusEnum.ACTIVE.getStatus()) .collectTime(eventTime).dataJson(data.toString()) .build()); } }