huang
4 小时以前 8ec0064cd95292f14027006a8be47c1a71f69af9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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<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
    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;
    }
}