package com.mes.device.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mes.device.entity.EngineeringSequence; import com.mes.device.mapper.EngineeringSequenceMapper; import com.mes.device.service.EngineeringSequenceService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; /** * 工程序号信息服务实现类 * * @author mes * @since 2025-11-20 */ @Slf4j @Service public class EngineeringSequenceServiceImpl extends ServiceImpl implements EngineeringSequenceService { // 修复:使用ThreadLocal保证DateTimeFormatter的线程安全 private static final ThreadLocal DATE_FORMATTER_THREAD_LOCAL = ThreadLocal.withInitial( () -> DateTimeFormatter.ofPattern("yyMMdd") ); // 重试间隔(毫秒),使用随机数避免并发请求同时重试 private static final int RETRY_INTERVAL_MIN = 50; private static final int RETRY_INTERVAL_MAX = 200; @Override public String generateEngineeringId(Date date) { Integer maxSequence = baseMapper.selectMaxSequenceByDate(date); maxSequence = (maxSequence == null) ? 0 : maxSequence; int newSequence = maxSequence + 1; LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); String dateStr = DATE_FORMATTER_THREAD_LOCAL.get().format(localDate); String engineeringId = "P" + dateStr + String.format("%02d", newSequence); log.info("生成工程号(未保存): engineeringId={}, date={}, sequence={}", engineeringId, date, newSequence); return engineeringId; } @Override @Transactional(rollbackFor = Exception.class) public boolean saveEngineeringId(Date date, String engineeringId) { try { // 解析工程号获取序号 LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); String dateStr = DATE_FORMATTER_THREAD_LOCAL.get().format(localDate); String sequenceStr = engineeringId.substring(engineeringId.length() - 2); int sequence = Integer.parseInt(sequenceStr); // 检查是否已存在 EngineeringSequence existing = baseMapper.selectByEngineeringId(engineeringId); EngineeringSequence engineeringSequence = new EngineeringSequence(); engineeringSequence.setEngineeringId(engineeringId); engineeringSequence.setDate(date); engineeringSequence.setSequence(sequence); boolean result; if (existing != null) { // 如果已存在,则更新 engineeringSequence.setId(existing.getId()); // 保留原始创建信息 engineeringSequence.setCreatedTime(existing.getCreatedTime()); engineeringSequence.setCreatedBy(existing.getCreatedBy()); // 更新为当前时间 engineeringSequence.setUpdatedTime(new Date()); engineeringSequence.setUpdatedBy("system"); result = updateById(engineeringSequence); if (result) { log.info("更新工程号成功: engineeringId={}, date={}, sequence={}", engineeringId, date, sequence); } else { log.error("更新工程号失败: engineeringId={}, date={}, sequence={}", engineeringId, date, sequence); } } else { // 如果不存在,则插入 engineeringSequence.setCreatedTime(new Date()); engineeringSequence.setUpdatedTime(new Date()); engineeringSequence.setCreatedBy("system"); engineeringSequence.setUpdatedBy("system"); result = save(engineeringSequence); if (result) { log.info("保存工程号成功: engineeringId={}, date={}, sequence={}", engineeringId, date, sequence); } else { log.error("保存工程号失败: engineeringId={}, date={}, sequence={}", engineeringId, date, sequence); } } return result; } catch (Exception e) { log.error("保存工程号失败, date={}, engineeringId={}", date, engineeringId, e); throw new RuntimeException("保存工程号失败", e); } } @Override @Transactional(rollbackFor = Exception.class) public String generateAndSaveEngineeringId(Date date) { String engineeringId = generateEngineeringId(date); saveEngineeringId(date, engineeringId); return engineeringId; } }