diff --git a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/LarkHelper/LarkHelper.java b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/LarkHelper/LarkHelper.java index 67cc74d..162fa7a 100644 --- a/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/LarkHelper/LarkHelper.java +++ b/ruoyi-flyingbook/src/main/java/com/ruoyi/flyingbook/LarkHelper/LarkHelper.java @@ -3,6 +3,8 @@ package com.ruoyi.flyingbook.LarkHelper; import com.lark.oapi.Client; import com.lark.oapi.core.cache.ICache; import com.lark.oapi.core.enums.AppType; +import com.lark.oapi.core.httpclient.OkHttpTransport; +import com.lark.oapi.okhttp.OkHttpClient; import com.lark.oapi.service.bitable.v1.model.*; import com.ruoyi.flyingbook.domain.lark.LarkRequest; import lombok.extern.slf4j.Slf4j; @@ -10,6 +12,7 @@ import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * @author yuxiangyong @@ -32,6 +35,17 @@ public class LarkHelper { return Client.newBuilder(request.getAppId(), request.getAppSecret()) .marketplaceApp() .appType(AppType.SELF_BUILT) + .httpTransport(okHttpTransport()) .build(); } + + public OkHttpTransport okHttpTransport() { + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .connectTimeout(20, TimeUnit.SECONDS) + .writeTimeout(100, TimeUnit.SECONDS) + .readTimeout(100, TimeUnit.SECONDS) + .build(); + OkHttpTransport okHttpTransport = new OkHttpTransport(okHttpClient); + return okHttpTransport; + } } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/ManufactureOrderSyncJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/ManufactureOrderSyncJob.java index 261989c..8bff354 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/ManufactureOrderSyncJob.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/ManufactureOrderSyncJob.java @@ -58,7 +58,9 @@ public class ManufactureOrderSyncJob extends SyncAccountsJobAbstract { return Arrays.asList( "code", "manufactureorderdetails_inventory_code", - "manufactureorderdetails_pubuserdefnvc2"); + "manufactureorderdetails_pubuserdefnvc2", + "manufactureorderdetails_quantity", + "manufactureorderdetails_sourcevouchercode"); } @Override diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/PurchaseArrivalOpenSyncJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/PurchaseArrivalOpenSyncJob.java index 6dcc9ea..d77bdd4 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/PurchaseArrivalOpenSyncJob.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/PurchaseArrivalOpenSyncJob.java @@ -1,6 +1,7 @@ package com.ruoyi.quartz.task.CJT; import com.ruoyi.common.enums.AppType; +import com.ruoyi.common.enums.CjtAccountEnum; import com.ruoyi.common.enums.TableFieldTypeEnum; import com.ruoyi.common.enums.TableRelationTypeEnum; import com.ruoyi.common.utils.DateUtils; @@ -44,10 +45,19 @@ public class PurchaseArrivalOpenSyncJob extends SyncAccountsJobAbstract{ @Override protected List getUniqueFields(String cjt) { + CjtAccountEnum cjtAccountEnum = CjtAccountEnum.getByCode(cjt); + if (cjtAccountEnum != null && cjtAccountEnum.equals(CjtAccountEnum.TWO)){ + return Arrays.asList( + "code", + "details_inventory_code", + "details_detailmemo"); + + } return Arrays.asList( "code", "details_inventory_code", - "details_detailmemo"); + "details_detailmemo", + "details_quantity"); } @Override diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleDeliverySyncJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleDeliverySyncJob.java index 900011f..e1efd8b 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleDeliverySyncJob.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleDeliverySyncJob.java @@ -54,13 +54,15 @@ public class SaleDeliverySyncJob extends SyncAccountsJobAbstract { "saledeliverydetails_saleordercode",//销售订单号 "saledeliverydetails_inventory_code",//存货编码 "saledeliverydetails_quantity",//数量 - "memo");//备注1 + "memo",//备注1 + "saledeliverydetails_detailmemo");//明细备注1 } List list = new ArrayList<>(Arrays.asList( "code",//单据编号 "saledeliverydetails_inventory_code", - "saledeliverydetails_detailmemo")); + "saledeliverydetails_detailmemo", + "saledeliverydetails_quantity")); return list; } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleOrderSyncJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleOrderSyncJob.java index eca95e5..8cf5442 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleOrderSyncJob.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SaleOrderSyncJob.java @@ -52,13 +52,15 @@ public class SaleOrderSyncJob extends SyncAccountsJobAbstract{ "code",//编号 "saleorderdetails_inventory_code",//存货编码 "saleorderdetails_pubuserdefnvc1",//钢板面 - "saleorderdetails_detailmemo");//明细备注 + "saleorderdetails_detailmemo",//明细备注 + "saleorderdetails_quantity");//数量 } List list = Arrays.asList( "code", "saleorderdetails_inventory_code", - "saleorderdetails_detailmemo"); + "saleorderdetails_detailmemo", + "saleorderdetails_quantity"); return list; } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SyncAccountsJobAbstract.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SyncAccountsJobAbstract.java index 130b2d1..682a5f8 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SyncAccountsJobAbstract.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/CJT/SyncAccountsJobAbstract.java @@ -2,6 +2,7 @@ package com.ruoyi.quartz.task.CJT; import com.alibaba.fastjson.JSONObject; import com.lark.oapi.core.utils.Lists; +import com.lark.oapi.service.bitable.v1.model.AppTableRecord; import com.lark.oapi.service.bitable.v1.model.CreateAppTableRecordRespBody; import com.ruoyi.common.constant.RedisConstants; import com.ruoyi.common.core.redis.RedisCache; @@ -10,6 +11,7 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.flyingbook.LarkHelper.LarkRobotHelper; import com.ruoyi.flyingbook.LarkHelper.LarkTableHelper; import com.ruoyi.flyingbook.domain.ErpLarkRelation; +import com.ruoyi.flyingbook.domain.ErpLarkTempRelation; import com.ruoyi.flyingbook.domain.LarkCompanyRelation; import com.ruoyi.flyingbook.domain.LarkTableRelation; import com.ruoyi.flyingbook.domain.lark.LarkTableRequest; @@ -62,7 +64,7 @@ public abstract class SyncAccountsJobAbstract { /** * 分页条数 */ - protected static final Integer PAGE_SIZE = 20; + protected static final Integer PAGE_SIZE = 50; public static final String RETRY_KEY = "RETRY_CJT:%s:%s"; @@ -82,43 +84,43 @@ public abstract class SyncAccountsJobAbstract { private Boolean asynchronousCheck(LocalDateTime now, String cjt) { int hour = now.getHour(); - if (hour != 1) { - return Boolean.FALSE; - } - //目前只给畅捷通账号二加工单开补偿劝降 - if ((AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE.getCode().equals(syncLarkAppType().getCode()) - && CjtAccountEnum.TWO.getCode().equals(cjt)) || (AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.getCode().equals(syncLarkAppType().getCode()) - && CjtAccountEnum.ONE.getCode().equals(cjt))){ - String asynchronous = getAsynchronousKey(cjt); - Object cacheObject = redisCache.getCacheObject(asynchronous); - if (cacheObject != null) { - return Boolean.FALSE; + if ((hour == 0 && CjtAccountEnum.ONE.getCode().equals(cjt)) + || (hour == 1 && CjtAccountEnum.TWO.getCode().equals(cjt))) { + //目前只给畅捷通账号二加工单开补偿劝降 + if ((AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE.getCode().equals(syncLarkAppType().getCode()) + && CjtAccountEnum.TWO.getCode().equals(cjt)) || (AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.getCode().equals(syncLarkAppType().getCode()) + && CjtAccountEnum.ONE.getCode().equals(cjt))) { + String asynchronous = getAsynchronousKey(cjt); + Object cacheObject = redisCache.getCacheObject(asynchronous); + if (cacheObject != null) { + return Boolean.FALSE; + } + redisCache.setCacheObject(asynchronous, asynchronous, 2, TimeUnit.HOURS); + return Boolean.TRUE; + } else { + return false; } - redisCache.setCacheObject(asynchronous, asynchronous, 2, TimeUnit.HOURS); - return Boolean.TRUE; - }else { - return false; } + return false; } - private String getAsynchronousKey(String cjt){ - return String.format("%s:%s:%s", RedisConstants.CJT_ASYNCHRONOUS, syncLarkAppType().getCode(), cjt); + private String getAsynchronousKey(String cjt) { + return String.format("%s:%s:%s", RedisConstants.CJT_ASYNCHRONOUS, syncLarkAppType().getCode(), cjt); } private CJTJobContext initContext(String queryFromTime, String queryToTime, LocalDateTime now, String cjt) { CJTJobContext context = new CJTJobContext(); Boolean asynchronous = asynchronousCheck(now, cjt); context.setAsynchronous(asynchronous); - LocalDate localDate = LocalDate.now().minusDays(1L); if (StringUtils.isEmpty(queryFromTime)) { queryFromTime = asynchronous - ? DateUtils.startOfDate(localDate) + ? DateUtils.startOfDate(LocalDate.now().minusDays(8L)) : DateUtils.ldt2str(now.minusMinutes(REDUCE_MINUTES), DateUtils.YYYY_MM_DD_HH_MM_SS); } context.setQueryFromTime(queryFromTime); if (StringUtils.isEmpty(queryToTime)) { queryToTime = asynchronous - ? DateUtils.endOfDate(localDate) + ? DateUtils.endOfDate(LocalDate.now().minusDays(1L)) : DateUtils.ldt2str(now, DateUtils.YYYY_MM_DD_HH_MM_SS); } context.setQueryToTime(queryToTime); @@ -168,12 +170,12 @@ public abstract class SyncAccountsJobAbstract { log.info("===================== {} strat ======================", this.getClassName()); //初始化飞书信息及相关配置 initLarkInfo(context); - if (Boolean.TRUE.equals(context.getAsynchronous())) { - Boolean deleteSuccess = handleRepeatData(now, cjt, context); - if (!deleteSuccess){ - return; - } - } +// if (Boolean.TRUE.equals(context.getAsynchronous())) { +// Boolean deleteSuccess = handleRepeatData(now, cjt, context); +// if (!deleteSuccess){ +// return; +// } +// } //重置ticket resetTicket(context); //执行分页同步 @@ -183,7 +185,7 @@ public abstract class SyncAccountsJobAbstract { if (Boolean.TRUE.equals(context.getAsynchronous())) { String asynchronous = getAsynchronousKey(cjt); redisCache.deleteObject(asynchronous); - }else { + } else { CJTRetryRequest request = new CJTRetryRequest(now, 1, cjt); redisCache.rightPush(getRetryKey(cjt), request); } @@ -200,24 +202,24 @@ public abstract class SyncAccountsJobAbstract { try { LarkCompanyRelation companyRelation = context.getCompanyRelation(); LarkTableRelation tableRelation = context.getTableRelation(); - LarkTableRequest request = new LarkTableRequest(companyRelation.getAppId(),companyRelation.getSecret(),tableRelation.getToAppToken(),tableRelation.getToTableId()); + LarkTableRequest request = new LarkTableRequest(companyRelation.getAppId(), companyRelation.getSecret(), tableRelation.getToAppToken(), tableRelation.getToTableId()); String date = DateUtils.ldt2str(now.minusDays(1L), DateUtils.YYYY_MM_DD); List recordList = erpLarkRelationMapper.queryWaitDeleteRecordList(date, getRequestUrl(), cjt); List waitDeleteList = new ArrayList<>(); for (String record : recordList) { waitDeleteList.add(record); - if (waitDeleteList.size() == 500){ + if (waitDeleteList.size() == 500) { request.setRecords(waitDeleteList.toArray(new String[0])); larkTableHelper.deleteTableRecordBatch(request); waitDeleteList = new ArrayList<>(); } } - if (!CollectionUtils.isEmpty(waitDeleteList)){ + if (!CollectionUtils.isEmpty(waitDeleteList)) { request.setRecords(waitDeleteList.toArray(new String[0])); larkTableHelper.deleteTableRecordBatch(request); } erpLarkRelationMapper.deleteRecordList(date, getRequestUrl(), cjt); - }catch (Exception e){ + } catch (Exception e) { return Boolean.FALSE; } return Boolean.TRUE; @@ -355,9 +357,9 @@ public abstract class SyncAccountsJobAbstract { //实际返回数据 rows = response.getRows(); if (!CollectionUtils.isEmpty(rows)) { - Map existKeyMap = getExistKeyMap(cjtRequest, response.getColumns(), rows, context.getCjt(),addRecordRequest); + Map existKeyMap = getExistKeyMap(cjtRequest, response.getColumns(), rows, context.getCjt(), addRecordRequest); //批量同步飞书 - List errorCodeList = syncLarkBatch(response.getColumns(), rows, existKeyMap, addRecordRequest, context.getCjt(),context.getAsynchronous()); + List errorCodeList = syncLarkBatch(response.getColumns(), rows, existKeyMap, addRecordRequest, context.getCjt(), context.getAsynchronous()); if (!CollectionUtils.isEmpty(errorCodeList)) { String errorKey = String.join(",", errorCodeList); throw new RuntimeException(String.format("存在同步失败的记录 %s", errorKey)); @@ -375,7 +377,7 @@ public abstract class SyncAccountsJobAbstract { } } - private List getUniqueKey(List keyList, List> rows, String cjt, LarkTableRequest addRecordRequest ) { + private List getUniqueKey(List keyList, List> rows, String cjt, LarkTableRequest addRecordRequest) { //组成唯一键的集合 List uniqueFields = getUniqueFields(cjt); List result = new ArrayList<>(); @@ -387,7 +389,7 @@ public abstract class SyncAccountsJobAbstract { midList.add(row.get(i)); } } - String uniqueKey = String.join("_", midList).toUpperCase()+"_" + addRecordRequest.getAppTable(); + String uniqueKey = String.join("_", midList).toUpperCase() + "_" + addRecordRequest.getAppTable(); result.add(uniqueKey); } } @@ -401,7 +403,7 @@ public abstract class SyncAccountsJobAbstract { if (CollectionUtils.isEmpty(rows)) { return new HashMap<>(); } - List uniqueKeyList = getUniqueKey(keyList, rows, cjt,addRecordRequest); + List uniqueKeyList = getUniqueKey(keyList, rows, cjt, addRecordRequest); if (CollectionUtils.isEmpty(uniqueKeyList)) { return new HashMap<>(); } @@ -430,7 +432,7 @@ public abstract class SyncAccountsJobAbstract { * 执行字段映射 */ protected List syncLarkBatch(List keyList, List> rows, Map existKeyMap - , LarkTableRequest addRecordRequest, String cjt,Boolean asynchronous) { + , LarkTableRequest addRecordRequest, String cjt, Boolean asynchronous) { List relationList = new ArrayList<>(); //查询字段与飞书字段的对应关系 Map queryFieldsMap = getQueryFieldsMap(cjt); @@ -440,6 +442,7 @@ public abstract class SyncAccountsJobAbstract { List errorKey = new ArrayList<>(); //判断当前查询条件内是否存在重复数据 Map repeatMap = new HashMap<>(); + List waitUpdateList = new ArrayList<>(); for (List row : rows) { String uniqueKey = null; try { @@ -457,7 +460,7 @@ public abstract class SyncAccountsJobAbstract { } body.put(larkLabel, this.changeValueType(value, cjtSyncTypeRelation)); } - uniqueKey = String.join("_", uniqueKeyList).toUpperCase()+"_"+addRecordRequest.getAppTable(); + uniqueKey = String.join("_", uniqueKeyList).toUpperCase() + "_" + addRecordRequest.getAppTable(); if (repeatMap.containsKey(uniqueKey)) { continue; } @@ -468,13 +471,14 @@ public abstract class SyncAccountsJobAbstract { //在飞书创建一行,并根据创建返回的行id在本地保留一条映射纪律 CreateAppTableRecordRespBody respBody = larkTableHelper.addTableRecord(addRecordRequest); larkKey = respBody.getRecord().getRecordId(); - relationList.add(buildErpLarkRelation(uniqueKey, larkKey, cjt,asynchronous)); + relationList.add(buildErpLarkRelation(uniqueKey, larkKey, cjt, asynchronous)); } else { if (!AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.equals(syncLarkAppType())) { //根据本地保留映射,确认飞书的更新行,更新后防止影响后续更新,需要将行id进行置空 - addRecordRequest.setRecord(larkKey); - larkTableHelper.updateTableRecord(addRecordRequest); - addRecordRequest.setRecord(null); + AppTableRecord appTableRecord = new AppTableRecord(); + appTableRecord.setFields(body); + appTableRecord.setRecordId(larkKey); + waitUpdateList.add(appTableRecord); } } } catch (Exception e) { @@ -482,14 +486,26 @@ public abstract class SyncAccountsJobAbstract { errorKey.add(String.format("【%s,%s】", uniqueKey, e.getMessage())); } } + if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(waitUpdateList)) { + addRecordRequest.setAppTableRecords(waitUpdateList.toArray(new AppTableRecord[0])); + updateTableRecordBatch(addRecordRequest); + } if (!CollectionUtils.isEmpty(relationList)) { erpLarkRelationMapper.batchInsert(relationList); } return errorKey; } + private void updateTableRecordBatch(LarkTableRequest addRecordRequest) { + try { + larkTableHelper.updateTableRecordBatch(addRecordRequest); + } catch (Exception e) { + log.error("批量更新失败"); + } + } + //构建飞书行与cjt唯一键的对应关系对象 - private ErpLarkRelation buildErpLarkRelation(String key, String larkKey, String cjt,Boolean asynchronous) { + private ErpLarkRelation buildErpLarkRelation(String key, String larkKey, String cjt, Boolean asynchronous) { ErpLarkRelation erpLarkRelation = new ErpLarkRelation(); erpLarkRelation.setKey(key); erpLarkRelation.setLarkKey(larkKey); @@ -498,7 +514,7 @@ public abstract class SyncAccountsJobAbstract { erpLarkRelation.setRemark(cjt); erpLarkRelation.setCreateBy("SYSTEM"); Date date = new Date(); - if (Boolean.TRUE.equals(asynchronous)){ + if (Boolean.TRUE.equals(asynchronous)) { LocalDateTime localDateTime = LocalDateTime.now().minusDays(1L); date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); }