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 baofei(@RequestBody(required = false) Map 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 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 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 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 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 baofeiQiju(@RequestBody(required = false) Map 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> qiyong(@RequestBody(required = false) Map formData, @RequestParam(value = "yiqi_ids", required = false) String yiqiIds) { List resolvedYiqiIds = resolveYiqiIds(formData, yiqiIds); try { int count = limsShebeiYiqiXinxiService.qiyong(resolvedYiqiIds); Map 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 check(@RequestBody(required = false) Map 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 checkShiyong(@RequestBody(required = false) Map 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 confirmYanzheng(@RequestBody(required = false) Map 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 confirmJiliang(@RequestBody(required = false) Map 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 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 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 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 resolveYiqiIds(Map formData, String yiqiIds) { Set 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 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(); } }