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.dao.DuplicateKeyException;
|
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<EngineeringSequenceMapper, EngineeringSequence> implements EngineeringSequenceService {
|
|
// 修复:使用ThreadLocal保证DateTimeFormatter的线程安全
|
private static final ThreadLocal<DateTimeFormatter> 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
|
@Transactional(rollbackFor = Exception.class)
|
public String generateAndSaveEngineeringId(Date date) {
|
try {
|
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);
|
|
EngineeringSequence engineeringSequence = new EngineeringSequence();
|
engineeringSequence.setEngineeringId(engineeringId);
|
engineeringSequence.setDate(date);
|
engineeringSequence.setSequence(newSequence);
|
engineeringSequence.setCreatedTime(new Date());
|
engineeringSequence.setUpdatedTime(new Date());
|
engineeringSequence.setCreatedBy("system");
|
engineeringSequence.setUpdatedBy("system");
|
|
save(engineeringSequence);
|
|
log.info("生成工程号成功: engineeringId={}, date={}, sequence={}", engineeringId, date, newSequence);
|
return engineeringId;
|
} catch (DuplicateKeyException dup) {
|
log.error("生成工程号唯一键冲突: date={}", date, dup);
|
throw new RuntimeException("生成工程号失败", dup);
|
} catch (Exception e) {
|
log.error("生成工程号失败, date={}", date, e);
|
throw new RuntimeException("生成工程号失败", e);
|
}
|
}
|
}
|