package com.glxp.api.service.sync; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.glxp.api.common.res.BaseResponse; import com.glxp.api.common.util.ResultVOUtils; import com.glxp.api.constant.*; import com.glxp.api.controller.sync.SpsSyncWebSocket; import com.glxp.api.constant.Constant; import com.glxp.api.dao.basic.BasicProductsDao; import com.glxp.api.entity.basic.*; import com.glxp.api.entity.inout.*; import com.glxp.api.entity.inv.DeviceInspectTaskDetailEntity; import com.glxp.api.entity.inv.DeviceInspectTaskEntity; import com.glxp.api.entity.purchase.*; import com.glxp.api.entity.sync.BasicExportStatusEntity; import com.glxp.api.entity.sync.BasicExportStatusTimeEntity; import com.glxp.api.entity.sync.SocketMsgEntity; import com.glxp.api.entity.sync.SyncDataBustypeEntity; import com.glxp.api.entity.thrsys.ThrBusTypeOriginEntity; import com.glxp.api.req.basic.ProductInfoFilterRequest; import com.glxp.api.req.basic.UdiCompanyRequest; import com.glxp.api.req.inout.FilterOrderRequest; import com.glxp.api.req.sync.SpsSyncDataRequest; import com.glxp.api.res.sync.SpSyncUdiResponse; import com.glxp.api.res.sync.SpsSyncDeviceTaskResponse; import com.glxp.api.res.sync.SpsSyncOrderResponse; import com.glxp.api.res.system.SyncDataSetResponse; import com.glxp.api.service.basic.*; import com.glxp.api.service.inout.*; import com.glxp.api.service.inout.impl.IoOrderInvoiceService; import com.glxp.api.service.inv.DeviceInspectTaskDetailService; import com.glxp.api.service.inv.DeviceInspectTaskService; import com.glxp.api.service.purchase.*; import com.glxp.api.service.thrsys.IThrBusTypeOriginService; import com.glxp.api.util.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.*; import java.util.function.Function; import static com.glxp.api.constant.BasicProcessStatus.NEW_ALL_ORDER; import static com.glxp.api.constant.BasicProcessStatus.NEW_ALL_UDIS; import static com.glxp.api.constant.Constant.SYNC_REMARK; @Slf4j @Service @RequiredArgsConstructor public class SpsSyncDownloadService { private final Logger logger = LoggerFactory.getLogger(SpsSyncDownloadService.class); private final RedisUtil redisUtil; //已完成扫码单据 @Resource IoOrderService orderService; @Resource IoCodeService codesService; @Resource SyncDataSetService syncDataSetService; @Resource IoOrderDetailBizService orderDetailBizService; @Resource IoOrderDetailCodeService orderDetailCodeService; @Resource IoOrderDetailResultService orderDetailResultService; @Resource BasicExportService basicExportService; @Resource BasicExportTimeService basicExportTimeService; @Resource IoOrderInvoiceService orderInvoiceService; // 创建单据同步任务 public void syncOrderTask(Date lastUpdateTime) { log.info("创建单据同步任务"); //自动创建要求被下载已完成单据任务. // 1.判断是否同步任务已存在 Date curTime = new Date(); BasicExportStatusEntity basicExportStatusEntity1 = basicExportService.getOne(Wrappers.lambdaQuery(BasicExportStatusEntity.class) .eq(BasicExportStatusEntity::getType, NEW_ALL_ORDER) .orderByDesc(BasicExportStatusEntity::getStartTime) .last("limit 1") ); //首次任务or上次任务结束 if (basicExportStatusEntity1 == null || IntUtil.value(BasicExportStatusEnum.COMPLETED.getCode()) == IntUtil.value(basicExportStatusEntity1.getStatus())) { log.info("no2:" + basicExportStatusEntity1.getStatus() + "---" + BasicExportStatusEnum.COMPLETED.getCode()); SpsSyncDataRequest spsSyncDataRequest = getRequest(ConstantStatus.SYNC_DOWNLOAD_SCAN_ORDER); if (lastUpdateTime != null) spsSyncDataRequest.setLastUpdateTime(DateUtil.formatDateTime(lastUpdateTime)); BaseResponse baseResponse = findOrder(spsSyncDataRequest); SpsSyncOrderResponse syncOrderResponse = baseResponse.getData(); // 2.查看是否有需要更新的数据 if (CollUtil.isNotEmpty(syncOrderResponse.getOrderEntities())) { // 3.插入到任务表,等待获取 BasicExportStatusEntity orderStatusEntity = new BasicExportStatusEntity(); orderStatusEntity.setId(CustomUtil.getId()); orderStatusEntity.setIdDatas(ConstantStatus.SYNC_SCAN_ORDER); orderStatusEntity.setType(NEW_ALL_ORDER); orderStatusEntity.setUpdateTime(new Date()); orderStatusEntity.setStatus(BasicExportStatusEnum.WAIT_SYNC.getCode()); orderStatusEntity.setStartTime(curTime); orderStatusEntity.setScheduleType(BasicProcessStatus.SCHEDULE_NORMAL); if (lastUpdateTime != null) { String fileFullPath = null; try { fileFullPath = writeFile(filePath, BasicProcessStatus.NEW_ALL_BUS_ORDER, JSONUtil.toJsonStr(baseResponse.getData())); orderStatusEntity.setCacheFilePath(fileFullPath); orderStatusEntity.setRemark(baseResponse.getData().getSyncRemark()); } catch (IOException e) { e.printStackTrace(); } } basicExportService.insertExportStatus(orderStatusEntity); SocketMsgEntity socketMsgEntity = SocketMsgEntity.builder().type(SocketMsgType.DL_ALL_DATA).remark("下载基础信息").build(); spsSyncWebSocket.sendMessage(socketMsgEntity, "1:" + socketToken); } } } @Transactional // 创建国家库同步任务 public void syncDiProductsTask(Date lastUpdateTime) { BasicExportStatusEntity exportStatus = basicExportService.getOne(Wrappers.lambdaQuery(BasicExportStatusEntity.class) .eq(BasicExportStatusEntity::getType, NEW_ALL_UDIS) .orderByDesc(BasicExportStatusEntity::getStartTime) .last("limit 1") ); //首次任务or上次任务结束 if (exportStatus == null || BasicExportStatusEnum.COMPLETED.getCode().equals(exportStatus.getStatus())) { SpsSyncDataRequest spsSyncDataRequest = getRequest(ConstantStatus.SYNC_DI_PRODUCTS); if (lastUpdateTime != null) { spsSyncDataRequest.setLastUpdateTime(DateUtil.formatDateTime(lastUpdateTime)); BasicExportStatusTimeEntity timeInfo = BasicExportStatusTimeEntity.builder() .key("AutoDownloadDiProducts") .lastUpdateTime(DateUtil.formatDateTime(lastUpdateTime)) .build(); basicExportTimeService.replace(timeInfo); } BaseResponse baseResponse = syncUdi(spsSyncDataRequest); SpSyncUdiResponse spSyncUdiResponse = baseResponse.getData(); if (CollUtil.isNotEmpty(spSyncUdiResponse.getProductInfoEntityList()) || CollUtil.isNotEmpty(spSyncUdiResponse.getUdiCompanyEntities())) { BasicExportStatusEntity basicExportStatusEntity = new BasicExportStatusEntity(); basicExportStatusEntity.setId(CustomUtil.getId()); basicExportStatusEntity.setIdDatas(ConstantStatus.SYNC_DI_PRODUCTS); basicExportStatusEntity.setType(NEW_ALL_UDIS); basicExportStatusEntity.setUpdateTime(new Date()); basicExportStatusEntity.setStartTime(new Date()); basicExportStatusEntity.setStatus(BasicExportStatusEnum.WAIT_SYNC.getCode()); basicExportStatusEntity.setScheduleType(BasicProcessStatus.SCHEDULE_NORMAL); basicExportService.insertExportStatus(basicExportStatusEntity); } } } private final BasicHospTypeService hospTypeService; private final UdiRelevanceService udiRelevanceService; private final BasicProductsDao basicProductsDao; private final CompanyProductRelevanceService relevanceService; private final BasicCorpService corpService; private final SupCertService supCertService; private final SupCertSetService supCertSetService; private final SupCompanyService supCompanyService; private final SupManufacturerService supManufacturerService; private final SupProductService supProductService; @Value("${file_path}") private String filePath; /** * 同步数据 * * @param info 同步设置 * @param exportType 数据模块类型 */ public void syncData(SyncDataSetResponse info, BasicExportTypeEnum exportType, Date syncTime) { Date now = new Date(); switch (exportType) { case BASIC_DATA: if (needExec(info.getBasicProducts(), info.getBasicCorp(), info.getSupCert())) { basicExportInfoCreate(exportType, syncTime, now , x -> x.generateBasicDataFile(info, now, false, syncTime) , x -> x.generateBasicDataFile(info, now, true, syncTime)); } break; case OTHER_DATA: if (needExec(info.getUdiCodeLost(), info.getUdiCodeRel())) { basicExportInfoCreate(exportType, syncTime, now , x -> x.generateOtherDataFile(info, now, false, syncTime) , x -> x.generateOtherDataFile(info, now, true, syncTime)); } break; case DOCUMENT_TYPE_DATA: // if (needExec(info.getTypeBus(), info.getTypeScan(), info.getTypeThird())) { // basicExportInfoCreate(exportType, syncTime, now // , x -> x.generateDocumentTypeDataFile(info, now, false, syncTime) // , x -> x.generateDocumentTypeDataFile(info, now, true, syncTime)); // } break; case DEVICE_TASK: basicExportInfoCreate(exportType, syncTime, now , x -> x.generateDevTaskDataFile(info, now, false, syncTime) , x -> x.generateDevTaskDataFile(info, now, true, syncTime)); } } /** * 判断是否需要执行 * * @param set 需要判断的数据 * @return */ private boolean needExec(int... set) { return Arrays.stream(set).filter(i -> i == 2).findAny().isPresent(); } private final ApplicationContext applicationContext; /** * 创建一个同步任务 * * @param exportEnum 任务类型枚举 * @param hasDataMethod 判断时候有无数据方法 * @param createFileMethod 执行文件生成方法 */ private void basicExportInfoCreate(BasicExportTypeEnum exportEnum, Date syncTime, Date now, Function hasDataMethod, Function createFileMethod) { //防止出现同时调用问题 String redisKey = String.format("spsm-sync-create:%s", exportEnum.getKey()); boolean result = redisUtil.setIfAbsent(redisKey, 1, 10); if (!result) { String errorMsg = String.format("syncIdcSps----process------------同步[%s]重复进入", exportEnum.getRemark()); // logger.info(errorMsg); // throw new RuntimeException(errorMsg); log.error(errorMsg); } BasicExportStatusEntity exportStatus = basicExportService.getOne(Wrappers.lambdaQuery(BasicExportStatusEntity.class) .eq(BasicExportStatusEntity::getType, exportEnum.getRemark()) .orderByDesc(BasicExportStatusEntity::getStartTime) .last("limit 1") ); //首次任务or上次任务结束 if (exportStatus == null || BasicExportStatusEnum.COMPLETED.getCode().equals(exportStatus.getStatus())) { //判断有无新数据 Boolean hasData = hasDataMethod.apply(applicationContext.getBean(this.getClass())); if (Boolean.FALSE.equals(hasData)) { return; } exportStatus = BasicExportStatusEntity.builder() .id(CustomUtil.getId()) .status(syncTime == null ? BasicExportStatusEnum.WAIT_TRIGGERED.getCode() : BasicExportStatusEnum.WAIT_BUILT.getCode()) .idDatas(exportEnum.getKey()) .type(exportEnum.getRemark()) .scheduleType(0) .updateTime(cn.hutool.core.date.DateUtil.date()) .startTime(now) .build(); basicExportService.save(exportStatus); if (syncTime != null) { createFileMethod.apply(applicationContext.getBean(this.getClass())); } } else if (exportStatus.getStatus().equals(BasicExportStatusEnum.WAIT_BUILT.getCode())) {//文件待生成 createFileMethod.apply(applicationContext.getBean(this.getClass())); } } /** * 读取基础数据,创建文件 * * @param info 同步设置信息 * @param now 当前时间 * @param createFile 是否创建文件 * @return 是否有数据 true/false 有新数据/无新数据 */ protected boolean generateBasicDataFile(SyncDataSetResponse info, Date now, boolean createFile, Date syncTime) { BasicExportTypeEnum exportType = BasicExportTypeEnum.BASIC_DATA; //文件数据 Map jsonMap = new WeakHashMap<>(4); List syncFiles = new ArrayList<>(); Map> totalTimeMap = new WeakHashMap<>(10); StringBuffer remark = new StringBuffer(); Map syncTimeMap = new WeakHashMap<>(3); syncTimeMap.put("isNew", true); boolean ge = false; if (syncTime != null) { ge = true; } try { //确认有开启物资字典由外向内同步 if (needExec(info.getBasicProducts())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.BASIC_PRODUCTS, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.BASIC_PRODUCTS, map); List hospTypeList = hospTypeService.list(Wrappers.lambdaQuery(BasicHospTypeEntity.class) .le(!ge && (boolean) map.get("isNew"), BasicHospTypeEntity::getUpdateTime, now) .between(ge, BasicHospTypeEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), BasicHospTypeEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(hospTypeList)) { jsonMap.put(BasicHospTypeEntity.class.getSimpleName(), hospTypeList); remark.append("物资字典分类信息:").append(hospTypeList.size()).append("条\n"); } List udiRelevanceList = udiRelevanceService.list(Wrappers.lambdaQuery(UdiRelevanceEntity.class) .le(!ge && (boolean) map.get("isNew"), UdiRelevanceEntity::getUpdateTime, now) .between(ge, UdiRelevanceEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), UdiRelevanceEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(udiRelevanceList)) { jsonMap.put(UdiRelevanceEntity.class.getSimpleName(), udiRelevanceList); remark.append("物资字典主表信息:").append(udiRelevanceList.size()).append("条\n"); } List productsList = basicProductsDao.selectList(Wrappers.lambdaQuery(BasicProductsEntity.class) .le(!ge && (boolean) map.get("isNew"), BasicProductsEntity::getUpdateTime, now) .between(ge, BasicProductsEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), BasicProductsEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(productsList)) { remark.append("物资字典字表信息:").append(productsList.size()).append("条\n"); jsonMap.put(BasicProductsEntity.class.getSimpleName(), productsList); } List relevanceList = relevanceService.list(Wrappers.lambdaQuery(CompanyProductRelevanceEntity.class) .le(!ge && (boolean) map.get("isNew"), CompanyProductRelevanceEntity::getUpdateTime, now) .between(ge, CompanyProductRelevanceEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), CompanyProductRelevanceEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(relevanceList)) { remark.append("供应商关联物资字典表:").append(relevanceList.size()).append("条\n"); jsonMap.put(CompanyProductRelevanceEntity.class.getSimpleName(), relevanceList); } } //确认有开启往来单位字典同步 if (needExec(info.getBasicCorp())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.BASIC_CORP, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.BASIC_CORP, map); List corpList = corpService.list(Wrappers.lambdaQuery(BasicCorpEntity.class) .le(!ge && (boolean) map.get("isNew"), BasicCorpEntity::getUpdateTime, now) .between(ge, BasicCorpEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), BasicCorpEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(corpList)) { remark.append("往来单位字典信息:").append(corpList.size()).append("条\n"); jsonMap.put(BasicCorpEntity.class.getSimpleName(), corpList); } } //确认有开启首营资质同步 if (needExec(info.getSupCert())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.SUP_CERT, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.SUP_CERT, map); List supCertList = supCertService.list(Wrappers.lambdaQuery(SupCertEntity.class) .ge(SupCertEntity::getAuditStatus, ConstantStatus.AUDIT_PASS) .le(!ge && (boolean) map.get("isNew"), SupCertEntity::getUpdateTime, now) .between(ge, SupCertEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), SupCertEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(supCertList)) { jsonMap.put(SupCertEntity.class.getSimpleName(), supCertList); for (SupCertEntity supCertEntity : supCertList) { if (StrUtil.isNotEmpty(supCertEntity.getFilePath())) { String[] fileNames = supCertEntity.getFilePath().split(","); syncFiles.addAll(CollUtil.toList(fileNames)); } } if (CollUtil.isNotEmpty(syncFiles)) { jsonMap.put("syncFiles", syncFiles); } } List supCertSetList = supCertSetService.list(Wrappers.lambdaQuery(SupCertSetEntity.class) .le(!ge && (boolean) map.get("isNew"), SupCertSetEntity::getUpdateTime, now) .between(ge, SupCertSetEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), SupCertSetEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(supCertSetList)) { remark.append("资质填报设置信息:").append(supCertSetList.size()).append("条\n"); jsonMap.put(SupCertSetEntity.class.getSimpleName(), supCertSetList); } List supCompanyList = supCompanyService.list(Wrappers.lambdaQuery(SupCompanyEntity.class) .ge(SupCompanyEntity::getAuditStatus, ConstantStatus.AUDIT_PASS) .le(!ge && (boolean) map.get("isNew"), SupCompanyEntity::getUpdateTime, now) .between(ge, SupCompanyEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), SupCompanyEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(supCompanyList)) { remark.append("供应商资质信息:").append(supCompanyList.size()).append("条\n"); jsonMap.put(SupCompanyEntity.class.getSimpleName(), supCompanyList); } List supManufacturerList = supManufacturerService.list(Wrappers.lambdaQuery(SupManufacturerEntity.class) .ge(SupManufacturerEntity::getAuditStatus, ConstantStatus.AUDIT_PASS) .le(!ge && (boolean) map.get("isNew"), SupManufacturerEntity::getUpdateTime, now) .between(ge, SupManufacturerEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), SupManufacturerEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(supManufacturerList)) { remark.append("生产企业资质信息:").append(supManufacturerList.size()).append("条\n"); jsonMap.put(SupManufacturerEntity.class.getSimpleName(), supManufacturerList); } List supProductList = supProductService.list(Wrappers.lambdaQuery(SupProductEntity.class) .ge(SupProductEntity::getAuditStatus, ConstantStatus.AUDIT_PASS) .le(!ge && (boolean) map.get("isNew"), SupProductEntity::getUpdateTime, now) .between(ge, SupProductEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), SupProductEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(supProductList)) { remark.append("配送产品资质信息:").append(supProductList.size()).append("条\n"); jsonMap.put(SupProductEntity.class.getSimpleName(), supProductList); } } if (jsonMap.size() > 0) { jsonMap.put(SYNC_REMARK, remark.toString()); if (!createFile) { return true; } try { String fileFullPath = writeFile(filePath, exportType.getRemark(), JsonUtils.toJsonString(jsonMap)); //计算总数 // int total = 0; // for (List l : jsonMap.values()) { // total += l.size(); // } try { //修改任务数据 boolean update = updateExportStatus(exportType, fileFullPath, remark.toString()); } catch (Exception e) { // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, fileFullPath); } SocketMsgEntity socketMsgEntity = SocketMsgEntity.builder().type(SocketMsgType.DL_ALL_DATA).remark("下载基础信息").build(); spsSyncWebSocket.sendMessage(socketMsgEntity, "1:" + socketToken); return true; } catch (IOException e) { logger.error(String.format("syncIdcSps----process------------生成[%s]文件及更改库操作异常,异常信息<%s>" , exportType.getRemark(), e.getMessage())); // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, null); } } return false; } catch (Exception e) { logger.error(e.getMessage()); return false; } } @Value("${WEBSOCKET_TOKEN}") private String socketToken; @Resource SpsSyncWebSocket spsSyncWebSocket; private final IoCodeLostService ioCodeLostService; private final IoCodeRelService ioCodeRelService; /** * 读取其他数据,创建文件 * * @param info 同步设置信息 * @param now 当前时间 * @param createFile 是否创建文件 * @return 是否有数据 true/false 有新数据/无新数据 */ protected boolean generateOtherDataFile(SyncDataSetResponse info, Date now, boolean createFile, Date syncTime) { StringBuffer remark = new StringBuffer(); BasicExportTypeEnum exportType = BasicExportTypeEnum.OTHER_DATA; //文件数据 List syncFiles = new ArrayList<>(); Map jsonMap = new WeakHashMap<>(4); Map> totalTimeMap = new WeakHashMap<>(10); Map syncTimeMap = new WeakHashMap<>(3); syncTimeMap.put("isNew", true); boolean ge = false; if (syncTime != null) { ge = true; } try { //确认有开启物资字典由外向内同步 if (info.getUdiCodeLost() == 2) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.IO_CODE_LOST, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.IO_CODE_LOST, map); List ioCodeLostList = ioCodeLostService.list(Wrappers.lambdaQuery(IoCodeLostEntity.class) .le(!ge && (boolean) map.get("isNew"), IoCodeLostEntity::getUpdateTime, now) .between(ge, IoCodeLostEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), IoCodeLostEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(ioCodeLostList)) { remark.append("UDI缺失码:").append(ioCodeLostList.size()).append("条\n"); jsonMap.put(IoCodeLostEntity.class.getSimpleName(), ioCodeLostList); } } //确认有开启udi关联关系同步 if (info.getUdiCodeRel() == 2) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.IO_CODE_REL, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.IO_CODE_REL, map); List ioCodeRelList = ioCodeRelService.list(Wrappers.lambdaQuery(IoCodeRelEntity.class) .le(!ge && (boolean) map.get("isNew"), IoCodeRelEntity::getUpdateTime, now) .between(ge, IoCodeRelEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), IoCodeRelEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(ioCodeRelList)) { remark.append("UDI码关联关系:").append(ioCodeRelList.size()).append("条\n"); jsonMap.put(IoCodeRelEntity.class.getSimpleName(), ioCodeRelList); } } if (info.getOrderInvoice() == 2) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.ORDER_INVOICE, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.ORDER_INVOICE, map); List orderInvoiceEntities = orderInvoiceService.list(Wrappers.lambdaQuery(IoOrderInvoiceEntity.class) .le(!ge && (boolean) map.get("isNew"), IoOrderInvoiceEntity::getUpdateTime, now) .between(ge, IoOrderInvoiceEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), IoOrderInvoiceEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(orderInvoiceEntities)) { for (IoOrderInvoiceEntity orderInvoiceEntity : orderInvoiceEntities) { if (StrUtil.isNotEmpty(orderInvoiceEntity.getLicenseUrl())) { syncFiles.add(orderInvoiceEntity.getLicenseUrl()); } } if (CollUtil.isNotEmpty(syncFiles)) { jsonMap.put("syncFiles", syncFiles); } remark.append("扫码单据发票信息:").append(orderInvoiceEntities.size()).append("条\n"); jsonMap.put(IoOrderInvoiceEntity.class.getSimpleName(), orderInvoiceEntities); } } if (jsonMap.size() > 0) { jsonMap.put(SYNC_REMARK, remark.toString()); if (!createFile) { return true; } try { String fileFullPath = writeFile(filePath, exportType.getRemark(), JsonUtils.toJsonString(jsonMap)); //计算总数 // int total = 0; // for (List l : jsonMap.values()) { // total += l.size(); // } try { //修改任务数据 boolean update = updateExportStatus(exportType, fileFullPath, remark.toString()); } catch (Exception e) { // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, fileFullPath); } return true; } catch (IOException e) { logger.error(String.format("syncIdcSps----process------------生成[%s]文件及更改库操作异常,异常信息<%s>" , exportType.getRemark(), e.getMessage())); // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, null); } } return false; } catch (Exception e) { logger.error(e.getMessage()); return false; } } private final IBasicBussinessTypeService bussinessTypeService; private final IBasicBusTypeChangeService busTypeChangeService; private final IThrBusTypeOriginService thrBusTypeOriginService; /** * 读取单据类型数据,创建文件 * * @param info 同步设置信息 * @param now 当前时间 * @param createFile 是否创建文件 * @return 是否有数据 true/false 有新数据/无新数据 */ protected boolean generateDocumentTypeDataFile(SyncDataSetResponse info, Date now, boolean createFile, Date syncTime) { StringBuffer remark = new StringBuffer(); List syncFiles = new ArrayList<>(); BasicExportTypeEnum exportType = BasicExportTypeEnum.DOCUMENT_TYPE_DATA; //文件数据 Map jsonMap = new WeakHashMap<>(4); Map> totalTimeMap = new WeakHashMap<>(10); Map syncTimeMap = new WeakHashMap<>(3); syncTimeMap.put("isNew", true); boolean ge = false; if (syncTime != null) { ge = true; } try { //确认有开启业务单据类型同步 if (needExec(info.getTypeBus())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.BASIC_BUSSINESS_TYPE, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.BASIC_BUSSINESS_TYPE, map); List bussinessTypeEntities = bussinessTypeService.list(Wrappers.lambdaQuery(BasicBussinessTypeEntity.class) .le(!ge && (boolean) map.get("isNew"), BasicBussinessTypeEntity::getUpdateTime, now) .between(ge, BasicBussinessTypeEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), BasicBussinessTypeEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(bussinessTypeEntities)) { remark.append("扫码单据类型:").append(bussinessTypeEntities.size()).append("条\n"); jsonMap.put(BasicBussinessTypeEntity.class.getSimpleName(), bussinessTypeEntities); } } //确认有开启扫码单据类型同步 if (needExec(info.getTypeScan())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.BASIC_BUSTYPE_CHANGE, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.BASIC_BUSTYPE_CHANGE, map); List busTypeChangeEntities = busTypeChangeService.list(Wrappers.lambdaQuery(BasicBusTypeChangeEntity.class) .le(!ge && (boolean) map.get("isNew"), BasicBusTypeChangeEntity::getUpdateTime, now) .between(ge, BasicBusTypeChangeEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), BasicBusTypeChangeEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(busTypeChangeEntities)) { remark.append("业务单据类型:").append(busTypeChangeEntities.size()).append("条\n"); jsonMap.put(BasicBusTypeChangeEntity.class.getSimpleName(), busTypeChangeEntities); } } //确认有开启第三方单据类型同步 if (needExec(info.getTypeThird())) { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.THR_BUSTYPE_ORIGIN, createFile); totalTimeMap.put(BasicExportStatusTimeEnum.THR_BUSTYPE_ORIGIN, map); List thrBusTypeOriginEntities = thrBusTypeOriginService.list(Wrappers.lambdaQuery(ThrBusTypeOriginEntity.class) .le(!ge && (boolean) map.get("isNew"), ThrBusTypeOriginEntity::getUpdateTime, now) .between(ge, ThrBusTypeOriginEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), ThrBusTypeOriginEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(thrBusTypeOriginEntities)) { remark.append("第三方单据类型:").append(thrBusTypeOriginEntities.size()).append("条\n"); jsonMap.put(ThrBusTypeOriginEntity.class.getSimpleName(), thrBusTypeOriginEntities); } } if (jsonMap.size() > 0) { jsonMap.put(SYNC_REMARK, remark.toString()); if (!createFile) { return true; } try { String fileFullPath = writeFile(filePath, exportType.getRemark(), JsonUtils.toJsonString(jsonMap)); //计算总数 // int total = 0; // for (List l : jsonMap.values()) { // total += l.size(); // } try { //修改任务数据 boolean update = updateExportStatus(exportType, fileFullPath, remark.toString()); } catch (Exception e) { // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, fileFullPath); } return true; } catch (IOException e) { logger.error(String.format("syncIdcSps----process------------生成[%s]文件及更改库操作异常,异常信息<%s>" , exportType.getRemark(), e.getMessage())); // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, null); } } return false; } catch (Exception e) { logger.error(e.getMessage()); return false; } } @Resource DeviceInspectTaskService deviceInspectTaskService; @Resource DeviceInspectTaskDetailService deviceInspectTaskDetailService; /** * 读取设备任务数据,创建文件 */ protected boolean generateDevTaskDataFile(SyncDataSetResponse info, Date now, boolean createFile, Date syncTime) { StringBuffer remark = new StringBuffer(); BasicExportTypeEnum exportType = BasicExportTypeEnum.DEVICE_TASK; List syncFiles = new ArrayList<>(); Map jsonMap = new WeakHashMap<>(4); Map> totalTimeMap = new WeakHashMap<>(10); Map syncTimeMap = new WeakHashMap<>(3); syncTimeMap.put("isNew", true); boolean ge = false; if (syncTime != null) { ge = true; } try { Map map = basicExportStatusTimeInfo(now, BasicExportStatusTimeEnum.DEVICE_TASK, createFile); List deviceInspectTaskEntities = deviceInspectTaskService.list(Wrappers.lambdaQuery(DeviceInspectTaskEntity.class) .le(!ge && (boolean) map.get("isNew"), DeviceInspectTaskEntity::getUpdateTime, now) .between(ge, DeviceInspectTaskEntity::getUpdateTime, syncTime, now) .between(!ge && !(boolean) map.get("isNew"), DeviceInspectTaskEntity::getUpdateTime , map.get("oldDate"), now) ); if (CollectionUtil.isNotEmpty(deviceInspectTaskEntities)) { remark.append("设备任务主表:").append(deviceInspectTaskEntities.size()).append("条\n"); jsonMap.put(DeviceInspectTaskEntity.class.getSimpleName(), deviceInspectTaskEntities); List datas = new ArrayList<>(); for (DeviceInspectTaskEntity deviceInspectTaskEntity : deviceInspectTaskEntities) { List deviceInspectTaskDetailEntities = deviceInspectTaskDetailService.list(new QueryWrapper().eq("taskOrderIdFk", deviceInspectTaskEntity.getOrderId())); datas.addAll(deviceInspectTaskDetailEntities); for (DeviceInspectTaskDetailEntity detailEntity : deviceInspectTaskDetailEntities) { if (StrUtil.isNotEmpty(detailEntity.getInspectImage())) { syncFiles.add(filePath + detailEntity.getInspectImage().replace(",", "")); } } } if (CollectionUtil.isNotEmpty(datas)) { remark.append("设备任务字表:").append(datas.size()).append("条\n"); jsonMap.put(DeviceInspectTaskDetailEntity.class.getSimpleName(), datas); } if (CollUtil.isNotEmpty(syncFiles)) { jsonMap.put("syncFiles", syncFiles); } } if (jsonMap.size() > 0) { jsonMap.put(SYNC_REMARK, remark.toString()); if (!createFile) { return true; } try { String fileFullPath = writeFile(filePath, exportType.getRemark(), JsonUtils.toJsonString(jsonMap)); try { //修改任务数据 boolean update = updateExportStatus(exportType, fileFullPath, remark.toString()); } catch (Exception e) { // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, fileFullPath); } return true; } catch (IOException e) { logger.error(String.format("syncIdcSps----process------------生成[%s]文件及更改库操作异常,异常信息<%s>" , exportType.getRemark(), e.getMessage())); // 异常回滚 this.exportTimeRollback(totalTimeMap, exportType, null); } } return false; } catch ( Exception e) { logger.error(e.getMessage()); return false; } } /** * 插入 basicExportStatusTime表 * * @param date 当前时间 * @param exportStatusTimeEnum key枚举 * @param createFile 是否需要创建文件,false时只做查询 * @return 最后一次同步时间 返回值需与参数 date 比较,判断是否相等 * @throws Exception */ private Map basicExportStatusTimeInfo(Date date, BasicExportStatusTimeEnum exportStatusTimeEnum, boolean createFile) throws Exception { //防止出现同时调用问题 String redisKey = String.format("spsm-sync-task:%s", exportStatusTimeEnum.getKey()); boolean result = redisUtil.setIfAbsent(redisKey, 1, 10); if (!result) { String errorMsg = String.format("syncIdcSps----process------------同步[%s]重复进入", exportStatusTimeEnum.getRemark()); // logger.info(errorMsg); throw new Exception(errorMsg); } boolean isNew = true; BasicExportStatusTimeEntity timeInfo = basicExportTimeService.getOne(Wrappers.lambdaQuery(BasicExportStatusTimeEntity.class) .eq(BasicExportStatusTimeEntity::getKey, exportStatusTimeEnum.getKey())); if (timeInfo == null) { if (createFile) { timeInfo = BasicExportStatusTimeEntity.builder() .key(exportStatusTimeEnum.getKey()) .lastUpdateTime(DateUtil.formatDateTime(date)) .remark(exportStatusTimeEnum.getRemark()) .build(); basicExportTimeService.save(timeInfo); } } else { if (StrUtil.isNotEmpty(timeInfo.getLastUpdateTime())) { isNew = false; } if (createFile) { basicExportTimeService.update(Wrappers.lambdaUpdate(BasicExportStatusTimeEntity.class) .set(BasicExportStatusTimeEntity::getLastUpdateTime, DateUtil.formatDateTime(date)) .eq(BasicExportStatusTimeEntity::getKey, exportStatusTimeEnum.getKey()) ); } } redisUtil.del(redisKey); WeakHashMap returnMap = new WeakHashMap<>(10); returnMap.put("isNew", isNew); returnMap.put("oldDate", isNew ? null : timeInfo.getLastUpdateTime()); if (createFile) { returnMap.put("id", timeInfo.getId()); } return returnMap; } /** * 修改任务数据 * * @param exportType 任务类型 * @param fileFullPath 文件地址 * @return 更新结果 true/false */ private boolean updateExportStatus(BasicExportTypeEnum exportType, String fileFullPath, String remark) { return basicExportService.update(Wrappers.lambdaUpdate(BasicExportStatusEntity.class) .set(BasicExportStatusEntity::getStatus, BasicExportStatusEnum.WAIT_SYNC.getCode()) .set(BasicExportStatusEntity::getUpdateTime, new Date()) .set(BasicExportStatusEntity::getCacheFilePath, fileFullPath) .set(BasicExportStatusEntity::getRemark, remark) .eq(BasicExportStatusEntity::getType, exportType.getRemark()) .eq(BasicExportStatusEntity::getStatus, BasicExportStatusEnum.WAIT_BUILT.getCode()) .isNull(BasicExportStatusEntity::getCacheFilePath) ); } /** * 异常回滚操作 * * @param totalTimeMap 总的exportTime数据回滚 * @param delFilePath 需要删除的文件地址 */ private void exportTimeRollback(Map> totalTimeMap, BasicExportTypeEnum exportType, String delFilePath) { for (Map.Entry> entry : totalTimeMap.entrySet()) { //防止出现同时调用问题 String redisKey = String.format("spsm-sync-rollback:%s", entry.getKey().getKey()); boolean result = redisUtil.setIfAbsent(redisKey, 1, 10); if (!result) { String errorMsg = String.format("syncIdcSps----process------------同步回滚[%s]重复进入", entry.getKey().getRemark()); logger.error(errorMsg); } if ((boolean) entry.getValue().get("isNew")) { basicExportTimeService.deleteById(entry.getValue().get("id").toString()); } else { basicExportTimeService.update(Wrappers.lambdaUpdate(BasicExportStatusTimeEntity.class) .set(BasicExportStatusTimeEntity::getLastUpdateTime, entry.getValue().get("oldDate")) .eq(BasicExportStatusTimeEntity::getKey, entry.getKey().getKey()) .eq(BasicExportStatusTimeEntity::getId, entry.getValue().get("id")) ); } } if (StrUtil.isNotBlank(delFilePath)) { try { File file = new File(delFilePath); file.deleteOnExit(); } catch (Exception e) { String errorMsg = String.format("syncIdcSps----process------------同步回滚[%s]删除文件异常", exportType.getRemark()); logger.error(errorMsg); } } } private String writeFile(String filePath, String fileDesc, String content) throws IOException { filePath = String.format("%s/%s", filePath, DateUtil.getDate()); String fileFullPath = String.format("%s/%s-%s.udi", filePath, fileDesc, IdUtil.fastSimpleUUID()); File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } file = new File(fileFullPath); while (!file.createNewFile()) { fileFullPath = String.format("%s/%s/%s-%s.udi", filePath, DateUtil.getDate(), fileDesc, IdUtil.fastSimpleUUID()); file = new File(fileFullPath); } FileWriter fileWriter = new FileWriter(file); fileWriter.write(content); fileWriter.flush(); fileWriter.close(); return fileFullPath; } //获取需要同步信息 public BaseResponse findOrder(SpsSyncDataRequest spsSyncDataRequest) { SpsSyncOrderResponse syncOrderResponse = new SpsSyncOrderResponse(); //查询数据同步设置 List orderEntities = new ArrayList<>(); if (StrUtil.isEmpty(spsSyncDataRequest.getBillNo())) { SyncDataSetResponse syncDataSetEntity = syncDataSetService.selectSet(); FilterOrderRequest orderFilterRequest = new FilterOrderRequest(); BeanUtils.copyProperties(spsSyncDataRequest, orderFilterRequest); if (CollUtil.isNotEmpty(syncDataSetEntity.getToInBusTypes())) { for (SyncDataBustypeEntity syncDataBustypeEntity : syncDataSetEntity.getToInBusTypes()) { List temps = orderService.findByStatus(syncDataBustypeEntity.getAction(), syncDataBustypeEntity.getOrderStatus(), DateUtil.parseDate(spsSyncDataRequest.getLastUpdateTime())); if (CollUtil.isNotEmpty(temps)) { orderEntities.addAll(temps); } } } } else { IoOrderEntity orderEntity = orderService.findByBillNo(spsSyncDataRequest.getBillNo()); orderEntities.add(orderEntity); } syncOrderResponse.setOrderEntities(orderEntities); List codeEntities = new ArrayList<>(); List orderDetailBizEntities = new ArrayList<>(); List orderDetailCodeEntities = new ArrayList<>(); List orderDetailResultEntities = new ArrayList<>(); List orderInvoiceEntities = new ArrayList<>(); List syncFiles = new ArrayList<>(); if (CollUtil.isNotEmpty(orderEntities)) { for (IoOrderEntity orderEntity : orderEntities) { List codes = codesService.findByOrderId(orderEntity.getBillNo()); if (CollUtil.isNotEmpty(codes)) { codeEntities.addAll(codes); } List bizEntities = orderDetailBizService.findByOrderId(orderEntity.getBillNo()); if (CollUtil.isNotEmpty(bizEntities)) { orderDetailBizEntities.addAll(bizEntities); for (IoOrderDetailBizEntity bizEntity : bizEntities) { if (StrUtil.isNotEmpty(bizEntity.getFilePath())) { String[] fileNames = bizEntity.getFilePath().split(","); syncFiles.addAll(CollUtil.toList(fileNames)); } if (StrUtil.isNotEmpty(bizEntity.getColdFilePath())) { String[] fileNames = bizEntity.getColdFilePath().split(","); syncFiles.addAll(CollUtil.toList(fileNames)); } } } List detailCodeEntities = orderDetailCodeService.findByOrderId(orderEntity.getBillNo()); if (CollUtil.isNotEmpty(detailCodeEntities)) { orderDetailCodeEntities.addAll(detailCodeEntities); } List detailResultEntities = orderDetailResultService.findByOrderId(orderEntity.getBillNo()); if (CollUtil.isNotEmpty(detailResultEntities)) { orderDetailResultEntities.addAll(detailResultEntities); } List invoiceEntities = orderInvoiceService.findByBillNo(orderEntity.getBillNo()); if (CollUtil.isNotEmpty(invoiceEntities)) { for (IoOrderInvoiceEntity orderInvoiceEntity : invoiceEntities) { if (StrUtil.isNotEmpty(orderInvoiceEntity.getLicenseUrl())) { syncFiles.add(orderInvoiceEntity.getLicenseUrl()); } } orderInvoiceEntities.addAll(invoiceEntities); } } } String logs = ""; logs = logs + "扫码单据信息:" + orderEntities.size() + "条\n"; logs = logs + "单据业务详情信息:" + orderDetailBizEntities.size() + "条\n"; logs = logs + "单据扫码详情信息:" + orderDetailCodeEntities.size() + "条\n"; logs = logs + "单据校验结果信息:" + orderDetailResultEntities.size() + "条\n"; logs = logs + "发票信息:" + orderInvoiceEntities.size() + "条\n"; logs = logs + "扫码信息:" + codeEntities.size() + "条\n"; syncOrderResponse.setSyncRemark(logs); syncOrderResponse.setSyncFiles(syncFiles); syncOrderResponse.setCodeEntities(codeEntities); syncOrderResponse.setOrderDetailBizEntities(orderDetailBizEntities); syncOrderResponse.setOrderDetailCodeEntities(orderDetailCodeEntities); syncOrderResponse.setOrderDetailResultEntities(orderDetailResultEntities); syncOrderResponse.setOrderInvoiceEntities(orderInvoiceEntities); return ResultVOUtils.success(syncOrderResponse); } // 获取需要同步国家库数据 @Resource ProductInfoService productInfoService; @Resource UdiCompanyService udiCompanyService; //udi同步数据 public BaseResponse syncUdi(SpsSyncDataRequest spsSyncDataRequest) { SpSyncUdiResponse spSyncUdiResponse = new SpSyncUdiResponse(); SyncDataSetResponse syncDataSetEntity = syncDataSetService.selectSet(); if (syncDataSetEntity.getDbDiProducts() == 2) { ProductInfoFilterRequest productInfoFilterRequest = new ProductInfoFilterRequest(); BeanUtils.copyProperties(spsSyncDataRequest, productInfoFilterRequest); productInfoFilterRequest.setUpdateTime(spsSyncDataRequest.getLastUpdateTime()); List productInfoEntityList = productInfoService.syncDlUdi(productInfoFilterRequest); spSyncUdiResponse.setProductInfoEntityList(productInfoEntityList); } if (syncDataSetEntity.getDbDiCompany() == 2) { UdiCompanyRequest udiCompanyRequest = new UdiCompanyRequest(); BeanUtils.copyProperties(spsSyncDataRequest, udiCompanyRequest); udiCompanyRequest.setUpdateTime(spsSyncDataRequest.getLastUpdateTime()); List udiCompanyEntities = udiCompanyService.syncDlCompany(udiCompanyRequest); spSyncUdiResponse.setUdiCompanyEntities(udiCompanyEntities); } return ResultVOUtils.success(spSyncUdiResponse); } public SpsSyncDataRequest getRequest(String type) { SpsSyncDataRequest spsSyncDataRequest = new SpsSyncDataRequest(); spsSyncDataRequest.setPage(1); spsSyncDataRequest.setLimit(1); BasicExportStatusTimeEntity basicExportStatusTimeEntity = basicExportTimeService.findByType(type); spsSyncDataRequest.setLastUpdateTime(basicExportStatusTimeEntity.getLastUpdateTime()); return spsSyncDataRequest; } }