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 cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.pagehelper.PageHelper; import com.glxp.api.common.res.BaseResponse; import com.glxp.api.dao.inout.IoCodeTempDao; import com.glxp.api.entity.auth.AuthAdmin; import com.glxp.api.entity.basic.BasicCorpEntity; 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.RelCodeDetail; import com.glxp.api.entity.inout.IoCodeTempEntity; import com.glxp.api.entity.system.CompanyEntity; import com.glxp.api.entity.system.SyncDataSetEntity; import com.glxp.api.exception.JsonException; import com.glxp.api.http.sync.SpGetHttpClient; import com.glxp.api.http.sync.SpsDirectClient; import com.glxp.api.req.alihealth.AlihealthRelCodeInsertReqeust; import com.glxp.api.req.collect.RelCodeBatchRequest; import com.glxp.api.req.collect.RelCodeDetailRequest; import com.glxp.api.res.alihealth.AlihealthKytSinglerelationResponse; 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.service.basic.impl.BasicCorpServiceImpl; import com.glxp.api.service.sync.SyncDataSetService; import com.glxp.api.service.system.impl.CompanyServiceImpl; import com.glxp.api.util.StringUtils; import com.glxp.api.util.udi.FilterUdiUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.glxp.api.dao.collect.RelCodeBatchMapper; import com.glxp.api.entity.collect.RelCodeBatch; 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; @Resource private CompanyServiceImpl companyService; @Resource private BasicCorpServiceImpl basicCorpService; @Resource private RelCodeBatchService relCodeBatchService; /** * 上传保存关联信息 * * @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) { String productCode = relCodeBatchRequest.getProductCode(); String subTypeNo = relCodeBatchRequest.getSubTypeNo(); String batchNo = relCodeBatchRequest.getBatchNo(); //如果不存在就添加 List list = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getProductCode, productCode) .eq(RelCodeBatch::getSubTypeNo, subTypeNo) .eq(RelCodeBatch::getBatchNo, batchNo)); if (CollUtil.isNotEmpty(list)) { throw new JsonException("层级编码:【" + productCode + "】;类型编码:【" + subTypeNo + "】;批次号:【" + batchNo + "】已存在!"); } 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()); String customerId = String.valueOf(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); }); } } 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); } /** * 通过 parentCode 拉取spms同步库进行更新 */ public boolean UpdateDetailByParentCode(String parentCode) { 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); List relCodeDetailSons = relCodeDetailByParentCodeResponse.getRelCodeDetailSons(); if (CollUtil.isNotEmpty(relCodeDetailSons)) { relCodeDetailSons.forEach(item -> { this.saveDetailByParentCode(item); }); } } catch (Exception e) { log.error("拉取SPMS同步库进行更新失败:[" + parentCode + "]"); log.error(e.getMessage(), e); } } return true; } else return false; } public void saveDetailByParentCode(RelCodeDetailByParentCodeResponse relCodeDetailByParentCodeResponse) { 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.setId(null); relCodeBatch.setCreateTime(new Date()); relCodeBatch.setUpdateTime(new Date()); relCodeBatch.setUploadFlagUp(1); relCodeBatch.setUploadFlagDown(0); this.save(relCodeBatch); List detailList = relCodeDetailByParentCodeResponse.getRelCodeDetail(); List relCodeDetails = new ArrayList<>(); for (RelCodeDetail relCodeDetail : detailList) { relCodeDetail.setId(null); relCodeDetail.setBatchIdFk(relCodeBatch.getId()); relCodeDetails.add(relCodeDetail); } relCodeDetailService.saveBatch(relCodeDetails); } } @Resource SpsDirectClient spsDirectClient; @Resource private SpGetHttpClient spGetHttpClient; /** * 层级编码查询spms同步库 */ public List detailByParentCode(String parentCode) { try { return spsDirectClient.detailByParentCode(parentCode); } catch (Exception e) { e.printStackTrace(); return null; } } @Resource IoCodeTempDao ioCodeTempDao; @Resource UdiProductService udiProductService; @Resource SyncDataSetService syncDataSetService; public void threadUpdateIoCodeTempEntity(String parentCode) { SyncDataSetEntity syncDataSetEntity = syncDataSetService.findSet(); if(syncDataSetEntity == null || StrUtil.isEmpty(syncDataSetEntity.getSyncIp())){ return; } ThreadUtil.execAsync(() -> { List ioCodeTempEntities = ioCodeTempDao.selectList(new LambdaQueryWrapper().eq(IoCodeTempEntity::getCode, parentCode)); if (CollUtil.isNotEmpty(ioCodeTempEntities)) { IoCodeTempEntity codeTempEntity = ioCodeTempEntities.get(0); //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 (navList == null || navList.size() == 0) { CompanyEntity companyEntity = companyService.findCompany(); BasicCorpEntity basicCorpEntity = basicCorpService.selectByErpId(codeTempEntity.getSupId()); AlihealthRelCodeInsertReqeust alihealthRelCodeInsertReqeust = new AlihealthRelCodeInsertReqeust(); alihealthRelCodeInsertReqeust.setName(basicCorpEntity.getName()); alihealthRelCodeInsertReqeust.setAppKey(companyEntity.getAppId()); alihealthRelCodeInsertReqeust.setAppSecret(companyEntity.getAppSecret()); alihealthRelCodeInsertReqeust.setCustomerId(codeTempEntity.getSupId()); alihealthRelCodeInsertReqeust.setCode(parentCode); alihealthRelCodeInsertReqeust.setRefEntId(companyEntity.getRefEntId()); BaseResponse baseResponse = spGetHttpClient.relCodeInsert(alihealthRelCodeInsertReqeust); if (baseResponse.getCode() == 20000) { System.out.println("sda" + baseResponse.getData().toString()); AlihealthKytSinglerelationResponse alihealthKytSinglerelationResponse = JSONUtil.toBean(baseResponse.getData().toString(), AlihealthKytSinglerelationResponse.class); // 返回的码关联关系进行插入 RelCodeBatch relCodeBatch = alihealthKytSinglerelationResponse.disposeRelCodeBatch(alihealthRelCodeInsertReqeust.getCustomerId()); RelCodeBatch relCodeBatchOne = relCodeBatchService.getOne(new QueryWrapper().eq("productCode", relCodeBatch.getProductCode()) .last("limit 1") ); if (Objects.isNull(relCodeBatchOne)) { relCodeBatch.setCreateUser(alihealthRelCodeInsertReqeust.getCustomerId()); relCodeBatch.setCreateTime(new Date()); relCodeBatchService.save(relCodeBatch); } else { relCodeBatchService.update(relCodeBatch, new QueryWrapper().eq("productCode", relCodeBatch.getProductCode())); } Integer id = Objects.isNull(relCodeBatch.getId()) ? relCodeBatchOne.getId() : relCodeBatch.getId(); // 进行查询 List list = alihealthKytSinglerelationResponse.disposeRelRodeDetailList(id); if (list != null && list.size() > 0) { List curCodeList = new ArrayList(); for (RelCodeDetail relCodeDetail : list) { curCodeList.add(relCodeDetail.getCurCode()); } relCodeDetailService.remove(new QueryWrapper().in("curCode", curCodeList)); relCodeDetailService.saveBatch(list); } // 插入成功就重新查询一下 navList = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getCurCode, parentCode)); if (StringUtils.isEmpty(companyEntity.getRefEntId())) { companyEntity.setRefEntId(alihealthKytSinglerelationResponse.getRefEntId()); companyService.modifyCompany(companyEntity); } } else { if (StringUtils.isNotEmpty(companyEntity.getRefEntId())) { companyEntity.setRefEntId(null); companyService.modifyCompany(companyEntity); } log.error(baseResponse.getMessage()); } } 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 { 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; } }