package com.ruoyi.basic.service.impl; import cn.hutool.json.JSONUtil; import cn.hutool.poi.excel.ExcelUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.pojo.StandardMethodList; import com.ruoyi.common.utils.QueryWrappers; import com.ruoyi.basic.mapper.StandardMethodMapper; import com.ruoyi.basic.mapper.StandardProductListMapper; import com.ruoyi.basic.mapper.StructureItemParameterMapper; import com.ruoyi.basic.mapper.StandardMethodIndustryMapper; import com.ruoyi.basic.mapper.StandardMethodAttachmentMapper; import com.ruoyi.basic.mapper.LaboratoryMapper; import com.ruoyi.basic.mapper.StandardTreeMapper; import com.ruoyi.basic.mapper.StandardTreeTemplateBindingMapper; import com.ruoyi.basic.pojo.StandardMethod; import com.ruoyi.basic.pojo.StandardMethodIndustry; import com.ruoyi.basic.pojo.StandardMethodAttachment; import com.ruoyi.basic.pojo.Laboratory; import com.ruoyi.basic.pojo.StandardTree; import com.ruoyi.basic.pojo.StandardTreeTemplateBinding; import com.ruoyi.basic.pojo.StandardProductList; import com.ruoyi.basic.pojo.StructureItemParameter; import com.ruoyi.basic.service.StandardMethodService; import com.ruoyi.basic.service.StandardProductListService; import com.ruoyi.basic.service.StructureItemParameterService; import com.ruoyi.basic.utils.StandardTreePath; import com.ruoyi.basic.utils.StandardTreePathParser; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import com.ruoyi.common.exception.base.BaseException; import java.io.File; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; /** * @author Administrator * @description 针对表【standard_method(标准方法)】的数据库操作Service实现 * @createDate 2024-03-03 19:21:41 */ @Service public class StandardMethodServiceImpl extends ServiceImpl implements StandardMethodService { private StandardMethodMapper standardMethodMapper; private StandardProductListMapper standardProductListMapper; private StandardProductListService standardProductListService; private StructureItemParameterMapper structureItemParameterMapper; private StructureItemParameterService structureItemParameterService; private StandardMethodIndustryMapper standardMethodIndustryMapper; private StandardMethodAttachmentMapper standardMethodAttachmentMapper; private LaboratoryMapper laboratoryMapper; private StandardTreeMapper standardTreeMapper; private StandardTreeTemplateBindingMapper standardTreeTemplateBindingMapper; @Value("${file.path}") private String filePath; @Value("${wordUrl}") private String wordUrl; /** * 业务依赖由构造器注入;文件路径由 @Value 从配置读取,不能参与 Lombok 的全参构造器, * 否则 Spring 会把 String 误认为需要注入的 Bean。 */ public StandardMethodServiceImpl(StandardMethodMapper standardMethodMapper, StandardProductListMapper standardProductListMapper, StandardProductListService standardProductListService, StructureItemParameterMapper structureItemParameterMapper, StructureItemParameterService structureItemParameterService, StandardMethodIndustryMapper standardMethodIndustryMapper, StandardMethodAttachmentMapper standardMethodAttachmentMapper, LaboratoryMapper laboratoryMapper, StandardTreeMapper standardTreeMapper, StandardTreeTemplateBindingMapper standardTreeTemplateBindingMapper) { this.standardMethodMapper = standardMethodMapper; this.standardProductListMapper = standardProductListMapper; this.standardProductListService = standardProductListService; this.structureItemParameterMapper = structureItemParameterMapper; this.structureItemParameterService = structureItemParameterService; this.standardMethodIndustryMapper = standardMethodIndustryMapper; this.standardMethodAttachmentMapper = standardMethodAttachmentMapper; this.laboratoryMapper = laboratoryMapper; this.standardTreeMapper = standardTreeMapper; this.standardTreeTemplateBindingMapper = standardTreeTemplateBindingMapper; } @Override public IPage selectStandardMethodList(Page page, StandardMethod standardMethod) { IPage result = standardMethodMapper.selectStandardMethodList(page, QueryWrappers.queryWrappers(standardMethod)); for (StandardMethod method : result.getRecords()) { method.setIndustryIds(selectIndustryIds(method.getId())); } return result; } @Override public List selectStandardMethods() { return standardMethodMapper.selectList(Wrappers.lambdaQuery().select(StandardMethod::getId, StandardMethod::getCode, StandardMethod::getName).ne(StandardMethod::getId, 0)); } @Override @Transactional(rollbackFor = Exception.class) public Integer addStandardMethod(StandardMethod standardMethod) { standardMethod.setStructureTestObjectId(null); standardMethodMapper.insert(standardMethod); syncIndustries(standardMethod, Collections.emptySet()); return standardMethod.getId(); } @Override @Transactional(rollbackFor = Exception.class) public int delStandardMethod(Integer id) { StandardMethod method = standardMethodMapper.selectById(id); if (method == null) { throw new BaseException("标准不存在"); } for (Integer industryId : selectIndustryIds(id)) { removeIndustryTree(method, industryId); } standardMethodIndustryMapper.delete(Wrappers.lambdaQuery() .eq(StandardMethodIndustry::getStandardMethodId, id)); standardMethodAttachmentMapper.delete(Wrappers.lambdaQuery() .eq(StandardMethodAttachment::getStandardMethodId, id)); return standardMethodMapper.deleteById(id); } @Override @Transactional(rollbackFor = Exception.class) public int upStandardMethod(StandardMethod standardMethod) { StandardMethod oldStandardMethod = standardMethodMapper.selectById(standardMethod.getId()); if (oldStandardMethod == null) { throw new BaseException("标准不存在"); } if (!oldStandardMethod.getCode().equals(standardMethod.getCode())) { CompletableFuture.supplyAsync(() -> replaceMethod(oldStandardMethod.getCode(), standardMethod.getCode())); } int i = standardMethodMapper.updateById(standardMethod); syncIndustries(standardMethod, new LinkedHashSet<>(selectIndustryIds(oldStandardMethod.getId()))); return i; } private List selectIndustryIds(Integer methodId) { List list = standardMethodIndustryMapper.selectList( Wrappers.lambdaQuery() .eq(StandardMethodIndustry::getStandardMethodId, methodId)); List ids = new ArrayList<>(); for (StandardMethodIndustry item : list) { ids.add(item.getIndustryId()); } return ids; } private void syncIndustries(StandardMethod method, Set oldIds) { Set newIds = method.getIndustryIds() == null ? new LinkedHashSet() : new LinkedHashSet<>(method.getIndustryIds()); for (Integer industryId : newIds) { if (industryId == null || laboratoryMapper.selectById(industryId) == null) { throw new BaseException("行业不存在"); } } for (Integer oldId : oldIds) { if (!newIds.contains(oldId)) { removeIndustryTree(method, oldId); standardMethodIndustryMapper.delete(Wrappers.lambdaQuery() .eq(StandardMethodIndustry::getStandardMethodId, method.getId()) .eq(StandardMethodIndustry::getIndustryId, oldId)); } } for (Integer industryId : newIds) { Laboratory lab = laboratoryMapper.selectById(industryId); Long count = standardMethodIndustryMapper.selectCount(Wrappers.lambdaQuery() .eq(StandardMethodIndustry::getStandardMethodId, method.getId()) .eq(StandardMethodIndustry::getIndustryId, industryId)); if (count == 0) { StandardMethodIndustry relation = new StandardMethodIndustry(); relation.setStandardMethodId(method.getId()); relation.setIndustryId(industryId); standardMethodIndustryMapper.insert(relation); } StandardTree tree = standardTreeMapper.selectOne(Wrappers.lambdaQuery() .eq(StandardTree::getLaboratory, lab.getLaboratoryName()) .eq(StandardTree::getStandardMethodId, method.getId()) .isNull(StandardTree::getSampleType).isNull(StandardTree::getModel)); if (tree == null) { tree = new StandardTree(); tree.setLaboratory(lab.getLaboratoryName()); tree.setSample(buildLabel(method)); tree.setStandardMethodId(method.getId()); tree.setSort(0); standardTreeMapper.insert(tree); } else if (!buildLabel(method).equals(tree.getSample())) { StandardTree update = new StandardTree(); update.setId(tree.getId()); update.setSample(buildLabel(method)); standardTreeMapper.updateById(update); } } } private void removeIndustryTree(StandardMethod method, Integer industryId) { Laboratory lab = laboratoryMapper.selectById(industryId); if (lab == null) return; StandardTree tree = standardTreeMapper.selectOne(Wrappers.lambdaQuery() .eq(StandardTree::getLaboratory, lab.getLaboratoryName()) .eq(StandardTree::getStandardMethodId, method.getId()) .isNull(StandardTree::getSampleType).isNull(StandardTree::getModel)); if (tree != null) { standardTreeTemplateBindingMapper.delete(Wrappers.lambdaQuery() .eq(StandardTreeTemplateBinding::getStandardTreeId, tree.getId())); standardProductListMapper.delete(Wrappers.lambdaQuery() .eq(StandardProductList::getLaboratory, lab.getLaboratoryName()) .eq(StandardProductList::getSample, tree.getSample()) .isNull(StandardProductList::getSampleType).isNull(StandardProductList::getModel)); standardTreeMapper.deleteById(tree.getId()); } } private String buildLabel(StandardMethod method) { return method.getCode().trim(); } @Override public List selectAttachments(Integer standardMethodId) { return standardMethodAttachmentMapper.selectList(Wrappers.lambdaQuery() .eq(StandardMethodAttachment::getStandardMethodId, standardMethodId) .orderByAsc(StandardMethodAttachment::getSort, StandardMethodAttachment::getId)); } @Override public StandardMethodAttachment uploadAttachment(Integer standardMethodId, MultipartFile file) { if (standardMethodMapper.selectById(standardMethodId) == null) throw new BaseException("标准不存在"); if (file == null || file.isEmpty() || file.getSize() > 10 * 1024 * 1024) throw new BaseException("附件不能为空且不能超过10MB"); String originalName = file.getOriginalFilename(); if (originalName == null || !originalName.matches("(?i).+\\.(jpg|jpeg|png|gif|doc|docx|xls|xlsx|ppt|pptx|pdf|zip|rar)$")) throw new BaseException("不支持的附件格式"); try { boolean image = originalName.matches("(?i).+\\.(jpg|jpeg|png|gif)$"); File directory = new File(image ? filePath : wordUrl); if (!directory.exists()) directory.mkdirs(); String fileUrl = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmssSSS")) + "-" + originalName; file.transferTo(new File(directory, fileUrl)); StandardMethodAttachment attachment = new StandardMethodAttachment(); attachment.setStandardMethodId(standardMethodId); attachment.setFileName(originalName); attachment.setFileUrl(fileUrl); attachment.setSort(selectAttachments(standardMethodId).size()); standardMethodAttachmentMapper.insert(attachment); return attachment; } catch (IOException e) { throw new BaseException("附件上传失败"); } } @Override public boolean deleteAttachment(Long id) { return standardMethodAttachmentMapper.deleteById(id) > 0; } @Override public List selectIndustryOptions() { return laboratoryMapper.selectList(Wrappers.lambdaQuery() .select(Laboratory::getId, Laboratory::getLaboratoryName, Laboratory::getSort) .orderByAsc(Laboratory::getSort, Laboratory::getId)); } //编辑method后全部替换 public String replaceMethod(String oldCode, String code) { //查询StandardProductList中所有Method如果包含之前的则替换 List standardProductLists = standardProductListMapper.selectList(null); for (StandardProductList standardProductList : standardProductLists) { if (standardProductList.getMethod().contains(oldCode)) { String[] split = standardProductList.getMethod().split(","); String a = null; for (int i = 0; i < split.length; i++) { String methodName = split[i].substring(1, split[i].length() - 1); if (i == 0) { methodName = split[i].substring(2, split[i].length() - 1); } else if (i == split.length - 1) { methodName = split[i].substring(1, split[i].length() - 2); } if (methodName.equals(oldCode)) { methodName = code; } a += "\"" + methodName + "\","; } String method = "[\"" + a.substring(0, a.length() - 1) + "\"]"; standardProductList.setMethod(method); } } standardProductListService.updateBatchById(standardProductLists); //查询StructureItemParameter中所有Method如果包含之前的则替换 List structureItemParameters = structureItemParameterMapper.selectList(null); for (StructureItemParameter structureItemParameter : structureItemParameters) { if (structureItemParameter.getMethod().contains(oldCode)) { String[] split = structureItemParameter.getMethod().split(","); String a = null; for (int i = 0; i < split.length; i++) { String methodName = split[i].substring(1, split[i].length() - 1); if (i == 0) { methodName = split[i].substring(2, split[i].length() - 1); } else if (i == split.length - 1) { methodName = split[i].substring(1, split[i].length() - 2); } if (methodName.equals(oldCode)) { methodName = code; } a += "\"" + methodName + "\","; } String method = "[\"" + a.substring(0, a.length() - 1) + "\"]"; structureItemParameter.setMethod(method); } } structureItemParameterService.updateBatchById(structureItemParameters); return "替换完毕!"; } // 格式化数据 public StandardMethod formatData(List list) { StandardMethod standardMethod = new StandardMethod(); standardMethod.setField(list.get(1).toString()); // 造格式 List> structureTestObjectId = new ArrayList<>(); if (ObjectUtils.isEmpty(list.get(3))) { structureTestObjectId.add(Arrays.asList(list.get(2))); } else { structureTestObjectId.add(Arrays.asList(list.get(2), list.get(3))); } standardMethod.setStructureTestObjectId(JSONUtil.toJsonStr(structureTestObjectId)); standardMethod.setCode(list.get(4).toString()); standardMethod.setName(list.get(5).toString()); standardMethod.setNameEn(list.get(6).toString()); if (!Objects.equals(list.get(7), null)) { standardMethod.setRemark(list.get(7).toString()); } standardMethod.setQualificationId(list.get(8).toString()); if (ObjectUtils.isNotEmpty(list.get(9))) { if (list.get(9).equals("是")) { standardMethod.setIsProduct(1); } else if (list.get(9).equals("否")) { standardMethod.setIsProduct(0); } } if (ObjectUtils.isNotEmpty(list.get(10))) { if (list.get(10).equals("是")) { standardMethod.setIsUse(1); } else if (list.get(9).equals("否")) { standardMethod.setIsUse(0); } } return standardMethod; } @Override public Map> selectsStandardMethodByFLSSM(String tree) { if (tree == null || tree.trim().isEmpty()) { return Collections.emptyMap(); } StandardTreePath path = StandardTreePathParser.parse(tree); String industry = path.getIndustry(); List standardMethodLists = new ArrayList<>(standardMethodMapper.selectStandardMethodListsByIndustry(industry)); // 按 ID 去重,保持稳定排序 Map byId = new LinkedHashMap<>(); for (StandardMethodList m : standardMethodLists) { byId.putIfAbsent(m.getId(), m); } Map> map = new HashMap<>(); map.put("standardMethodList", new ArrayList<>(byId.values())); return map; } @Override public List selectStandardMethodEnum() { return standardMethodMapper.selectListEnum(); } }