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.common.util.ResultVOUtils; 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.BasicProductsEntity; import com.glxp.api.entity.basic.ProductInfoEntity; import com.glxp.api.entity.basic.UdiEntity; 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.inout.IoCodeTempService; 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"); } List relCodeDetails = new ArrayList<>(); Document document = XmlUtil.readXML(file.getInputStream()); //获取根 Element rootElement = XmlUtil.getRootElement(document); //截取Relation NodeList relation = rootElement.getElementsByTagName("Relation"); if(relation == null){ throw new JsonException("XML文件解析错误"); } Element relationE = (Element) relation.item(0); 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"); //截取Batch NodeList batch = rootElement.getElementsByTagName("Batch"); if(batch == null){ throw new JsonException("XML文件解析错误"); } AuthAdmin user = customerService.getUserBean(); for (int i = 0; i < batch.getLength(); i++) { Node batchNode = batch.item(i); RelCodeBatch relCodeBatch = new RelCodeBatch(); if (batchNode.getNodeType() == Node.ELEMENT_NODE) { Element batchE = (Element) batchNode; relCodeBatch.setProductCode(productCode); relCodeBatch.setSubTypeNo(subTypeNo); relCodeBatch.setCascadeRatio(cascade); relCodeBatch.setPackageSpec(packageSpec); relCodeBatch.setComment(comment); String batchNo = batchE.getAttribute("batchNo"); relCodeBatch.setBatchNo(batchNo); String madeDate = batchE.getAttribute("madeDate"); relCodeBatch.setMadeDate(madeDate); // relCodeBatch.setMadeDate(DateUtil.parse(madeDate,"yyyy-MM-dd")); String validateDate = batchE.getAttribute("validateDate"); // relCodeBatch.setValidateDate(DateUtil.offsetDay(DateUtil.parse(validateDate,"yyyy-MM-dd"),1)); relCodeBatch.setValidateDate(String.valueOf(DateUtil.offsetDay(DateUtil.parse(validateDate,"yyyy-MM-dd"),1))); String workShop = batchE.getAttribute("workShop"); relCodeBatch.setWorkShop(workShop); String lineName = batchE.getAttribute("lineName"); relCodeBatch.setLineName(lineName); String lineManager = batchE.getAttribute("lineManager"); relCodeBatch.setLineManager(lineManager); relCodeBatch.setCreateTime(new Date()); relCodeBatch.setCreateUser(user.getUserName()); relCodeBatch.setUpdateTime(new Date()); relCodeBatch.setUpdateUser(user.getUserName()); this.save(relCodeBatch); } //batch下的节点code NodeList code = batchNode.getChildNodes(); for (int j = 0; j < code.getLength(); j++) { Node codeNode = code.item(j); RelCodeDetail relCodeDetail = new RelCodeDetail(); if (codeNode.getNodeType() == Node.ELEMENT_NODE) { Element codeE = (Element) codeNode; relCodeDetail.setBatchIdFk(relCodeBatch.getId()); String curCode = codeE.getAttribute("curCode"); relCodeDetail.setCurCode(curCode); String packLayer = codeE.getAttribute("packLayer"); 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)); relCodeDetails.add(relCodeDetail); } } } relCodeDetailService.saveBatch(relCodeDetails); }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()); relCodeBatch.setParentCode(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); } 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; 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); String udi1 = udi.getUdi(); ProductInfoEntity byNameCode = productInfoService.findByNameCode(udi1); List navList = this.list(new LambdaQueryWrapper() .eq(RelCodeBatch::getParentCode, parentCode)); if ( (byNameCode != null && "1".equals(byNameCode.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); } } } }