huang
11 小时以前 04914a9997afbbead6f8adbb9d9c40e05b2edbd1
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package com.mes.device.controller;
 
import com.mes.device.entity.EngineeringSequence;
import com.mes.device.entity.GlassInfo;
import com.mes.device.service.EngineeringSequenceService;
import com.mes.device.service.GlassInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
 
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * @author :huang
 * @date :2025-12-08
 * 工程导入转发接口(接收前端 Excel 行数据,后端组装后转发 MES)
 */
@Slf4j
@RestController
@RequestMapping("excel")
@RequiredArgsConstructor
public class GlassInfoImportController {
 
    private final GlassInfoService glassInfoService;
    private final EngineeringSequenceService engineeringSequenceService;
    private final RestTemplate restTemplate = new RestTemplate();
 
 
    /**
     * 导入工程
     * 前端入参示例:
     * {
     *   "excelRows": [
     *     {"glassId":"GL001","width":"1000","height":"2000","thickness":"5","quantity":"2","flowCardId":"NG25082101","filmsId":"白玻"}
     *   ]
     * }
     */
    @PostMapping("/importExcel")
    public ResponseEntity<?> importEngineer(@RequestBody Map<String, Object> body) {
        // 初始化返回结果和关键标记
        Map<String, Object> errorResponse = new HashMap<>();
        boolean mesSuccess = false;
        String engineeringId = null;
        // 1. 校验
        Object rowsObj = body.get("excelRows");
        if (!(rowsObj instanceof List)) {
            return ResponseEntity.badRequest().body("excelRows 必须是数组");
        }
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> excelRows = (List<Map<String, Object>>) rowsObj;
        if (CollectionUtils.isEmpty(excelRows)) {
            return ResponseEntity.badRequest().body("excelRows 不能为空");
        }
 
         try {
            // 2. 构建MES导入数据
            Map<String, Object> payload = glassInfoService.buildEngineerImportPayload(excelRows);
            log.info("构建的 MES 导入数据: {}", payload);
 
            // 3. 提取工程号
            engineeringId = (String) payload.get("engineerId");
            if (engineeringId == null || engineeringId.isEmpty()) {
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> glassInfoList = (List<Map<String, Object>>) payload.get("glassInfolList");
                if (glassInfoList != null && !glassInfoList.isEmpty()) {
                    Object firstEngineerId = glassInfoList.get(0).get("engineerId");
                    if (firstEngineerId != null) {
                        engineeringId = firstEngineerId.toString();
                    }
                }
            }
 
          // 4. 调用MES接口
            String mesEngineeringImportUrl = glassInfoService.getMesEngineeringImportUrl();
            ResponseEntity<Map> mesResp = restTemplate.postForEntity(mesEngineeringImportUrl, payload, Map.class);
            Map<String, Object> mesBody = mesResp.getBody();
 
            // 5. 检查MES响应是否真正成功(优化后的判断逻辑,增加异常捕获)
            if (mesResp.getStatusCode().is2xxSuccessful() && mesBody != null) {
                Object codeObj = mesBody.get("code");
                if (codeObj != null) {
                    try {
                        // 安全转换code为整数,避免类型转换异常
                        int code = codeObj instanceof Number ? ((Number) codeObj).intValue() :
                                Integer.parseInt(String.valueOf(codeObj).trim());
                        // MES成功通常返回code=200或0
                        mesSuccess = (code == 200 || code == 0);
                    } catch (NumberFormatException e) {
                        log.warn("MES响应code字段不是有效数字:{}", codeObj, e);
                    }
                } else {
                    // 没有code字段,认为HTTP 2xx就是成功
                    mesSuccess = true;
                }
            } else {
                // HTTP状态码不是2xx或响应体为空,设为失败
                mesSuccess = false;
                log.warn("MES接口返回非2xx状态码或空响应体,状态码:{}", mesResp.getStatusCode());
            }
 
            // 6. 只有MES导入真正成功且工程号不为空时,才保存到本地数据库
            if (mesSuccess && engineeringId != null && !engineeringId.isEmpty()) {
                // 先保存工程号
                engineeringSequenceService.saveEngineeringId(new Date(), engineeringId);
                // 再保存玻璃信息
                glassInfoService.saveGlassInfosFromExcel(excelRows, engineeringId);
                log.info("MES导入成功,已保存工程号和玻璃信息到本地数据库,工程号: {}", engineeringId);
            } else {
                log.warn("MES导入未成功,不保存工程号和玻璃信息到本地数据库: engineeringId={}, mesSuccess={}", engineeringId, mesSuccess);
            }
 
            // 7. 返回MES的响应
            return ResponseEntity.status(mesResp.getStatusCode()).body(mesBody);
        } catch (org.springframework.web.client.ResourceAccessException e) {
            // 连接超时或无法连接
            log.error("转发 MES 导入接口失败(连接问题) url={}, error={}", glassInfoService.getMesEngineeringImportUrl(), e.getMessage(), e);
            errorResponse.put("code", 500);
            errorResponse.put("message", "无法连接到 MES 接口,请检查网络连接或联系管理员");
            errorResponse.put("data", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        } catch (Exception e) {
            // 其他异常
            log.error("转发 MES 导入接口失败 url={}, error={}", glassInfoService.getMesEngineeringImportUrl(), e.getMessage(), e);
            errorResponse.put("code", 500);
            errorResponse.put("message", "转发 MES 失败: " + e.getMessage());
            errorResponse.put("data", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
 
    /**
     * 查询所有工程号列表
     */
    @GetMapping("/engineering/list")
    public ResponseEntity<?> getEngineeringList() {
        try {
            List<EngineeringSequence> list = engineeringSequenceService.list();
            List<Map<String, Object>> result = list.stream()
                    .map(seq -> {
                        Map<String, Object> map = new LinkedHashMap<>();
                        map.put("engineeringId", seq.getEngineeringId());
                        map.put("date", seq.getDate());
                        map.put("sequence", seq.getSequence());
                        return map;
                    })
                    .sorted(Comparator.comparing(
                            (Map<String, Object> map) -> (Date) map.get("date"),
                            Comparator.nullsLast(Comparator.reverseOrder())
                    ).thenComparing(
                            map -> (Integer) map.get("sequence"),
                            Comparator.nullsLast(Comparator.reverseOrder())
                    ))
                    .collect(Collectors.toList());
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("查询工程号列表失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 500);
            errorResponse.put("message", "查询工程号列表失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
 
    /**
     * 根据工程号查询对应的玻璃ID列表
     */
    @GetMapping("/engineering/{engineeringId}/glassIds")
    public ResponseEntity<?> getGlassIdsByEngineeringId(@PathVariable String engineeringId) {
        try {
            List<GlassInfo> glassInfos = glassInfoService.getGlassInfosByEngineeringId(engineeringId);
            List<String> glassIds = glassInfos.stream()
                    .map(GlassInfo::getGlassId)
                    .filter(id -> id != null && !id.trim().isEmpty())
                    .collect(Collectors.toList());
            
            Map<String, Object> result = new HashMap<>();
            result.put("engineeringId", engineeringId);
            result.put("glassIds", glassIds);
            result.put("count", glassIds.size());
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("根据工程号查询玻璃ID列表失败: engineeringId={}", engineeringId, e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 500);
            errorResponse.put("message", "查询玻璃ID列表失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
 
    /**
     * 删除工程号及其关联的玻璃信息
     */
    @DeleteMapping("/engineering/{engineeringId}")
    public ResponseEntity<?> deleteEngineering(@PathVariable String engineeringId) {
        try {
            // 1. 删除glass_info表中对应工程号的玻璃信息
            int deletedGlassCount = glassInfoService.deleteGlassInfosByEngineeringId(engineeringId);
            
            // 2. 删除engineering_sequence表中的工程号记录(逻辑删除)
            EngineeringSequence sequence = engineeringSequenceService.getOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<EngineeringSequence>()
                    .eq(EngineeringSequence::getEngineeringId, engineeringId)
                    .eq(EngineeringSequence::getIsDeleted, 0) // 只查询未删除的记录
                    .last("LIMIT 1")
            );
            
            boolean deletedSequence = false;
            if (sequence != null) {
                // removeById 会自动使用逻辑删除(因为实体类有 @TableLogic 注解)
                deletedSequence = engineeringSequenceService.removeById(sequence.getId());
                log.info("已删除工程号记录: engineeringId={}, sequenceId={}", engineeringId, sequence.getId());
            } else {
                log.warn("未找到工程号记录: engineeringId={}", engineeringId);
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("engineeringId", engineeringId);
            result.put("deletedGlassCount", deletedGlassCount);
            result.put("deletedSequence", deletedSequence);
            result.put("success", true);
            result.put("message", String.format("已删除工程号 %s,共删除 %d 条玻璃信息", engineeringId, deletedGlassCount));
            
            log.info("删除工程号成功: engineeringId={}, deletedGlassCount={}, deletedSequence={}", 
                    engineeringId, deletedGlassCount, deletedSequence);
            
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("删除工程号失败: engineeringId={}", engineeringId, e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("code", 500);
            errorResponse.put("message", "删除工程号失败: " + e.getMessage());
            errorResponse.put("success", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
        }
    }
}