package com.glxp.api.service.collect; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.XmlUtil; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; import com.glxp.api.common.res.BaseResponse; import com.glxp.api.dao.basic.BasicProductsDao; import com.glxp.api.dao.collect.RelCodeBatchMapper; import com.glxp.api.dao.inout.IoCodeTempDao; import com.glxp.api.entity.auth.AuthAdmin; import com.glxp.api.entity.basic.ProductInfoEntity; import com.glxp.api.entity.basic.UdiEntity; import com.glxp.api.entity.basic.UdiProductEntity; import com.glxp.api.entity.collect.RelCodeBatch; import com.glxp.api.entity.collect.RelCodeDetail; import com.glxp.api.entity.inout.IoCodeTempEntity; import com.glxp.api.exception.JsonException; import com.glxp.api.req.collect.RelCodeBatchRequest; import com.glxp.api.req.collect.RelCodeDetailRequest; import com.glxp.api.res.collect.RelCodeBatchResponse; import com.glxp.api.res.collect.RelCodeDetailByParentCodeResponse; import com.glxp.api.service.auth.CustomerService; import com.glxp.api.service.basic.ProductInfoService; import com.glxp.api.service.basic.UdiProductService; import com.glxp.api.util.HttpClient; import com.glxp.api.util.udi.FilterUdiUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; 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 org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @Service @Slf4j public class RelCodeBatchService extends ServiceImpl { @Resource private RelCodeDetailService relCodeDetailService; @Resource private CustomerService customerService; @Resource private ProductInfoService productInfoService; /** * 上传保存关联信息 * * @param file */ @Transactional(rollbackFor = Exception.class) public void xmlUpload(MultipartFile file) { try { String fileName = file.getOriginalFilename(); String suffix = FileUtil.getSuffix(fileName); if (!"xml".equals(suffix)) { throw new JsonException("仅支持XML,文件类型错误" + suffix); } log.info(file.getSize() + "文件长度"); if (file.getSize() > 5 * 1024 * 1024) { throw new JsonException("上传文件超过5M"); } Document document = XmlUtil.readXML(file.getInputStream()); //获取根 Element rootElement = XmlUtil.getRootElement(document); this.ProcessData(rootElement); } catch (Exception e) { throw new JsonException("上传失败:" + e.getMessage()); } } /** * 手动添加 * * @param relCodeBatchRequest */ @Transactional(rollbackFor = Exception.class) public void add(RelCodeBatchRequest relCodeBatchRequest) { List detailList = relCodeBatchRequest.getDetailList(); if (CollUtil.isEmpty(detailList)) { throw new JsonException("关联明细不能为空!"); } AuthAdmin user = customerService.getUserBean(); RelCodeDetailRequest relCodeDetailRequest = detailList.get(0); RelCodeBatch relCodeBatch = new RelCodeBatch(); BeanUtils.copyProperties(relCodeBatchRequest, relCodeBatch); relCodeBatch.setCreateTime(new Date()); relCodeBatch.setCreateUser(user.getUserName()); relCodeBatch.setUpdateTime(new Date()); relCodeBatch.setUpdateUser(user.getUserName()); //添加供应商id name String customerId = user.getCustomerId(); relCodeBatch.setErpId(customerId); relCodeBatch.setCurCode(relCodeDetailRequest.getParentCode()); this.save(relCodeBatch); List relCodeDetails = new ArrayList<>(); for (RelCodeDetailRequest request : detailList) { RelCodeDetail relCodeDetail = new RelCodeDetail(); String parentCode = request.getParentCode(); request.setParentCode(StrUtil.isNotBlank(parentCode) ? parentCode : "0"); BeanUtils.copyProperties(request, relCodeDetail); relCodeDetail.setBatchIdFk(relCodeBatch.getId()); relCodeDetails.add(relCodeDetail); } relCodeDetailService.saveBatch(relCodeDetails); this.updateDrugLevelCount(relCodeBatch); } public List filterList(RelCodeBatchRequest relCodeBatchRequest) { if (relCodeBatchRequest == null) { return Collections.emptyList(); } if (relCodeBatchRequest.getPage() != null) { int offset = (relCodeBatchRequest.getPage() - 1) * relCodeBatchRequest.getLimit(); PageHelper.offsetPage(offset, relCodeBatchRequest.getLimit()); } return this.baseMapper.filterList(relCodeBatchRequest); } @Transactional(rollbackFor = Exception.class) public void delete(Long id) { if (id == null) { throw new JsonException("id 不能为空"); } relCodeDetailService.remove(new LambdaQueryWrapper().eq(RelCodeDetail::getBatchIdFk, id)); this.removeById(id); } @Transactional(rollbackFor = Exception.class) public void addRelCodeSpellBox(List relCodeBatchRequests) { if (CollUtil.isEmpty(relCodeBatchRequests)) { throw new JsonException("单据信息异常!"); } relCodeBatchRequests.forEach(item -> { this.add(item); }); } @Transactional(rollbackFor = Exception.class) public void deleteDetail(String curCode) { List list = relCodeDetailService.list(new LambdaQueryWrapper().eq(RelCodeDetail::getParentCode, curCode)); if (CollUtil.isNotEmpty(list)) { List batchIds = list.stream().map(RelCodeDetail::getBatchIdFk).collect(Collectors.toList()); this.removeBatchByIds(batchIds); relCodeDetailService.remove(new LambdaQueryWrapper().in(RelCodeDetail::getBatchIdFk, batchIds)); } } @Transactional(rollbackFor = Exception.class) public void deleteAllDetail(List detailList) { if (CollUtil.isNotEmpty(detailList)) { detailList.forEach(item -> { String curCode = item.getCurCode(); this.deleteDetail(curCode); }); } } @Value("${UDI_SERVER_URL}") private String udiUrl; /** * 单条上传至国家同步库 */ @Transactional(rollbackFor = Exception.class) public boolean uploadDrugDataOne(RelCodeBatchRequest relCodeBatchRequest) { String json = JSONObject.toJSONString(relCodeBatchRequest); String response = HttpClient.uCloudPost(udiUrl + "/udiwms/relCode/batch/add", json); try { BaseResponse baseResponse = JSONObject.parseObject(response, new TypeReference>() { }); if (baseResponse.getCode() == 20000) { Integer id = relCodeBatchRequest.getId(); return this.update(new LambdaUpdateWrapper().set(RelCodeBatch::getUploadFlagUp, 1).eq(RelCodeBatch::getId, id)); } else { Integer id = relCodeBatchRequest.getId(); this.update(new LambdaUpdateWrapper().set(RelCodeBatch::getUploadFlagUp, 2).eq(RelCodeBatch::getId, id)); return false; } } catch (Exception e) { e.printStackTrace(); return false; } } /** * 层级编码查询国家同步库 */ public List detailByParentCode(String parentCode) { Map paramMap = new HashMap<>(2); paramMap.put("parentCode", parentCode); String response = HttpClient.mipsGet(udiUrl + "/udiwms/relCode/detailByParentCode", paramMap); try { BaseResponse> baseResponse = JSONObject.parseObject(response, new TypeReference>>() { }); if (baseResponse.getCode() == 20000) { List list = baseResponse.getData(); return list; } else { return null; } } catch (Exception e) { e.printStackTrace(); return null; } } /** * 通过 parentCode 拉取国家同步库进行更新 */ public boolean UpdateDetailByParentCode(String parentCode, Integer uploadFlagDown) { List list = this.detailByParentCode(parentCode); if (CollUtil.isNotEmpty(list)) { for (int i = 0; i < list.size(); i++) { try { RelCodeDetailByParentCodeResponse relCodeDetailByParentCodeResponse = list.get(i); this.saveDetailByParentCode(relCodeDetailByParentCodeResponse, uploadFlagDown); List relCodeDetailSons = relCodeDetailByParentCodeResponse.getRelCodeDetailSons(); if (CollUtil.isNotEmpty(relCodeDetailSons)) { this.saveDetailByParentCode(relCodeDetailByParentCodeResponse, uploadFlagDown); } } catch (Exception e) { log.error("拉取国家同步库进行更新失败:[" + parentCode + "]"); log.error(e.getMessage(), e); } } return true; } else return false; } public void saveDetailByParentCode(RelCodeDetailByParentCodeResponse relCodeDetailByParentCodeResponse, Integer uploadFlagDown) { String productCode = relCodeDetailByParentCodeResponse.getProductCode(); String subTypeNo = relCodeDetailByParentCodeResponse.getSubTypeNo(); String batchNo = relCodeDetailByParentCodeResponse.getBatchNo(); String parentCode1 = relCodeDetailByParentCodeResponse.getParentCode(); //如果不存在就添加 List navList = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getProductCode, productCode) .eq(StrUtil.isNotBlank(subTypeNo), RelCodeBatch::getSubTypeNo, subTypeNo) .eq(RelCodeBatch::getBatchNo, batchNo) .eq(RelCodeBatch::getParentCode, parentCode1)); if (CollUtil.isEmpty(navList)) { RelCodeBatch relCodeBatch = new RelCodeBatch(); BeanUtils.copyProperties(relCodeDetailByParentCodeResponse, relCodeBatch); relCodeBatch.setCreateTime(new Date()); relCodeBatch.setUpdateTime(new Date()); relCodeBatch.setUploadFlagUp(1); relCodeBatch.setUploadFlagDown(uploadFlagDown); this.save(relCodeBatch); List detailList = relCodeDetailByParentCodeResponse.getRelCodeDetail(); List relCodeDetails = new ArrayList<>(); for (RelCodeDetail relCodeDetail : detailList) { relCodeDetail.setBatchIdFk(relCodeBatch.getId()); relCodeDetails.add(relCodeDetail); } relCodeDetailService.saveBatch(relCodeDetails); } } public boolean batchExist(String parentCode) { //1、排除掉层级是1的 UdiEntity udi = FilterUdiUtils.getUdi(parentCode); String udi1 = udi.getUdi(); ProductInfoEntity byNameCode = productInfoService.findByNameCode(udi1); if (byNameCode != null && "1".equals(byNameCode.getPackLevel())) return true; //2、本地查询 List navList = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getParentCode, parentCode)); if (CollUtil.isNotEmpty(navList)) return true; //3、查不到进行远程拉取更新 return this.UpdateDetailByParentCode(parentCode, 0); } public List detailByParentCodeSpms(String parentCode, Integer uploadFlagDown) { List respList = new ArrayList<>(); List list = this.list(new LambdaQueryWrapper().eq(RelCodeBatch::getParentCode, parentCode)); if (CollUtil.isEmpty(list)) { respList = this.detailByParentCode(parentCode); for (int i = 0; i < respList.size(); i++) { try { RelCodeDetailByParentCodeResponse relCodeDetailByParentCodeResponse = respList.get(i); this.saveDetailByParentCode(relCodeDetailByParentCodeResponse, uploadFlagDown); List relCodeDetailSons = relCodeDetailByParentCodeResponse.getRelCodeDetailSons(); if (CollUtil.isNotEmpty(relCodeDetailSons)) { relCodeDetailSons.forEach(item -> { this.saveDetailByParentCode(item, uploadFlagDown); }); } } catch (Exception e) { log.error("拉取国家同步库进行更新失败:[" + parentCode + "]"); log.error(e.getMessage(), e); } } return respList; } else { for (int i = 0; i < list.size(); i++) { RelCodeBatch relCodeBatch = list.get(i); RelCodeDetailByParentCodeResponse relCodeDetailByParentCodeResponse = new RelCodeDetailByParentCodeResponse(); List relCodeDetails = relCodeDetailService.list(new LambdaQueryWrapper().eq(RelCodeDetail::getParentCode, parentCode)); BeanUtils.copyProperties(relCodeBatch, relCodeDetailByParentCodeResponse); relCodeDetailByParentCodeResponse.setRelCodeDetail(relCodeDetails); if (CollUtil.isNotEmpty(relCodeDetails)) { RelCodeDetail relCodeDetail = relCodeDetails.get(0); if (relCodeDetail.getPackLayer() > 1) {//说明有下级 List sons = new ArrayList<>(); for (int i1 = 0; i1 < relCodeDetails.size(); i1++) { RelCodeDetail relCodeDetail1 = relCodeDetails.get(i1); List relCodeDetailByParentCodeResponses = this.detailByParentCodeSpms(relCodeDetail1.getCurCode(), uploadFlagDown); if (CollUtil.isNotEmpty(relCodeDetailByParentCodeResponses)) { sons.addAll(relCodeDetailByParentCodeResponses); } } relCodeDetailByParentCodeResponse.setRelCodeDetailSons(sons); } } respList.add(relCodeDetailByParentCodeResponse); } return respList; } } @Resource IoCodeTempDao ioCodeTempDao; @Resource UdiProductService udiProductService; public void threadUpdateIoCodeTempEntity(String parentCode) { List ioCodeTempEntities = ioCodeTempDao.selectList(new LambdaQueryWrapper().eq(IoCodeTempEntity::getCode, parentCode)); if (CollUtil.isNotEmpty(ioCodeTempEntities)) { //1、排除掉层级是1的 UdiEntity udi = FilterUdiUtils.getUdi(parentCode); if (udi == null) return; String udi1 = udi.getUdi(); UdiProductEntity udiProductEntity = udiProductService.findByNameCode(udi1); if (udiProductEntity == null) return; List navList = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getParentCode, parentCode)); if ((udiProductEntity != null && "1".equals(udiProductEntity.getPackLevel())) || (CollUtil.isNotEmpty(navList)) ) { //打上匹配到了药品关联关系的标记 for (int i = 0; i < ioCodeTempEntities.size(); i++) { IoCodeTempEntity ioCodeTempEntity = ioCodeTempEntities.get(i); ioCodeTempEntity.setDrugLink(1); ioCodeTempDao.updateById(ioCodeTempEntity); } } else { ThreadUtil.execAsync(() -> { asynThreadUpdateIoCodeTempEntity(parentCode, ioCodeTempEntities); }); } } } public void asynThreadUpdateIoCodeTempEntity(String parentCode, List ioCodeTempEntities) { if (this.batchExist(parentCode)) { //打上匹配到了药品关联关系的标记 for (int i = 0; i < ioCodeTempEntities.size(); i++) { IoCodeTempEntity ioCodeTempEntity = ioCodeTempEntities.get(i); ioCodeTempEntity.setDrugLink(1); ioCodeTempDao.updateById(ioCodeTempEntity); } } else { //打上匹配不到了药品关联关系的标记 for (int i = 0; i < ioCodeTempEntities.size(); i++) { IoCodeTempEntity ioCodeTempEntity = ioCodeTempEntities.get(i); ioCodeTempEntity.setDrugLink(0); ioCodeTempDao.updateById(ioCodeTempEntity); } } } @Transactional(rollbackFor = Exception.class) void ProcessData(Element rootElement){ //截取Relation NodeList relation = rootElement.getElementsByTagName("Relation"); if (relation == null) { throw new JsonException("XML文件解析错误"); } Element relationE = (Element) relation.item(0); //截取Batch NodeList batch = rootElement.getElementsByTagName("Batch"); if (batch == null) { throw new JsonException("XML文件解析错误"); } String productCode = relationE.getAttribute("productCode"); String subTypeNo = relationE.getAttribute("subTypeNo"); String cascade = relationE.getAttribute("cascade"); String packageSpec = relationE.getAttribute("packageSpec"); String comment = relationE.getAttribute("comment"); AuthAdmin user = customerService.getUserBean(); for (int i = 0; i < batch.getLength(); i++) { Node batchNode = batch.item(i); RelCodeBatch relCodeBatch = new RelCodeBatch(); Map> codeMap = new HashMap<>(); if (batchNode.getNodeType() == Node.ELEMENT_NODE) { Element batchE = (Element) batchNode; String batchNo = batchE.getAttribute("batchNo"); String madeDate = batchE.getAttribute("madeDate"); String validateDate = batchE.getAttribute("validateDate"); String workShop = batchE.getAttribute("workShop"); String lineName = batchE.getAttribute("lineName"); String lineManager = batchE.getAttribute("lineManager"); String customerId = String.valueOf(user.getCustomerId()); relCodeBatch.setProductCode(productCode); relCodeBatch.setSubTypeNo(subTypeNo); relCodeBatch.setCascadeRatio(cascade); relCodeBatch.setPackageSpec(packageSpec); relCodeBatch.setComment(comment); relCodeBatch.setBatchNo(batchNo); relCodeBatch.setMadeDate(madeDate); relCodeBatch.setValidateDate(String.valueOf(DateUtil.offsetDay(DateUtil.parse(validateDate, "yyyy-MM-dd"), 1))); relCodeBatch.setLineName(lineName); relCodeBatch.setWorkShop(workShop); relCodeBatch.setLineManager(lineManager); relCodeBatch.setCreateTime(new Date()); relCodeBatch.setCreateUser(user.getUserName()); relCodeBatch.setUpdateTime(new Date()); relCodeBatch.setUpdateUser(user.getUserName()); relCodeBatch.setErpId(customerId); relCodeBatch.setUploadFlagDown(1); relCodeBatch.setUploadFlagUp(0); //batch下的节点code NodeList code = batchNode.getChildNodes(); for (int j = 0; j < code.getLength(); j++) { Node codeNode = code.item(j); if (codeNode.getNodeType() == Node.ELEMENT_NODE) { RelCodeDetail relCodeDetail = new RelCodeDetail(); Element codeE = (Element) codeNode; String curCode = codeE.getAttribute("curCode"); Integer packLayer = Integer.valueOf(codeE.getAttribute("packLayer")); relCodeDetail.setBatchIdFk(relCodeBatch.getId()); relCodeDetail.setCurCode(curCode); relCodeDetail.setPackLayer(Integer.valueOf(packLayer)); String parentCode = codeE.getAttribute("parentCode"); relCodeDetail.setParentCode(StrUtil.isNotBlank(parentCode) ? parentCode : "0"); String flag = codeE.getAttribute("flag"); relCodeDetail.setFlag(Integer.valueOf(flag)); //判断是否已存在 List relCodeDetails = codeMap.get(StrUtil.isNotBlank(parentCode) ? parentCode : "0"); if (relCodeDetails == null){ List newRelCodeDetails = new ArrayList<>(); newRelCodeDetails.add(relCodeDetail); codeMap.put(StrUtil.isNotBlank(parentCode) ? parentCode : "0",newRelCodeDetails); }else { relCodeDetails.add(relCodeDetail); codeMap.put(StrUtil.isNotBlank(parentCode) ? parentCode : "0",relCodeDetails); } } } //开始处理codeMap if (!codeMap.isEmpty()){ Map batchIdFkMap = new HashMap<>(); List addRelCodeDetail = new ArrayList<>(); RelCodeBatch updateDrugLevelRelCodeBatch = null; // 遍历 Map for (Map.Entry> entry : codeMap.entrySet()) { String key = entry.getKey(); List list = entry.getValue(); RelCodeBatch addRelCodeBatch = new RelCodeBatch(); BeanUtils.copyProperties(relCodeBatch,addRelCodeBatch); addRelCodeBatch.setParentCode(key); if ("0".equals(key)){ RelCodeDetail relCodeDetail = list.get(0); String curCode = relCodeDetail.getCurCode(); String diStr = FilterUdiUtils.getUdi(curCode).getUdi(); addRelCodeBatch.setProductCode(diStr); addRelCodeBatch.setCurCode(curCode); addRelCodeBatch.setThreeLevelCount(1); this.save(addRelCodeBatch); batchIdFkMap.put(curCode,addRelCodeBatch.getId()); updateDrugLevelRelCodeBatch = addRelCodeBatch; }else { for (RelCodeDetail detail : list) { Integer packLayer = detail.getPackLayer(); if (packLayer == 2){ RelCodeBatch addRelCodeBatch2 = new RelCodeBatch(); BeanUtils.copyProperties(relCodeBatch,addRelCodeBatch2); addRelCodeBatch2.setParentCode(key); String curCode = detail.getCurCode(); String diStr = FilterUdiUtils.getUdi(curCode).getUdi(); addRelCodeBatch2.setProductCode(diStr); addRelCodeBatch2.setCurCode(curCode); addRelCodeBatch2.setThreeLevelCount(0); addRelCodeBatch2.setTwoLevelCount(1); this.save(addRelCodeBatch2); batchIdFkMap.put(curCode,addRelCodeBatch2.getId()); //同时也是上面的明细 detail.setBatchIdFk(batchIdFkMap.get(key)); addRelCodeDetail.add(detail); }else if (packLayer == 1){ //直接明细 detail.setBatchIdFk(batchIdFkMap.get(key)); addRelCodeDetail.add(detail); } } } } if (CollUtil.isNotEmpty(addRelCodeDetail)){ relCodeDetailService.saveBatch(addRelCodeDetail); //更新层级关系的数量 this.updateDrugLevelCount(updateDrugLevelRelCodeBatch); } } } } } /** * 通过curCode 获取明细的数量 如果是 三级 需要先去计算二级单下的一级数量 在算出二级数量 * 如果是 二级 直接计算出 一级 * @param item */ private void updateDrugLevelCount(RelCodeBatch item) { String curCode = item.getCurCode(); List list = relCodeDetailService.list(new LambdaQueryWrapper().eq(RelCodeDetail::getParentCode, curCode)); if (CollUtil.isNotEmpty(list)){ RelCodeDetail relCodeDetail = list.get(0); Integer packLayer = relCodeDetail.getPackLayer(); if (packLayer == 2){ item.setThreeLevelCount(1); item.setTwoLevelCount(list.size()); //需要计算出一级数量 List twoCurCodes = list.stream().map(RelCodeDetail::getCurCode).collect(Collectors.toList()); List list2 = relCodeDetailService.list(new LambdaQueryWrapper().in(RelCodeDetail::getParentCode, twoCurCodes)); item.setOneLevelCount(list2.size()); //更新下 二级单 List twoRelCodeBatchs = this.list(new LambdaQueryWrapper().in(RelCodeBatch::getCurCode, twoCurCodes)); if (CollUtil.isNotEmpty(twoRelCodeBatchs)){ twoRelCodeBatchs.forEach( t -> { this.updateDrugLevelCount(t); }); } }else if (packLayer == 1){ item.setThreeLevelCount(0); item.setTwoLevelCount(1); item.setOneLevelCount(list.size()); } this.updateById(item); } return; } }