刘光辉
15 小时以前 34981c30a78e8bbd7791131059a9210f9928b62c
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
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
package jnpf.limsController;
 
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jnpf.exception.DataException;
import jnpf.limsEntity.LimsShebeiYiqiJiaozhunNeibuParam;
import jnpf.limsEntity.LimsShebeiYiqiJiaozhunWaibuParam;
import jnpf.limsEntity.LimsShebeiYiqiPeijianGenghuanParam;
import jnpf.limsEntity.LimsShebeiYiqiWeibaoParam;
import jnpf.limsService.LimsShebeiYiqiXinxiService;
import jnpf.limsService.LimsShebeiYiqiJiaozhunNeibuService;
import jnpf.limsService.LimsShebeiYiqiJiaozhunWaibuService;
import jnpf.limsService.LimsShebeiYiqiPeijianGenghuanService;
import jnpf.limsService.LimsShebeiYiqiQijuBaofeiService;
import jnpf.limsService.LimsShebeiYiqiWeibaoService;
import jnpf.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import java.lang.reflect.Array;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
@Slf4j
@Tag(name = "lims设备仪器接口", description = "设备仪器业务操作")
@RestController
@RequestMapping("/lims/biz/shebei/yiqi")
public class LimsShebeiYiqiController {
 
    @Autowired
    private LimsShebeiYiqiXinxiService limsShebeiYiqiXinxiService;
 
    @Autowired
    private LimsShebeiYiqiJiaozhunWaibuService limsShebeiYiqiJiaozhunWaibuService;
 
    @Autowired
    private LimsShebeiYiqiJiaozhunNeibuService limsShebeiYiqiJiaozhunNeibuService;
 
    @Autowired
    private LimsShebeiYiqiQijuBaofeiService limsShebeiYiqiQijuBaofeiService;
 
    @Autowired
    private LimsShebeiYiqiWeibaoService limsShebeiYiqiWeibaoService;
 
    @Autowired
    private LimsShebeiYiqiPeijianGenghuanService limsShebeiYiqiPeijianGenghuanService;
 
