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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package org.jeecg.modules.eam.service.impl;
 
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.eam.constant.BusinessCodeConst;
import org.jeecg.modules.eam.constant.HfTemplateCategoryEnum;
import org.jeecg.modules.eam.constant.SecondMaintenanceStatusEnum;
import org.jeecg.modules.eam.entity.EamBaseHFCode;
import org.jeecg.modules.eam.entity.EamMaintenanceStandardDetail;
import org.jeecg.modules.eam.entity.EamSecondMaintenanceOrder;
import org.jeecg.modules.eam.entity.EamSecondMaintenanceOrderDetail;
import org.jeecg.modules.eam.mapper.EamSecondMaintenanceOrderMapper;
import org.jeecg.modules.eam.service.IEamBaseHFCodeService;
import org.jeecg.modules.eam.service.IEamFactorySecondMaintPlanService;
import org.jeecg.modules.eam.service.IEamMaintenanceStandardDetailService;
import org.jeecg.modules.eam.service.IEamSecondMaintenanceOrderDetailService;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
 
@Service
@Slf4j
public class EamSecondMaintenanceOrderAsyncService {
    @Resource
    private EamSecondMaintenanceOrderMapper eamSecondMaintenanceOrderMapper;
 
    @Autowired
    private IEamSecondMaintenanceOrderDetailService secondMaintenanceOrderDetailService;
 
    @Autowired
    private IEamMaintenanceStandardDetailService eamMaintenanceStandardDetailService;
 
    @Autowired
    private IEamBaseHFCodeService hfCodeService;
 
    @Autowired
    private ISysBusinessCodeRuleService businessCodeRuleService;
 
    @Autowired
    private IEamFactorySecondMaintPlanService factorySecondMaintPlanService;
 
    @Async
    public void asyncGenerateNextMaintenanceOrder(String orderId) {
        try {
            log.info("开始异步生成下次工单,原工单ID: {}", orderId);
            generateNextOrder(orderId);
            log.info("异步生成下次工单完成,原工单ID: {}", orderId);
        } catch (Exception e) {
            log.error("异步生成下次工单失败,工单ID: {}", orderId, e);
            // 发送告警通知或进行重试
        }
    }
 
    @Transactional(rollbackFor = Exception.class)
    public void generateNextOrder(String orderId) {
        EamSecondMaintenanceOrder entity = eamSecondMaintenanceOrderMapper.selectById(orderId);
        if (entity == null) {
            log.warn("原工单不存在,ID: {}", orderId);
            return;
        }
        if (!entity.getMaintenanceStatus().equals(SecondMaintenanceStatusEnum.COMPLETE.name())) {
            log.warn("原工单状态未完成,不生成下次工单,ID: {}", orderId);
            return;
        }
 
        // 生成新的工单编号
        String newOrderNum = businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.SECOND_MAINTENANCE_CODE_RULE);
        if (StrUtil.isEmpty(newOrderNum)) {
            throw new JeecgBootException("生成工单编号失败");
        }
 
        EamSecondMaintenanceOrder nextOrder = new EamSecondMaintenanceOrder();
        nextOrder.setOrderNum(newOrderNum);
        nextOrder.setEquipmentId(entity.getEquipmentId());
        nextOrder.setStandardId(entity.getStandardId());
        nextOrder.setCreationMethod("AUTO");
        // 设置保养日期为原工单保养日期加6个月
        nextOrder.setMaintenanceDate(calculateNextMaintenanceDate(entity.getMaintenanceDate()));
        // 设置技术状态鉴定表HF编码
        EamBaseHFCode eamBaseHFCode = hfCodeService.selectByCategory(HfTemplateCategoryEnum.SECOND_MAINTENANCE.name());
        if (eamBaseHFCode == null) {
            throw new JeecgBootException("未配置技术状态鉴定表的HF编码,添加失败!");
        }
        nextOrder.setHfCode(eamBaseHFCode.getHfCode());
        nextOrder.setRemark(entity.getRemark());
        nextOrder.setMaintenanceStatus(SecondMaintenanceStatusEnum.WAIT_MAINTENANCE.name());
        nextOrder.setCreationMethod(entity.getCreationMethod());
        nextOrder.setDelFlag(CommonConstant.DEL_FLAG_0);
 
        // 插入新工单
        eamSecondMaintenanceOrderMapper.insert(nextOrder);
 
        // 复制工单明细
        List<EamMaintenanceStandardDetail> standardDetails = eamMaintenanceStandardDetailService.selectByStandardId(entity.getStandardId());
        if (CollectionUtil.isEmpty(standardDetails)) {
            log.warn("原工单的保养规范明细为空,工单ID: {}", orderId);
            return;
        }
 
        List<EamSecondMaintenanceOrderDetail> orderDetails = standardDetails.stream()
                .map(item -> {
                    EamSecondMaintenanceOrderDetail detail = new EamSecondMaintenanceOrderDetail();
                    BeanUtils.copyProperties(item, detail);
                    detail.setId(null);
                    detail.setOrderId(nextOrder.getId());
                    return detail;
                })
                .collect(Collectors.toList());
 
        secondMaintenanceOrderDetailService.saveBatch(orderDetails);
 
        // 插入首页二保养计划
        // 使用 SimpleDateFormat 直接格式化为“yyyy年MM月”格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
        String formattedDate = sdf.format(nextOrder.getMaintenanceDate());
        factorySecondMaintPlanService.add(nextOrder.getEquipmentId(), formattedDate);
    }
 
 
    /**
     * 计算六个月后的当月最后一天
     * @param currentDate 当前工单日期
     * @return 六个月后的当月最后一天
     */
    private Date calculateNextMaintenanceDate(Date currentDate) {
        // 转换为LocalDate处理日期
        LocalDate localDate = DateUtils.dateToLocalDate(currentDate);
        // 计算六个月后的日期
        LocalDate sixMonthsLater = localDate.plusMonths(6);
 
        // 调整到当月的最后一天
        LocalDate lastDayOfMonth = sixMonthsLater.with(TemporalAdjusters.lastDayOfMonth());
 
        // 转换回Date类型
        return DateUtils.localDateToDate(lastDayOfMonth);
    }
 
}