    /**
     * 仪器报废:按仪器信息 f_id 将 biz_status 更新为 yibaofei。
     */
    @Operation(summary = "仪器报废")
    @PostMapping("/baofei")
    public R<String> baofei(@RequestBody(required = false) Map<String, Object> formData,
                            @RequestParam(value = "yiqi_id", required = false) String yiqiId) {
        String resolvedYiqiId = resolveYiqiId(formData, yiqiId);
        try {
            limsShebeiYiqiXinxiService.baofei(resolvedYiqiId);
            return R.success("报废成功");
        } catch (DataException e) {
            log.warn("仪器报废失败:yiqiId={}, msg={}", resolvedYiqiId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 将外部校准记录同步到关联的计量器具。
     */
    @Operation(summary = "同步外部校准结果")
    @PostMapping("/jiaozhun/waibu")
    public R<String> syncWaibuJiaozhun(@RequestBody LimsShebeiYiqiJiaozhunWaibuParam param) {
        String jiaozhunId = param == null ? "" : param.getJiaozhunId();
        try {
            limsShebeiYiqiJiaozhunWaibuService.syncToQiju(jiaozhunId);
            return R.success("外部校准结果同步成功");
        } catch (DataException e) {
            log.warn("同步外部校准结果失败:jiaozhunId={}, msg={}", jiaozhunId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 将维保记录同步到关联的维保子项。
     */
    @Operation(summary = "同步仪器维保子项")
    @PostMapping("/weibao/sync")
    public R<String> syncWeibao(@RequestBody LimsShebeiYiqiWeibaoParam param) {
        String weibaoId = param == null ? "" : param.getWeibaoId();
        try {
            int count = limsShebeiYiqiWeibaoService.syncToZixiang(weibaoId);
            return R.success("维保子项同步成功,共" + count + "条");
        } catch (DataException e) {
            log.warn("同步仪器维保子项失败:weibaoId={}, msg={}", weibaoId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 将配件更换记录同步到关联的配件更换子项。
     */
    @Operation(summary = "同步仪器配件更换子项")
    @PostMapping("/peijian/genghuan/sync")
    public R<String> syncPeijianGenghuan(@RequestBody LimsShebeiYiqiPeijianGenghuanParam param) {
        String genghuanId = param == null ? "" : param.getGenghuanId();
        try {
            int count = limsShebeiYiqiPeijianGenghuanService.syncToZixiang(genghuanId);
            return R.success("配件更换子项同步成功,共" + count + "条");
        } catch (DataException e) {
            log.warn("同步仪器配件更换子项失败:genghuanId={}, msg={}", genghuanId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 将流程关联的内部校准记录同步到关联的计量器具。
     */
    @Operation(summary = "同步内部校准结果")
    @PostMapping("/jiaozhun/neibu")
    public R<String> syncNeibuJiaozhun(@RequestBody LimsShebeiYiqiJiaozhunNeibuParam param) {
        String flowId = param == null ? "" : param.getFlowId();
        String taskId = param == null ? "" : param.getTaskId();
        try {
            limsShebeiYiqiJiaozhunNeibuService.syncToQiju(flowId, taskId);
            return R.success("内部校准结果同步成功");
        } catch (DataException e) {
            log.warn("同步内部校准结果失败:flowId={}, taskId={}, msg={}", flowId, taskId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 根据流程关联的器具报废申请,将对应计量器具标记为已报废。
     */
    @Operation(summary = "器具报废")
    @PostMapping("/qiju/baofei")
    public R<String> baofeiQiju(@RequestBody(required = false) Map<String, Object> formData,
                                @RequestParam(value = "flow_id", required = false) String flowId,
                                @RequestParam(value = "task_id", required = false) String taskId) {
        String resolvedFlowId = resolveParam(formData, flowId, "flow_id", "flowId");
        String resolvedTaskId = resolveParam(formData, taskId, "task_id", "taskId");
        try {
            limsShebeiYiqiQijuBaofeiService.baofeiQiju(resolvedFlowId, resolvedTaskId);
            return R.success("器具报废成功");
        } catch (DataException e) {
            log.warn("器具报废失败:flowId={}, taskId={}, msg={}",
                    resolvedFlowId, resolvedTaskId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 仪器批量启用:按仪器信息 f_id 批量将 xingneng_zhuangtai 更新为 zhunyong。
     */
    @Operation(summary = "仪器批量启用")
    @PostMapping("/qiyong")
    public R<Map<String, Object>> qiyong(@RequestBody(required = false) Map<String, Object> formData,
                                         @RequestParam(value = "yiqi_ids", required = false) String yiqiIds) {
        List<String> resolvedYiqiIds = resolveYiqiIds(formData, yiqiIds);
        try {
            int count = limsShebeiYiqiXinxiService.qiyong(resolvedYiqiIds);
            Map<String, Object> data = new java.util.HashMap<>(2);
            data.put("yiqi_ids", resolvedYiqiIds);
            data.put("count", count);
            return R.success("启用成功", data);
        } catch (DataException e) {
            log.warn("仪器批量启用失败:yiqiIds={}, msg={}", resolvedYiqiIds, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 校验仪器当天是否已完成校准。
     */
    @Operation(summary = "校验仪器当天校准状态")
    @PostMapping("/jiaoyan/check")
    public R<String> check(@RequestBody(required = false) Map<String, Object> formData,
                           @RequestParam(value = "yiqi_id", required = false) String yiqiId,
                           @RequestParam(value = "jiaoyan_shijian", required = false) String jiaoyanShijian) {
        String resolvedYiqiId = resolveYiqiId(formData, yiqiId);
        try {
            LocalDateTime resolvedJiaoyanShijian = resolveJiaoyanShijian(formData, jiaoyanShijian);
            limsShebeiYiqiXinxiService.checkTodayJiaoyan(resolvedYiqiId, resolvedJiaoyanShijian);
            return R.success("校验通过");
        } catch (DataException e) {
            log.warn("仪器校准校验失败:yiqiId={}, msg={}", resolvedYiqiId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 校验仪器是否满足使用条件。
     */
    @Operation(summary = "校验仪器使用状态")
    @PostMapping("/shiyong/check")
    public R<String> checkShiyong(@RequestBody(required = false) Map<String, Object> formData,
                                  @RequestParam(value = "yiqi_id", required = false) String yiqiId) {
        String resolvedYiqiId = resolveYiqiId(formData, yiqiId);
        try {
            limsShebeiYiqiXinxiService.checkShiyong(resolvedYiqiId);
            return R.success("校验通过");
        } catch (DataException e) {
            log.warn("仪器使用校验失败:yiqiId={}, msg={}", resolvedYiqiId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 确认仪器验证,并将验证结果同步到关联仪器信息。
     */
    @Operation(summary = "确认仪器验证")
    @PostMapping("/yanzheng/confirm")
    public R<String> confirmYanzheng(@RequestBody(required = false) Map<String, Object> formData) {
        String yanzhengId = resolveParam(formData, null, "yanzheng_id", "yanzhengId");
        try {
            limsShebeiYiqiXinxiService.confirmYanzheng(yanzhengId);
            return R.success("仪器验证确认成功");
        } catch (DataException e) {
            log.warn("确认仪器验证失败:yanzhengId={}, msg={}", yanzhengId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    /**
     * 确认仪器计量,并将计量结果同步到关联仪器信息。
     */
    @Operation(summary = "确认仪器计量")
    @PostMapping("/jiliang/confirm")
    public R<String> confirmJiliang(@RequestBody(required = false) Map<String, Object> formData) {
        String jiliangId = resolveParam(formData, null, "jiliang_id", "jiliangId");
        try {
            limsShebeiYiqiXinxiService.confirmJiliang(jiliangId);
            return R.success("仪器计量确认成功");
        } catch (DataException e) {
            log.warn("确认仪器计量失败:jiliangId={}, msg={}", jiliangId, e.getMessage());
            return R.error(e.getMessage());
        }
    }
 
    private String resolveYiqiId(Map<String, Object> formData, String yiqiId) {
        String value = trimToEmpty(yiqiId);
        if (!value.isEmpty()) {
            return value;
        }
        if (formData == null) {
            return "";
        }
        Object raw = formData.get("yiqi_id");
        if (raw == null) {
            raw = formData.get("yiqiId");
        }
        return raw == null ? "" : trimToEmpty(String.valueOf(raw));
    }
 
    private String resolveParam(Map<String, Object> formData, String requestParam,
                                String snakeCaseKey, String camelCaseKey) {
        String value = trimToEmpty(requestParam);
        if (!value.isEmpty() || formData == null) {
            return value;
        }
        Object raw = formData.get(snakeCaseKey);
        if (raw == null) {
            raw = formData.get(camelCaseKey);
        }
        return raw == null ? "" : trimToEmpty(String.valueOf(raw));
    }
 
    private LocalDateTime resolveJiaoyanShijian(Map<String, Object> formData, String jiaoyanShijian) throws DataException {
        Object raw = trimToEmpty(jiaoyanShijian);
        if (raw.toString().isEmpty() && formData != null) {
            raw = formData.get("jiaoyan_shijian");
            if (raw == null) {
                raw = formData.get("jiaoyanShijian");
            }
        }
        if (raw == null || trimToEmpty(String.valueOf(raw)).isEmpty()) {
            throw new DataException("校准时间(jiaoyan_shijian)不能为空");
        }
 
        String value = trimToEmpty(String.valueOf(raw));
        try {
            if (value.matches("^-?\\d{1,17}$")) {
                return LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(value)), ZoneId.systemDefault());
            }
            if (value.length() == 10) {
                return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay();
            }
            try {
                return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
            } catch (DateTimeParseException ignored) {
                return LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        } catch (DateTimeParseException | NumberFormatException e) {
            throw new DataException("校准时间(jiaoyan_shijian)格式不正确");
        }
    }
 
    private List<String> resolveYiqiIds(Map<String, Object> formData, String yiqiIds) {
        Set<String> ids = new LinkedHashSet<>();
        addIds(ids, yiqiIds);
        if (formData != null) {
            Object raw = formData.get("yiqi_ids");
            if (raw == null) {
                raw = formData.get("yiqiIds");
            }
            addIds(ids, raw);
        }
        return new ArrayList<>(ids);
    }
 
    private void addIds(Set<String> ids, Object raw) {
        if (raw == null) {
            return;
        }
        if (raw instanceof Iterable) {
            for (Object item : (Iterable<?>) raw) {
                addIds(ids, item);
            }
            return;
        }
        if (raw.getClass().isArray()) {
            int length = Array.getLength(raw);
            for (int i = 0; i < length; i++) {
                addIds(ids, Array.get(raw, i));
            }
            return;
        }
        String value = trimToEmpty(String.valueOf(raw));
        if (value.isEmpty()) {
            return;
        }
        String[] splitIds = value.split(",");
        for (String splitId : splitIds) {
            String id = trimToEmpty(splitId);
            if (!id.isEmpty()) {
                ids.add(id);
            }
        }
    }
 
    private String trimToEmpty(String value) {
        return value == null ? "" : value.trim();
    }
}