|
|
|
@ -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,13 +84,12 @@ public abstract class SyncAccountsJobAbstract {
|
|
|
|
|
|
|
|
|
|
private Boolean asynchronousCheck(LocalDateTime now, String cjt) {
|
|
|
|
|
int hour = now.getHour();
|
|
|
|
|
if (hour != 1) {
|
|
|
|
|
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))){
|
|
|
|
|
&& CjtAccountEnum.ONE.getCode().equals(cjt))) {
|
|
|
|
|
String asynchronous = getAsynchronousKey(cjt);
|
|
|
|
|
Object cacheObject = redisCache.getCacheObject(asynchronous);
|
|
|
|
|
if (cacheObject != null) {
|
|
|
|
@ -96,12 +97,14 @@ public abstract class SyncAccountsJobAbstract {
|
|
|
|
|
}
|
|
|
|
|
redisCache.setCacheObject(asynchronous, asynchronous, 2, TimeUnit.HOURS);
|
|
|
|
|
return Boolean.TRUE;
|
|
|
|
|
}else {
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getAsynchronousKey(String cjt){
|
|
|
|
|
private String getAsynchronousKey(String cjt) {
|
|
|
|
|
return String.format("%s:%s:%s", RedisConstants.CJT_ASYNCHRONOUS, syncLarkAppType().getCode(), cjt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -109,16 +112,15 @@ public abstract class SyncAccountsJobAbstract {
|
|
|
|
|
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<String> recordList = erpLarkRelationMapper.queryWaitDeleteRecordList(date, getRequestUrl(), cjt);
|
|
|
|
|
List<String> 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<String, String> existKeyMap = getExistKeyMap(cjtRequest, response.getColumns(), rows, context.getCjt(),addRecordRequest);
|
|
|
|
|
Map<String, String> existKeyMap = getExistKeyMap(cjtRequest, response.getColumns(), rows, context.getCjt(), addRecordRequest);
|
|
|
|
|
//批量同步飞书
|
|
|
|
|
List<String> errorCodeList = syncLarkBatch(response.getColumns(), rows, existKeyMap, addRecordRequest, context.getCjt(),context.getAsynchronous());
|
|
|
|
|
List<String> 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<String> getUniqueKey(List<String> keyList, List<List<String>> rows, String cjt, LarkTableRequest addRecordRequest ) {
|
|
|
|
|
private List<String> getUniqueKey(List<String> keyList, List<List<String>> rows, String cjt, LarkTableRequest addRecordRequest) {
|
|
|
|
|
//组成唯一键的集合
|
|
|
|
|
List<String> uniqueFields = getUniqueFields(cjt);
|
|
|
|
|
List<String> 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<String> uniqueKeyList = getUniqueKey(keyList, rows, cjt,addRecordRequest);
|
|
|
|
|
List<String> uniqueKeyList = getUniqueKey(keyList, rows, cjt, addRecordRequest);
|
|
|
|
|
if (CollectionUtils.isEmpty(uniqueKeyList)) {
|
|
|
|
|
return new HashMap<>();
|
|
|
|
|
}
|
|
|
|
@ -430,7 +432,7 @@ public abstract class SyncAccountsJobAbstract {
|
|
|
|
|
* 执行字段映射
|
|
|
|
|
*/
|
|
|
|
|
protected List<String> syncLarkBatch(List<String> keyList, List<List<String>> rows, Map<String, String> existKeyMap
|
|
|
|
|
, LarkTableRequest addRecordRequest, String cjt,Boolean asynchronous) {
|
|
|
|
|
, LarkTableRequest addRecordRequest, String cjt, Boolean asynchronous) {
|
|
|
|
|
List<ErpLarkRelation> relationList = new ArrayList<>();
|
|
|
|
|
//查询字段与飞书字段的对应关系
|
|
|
|
|
Map<String, CJTSyncTypeRelation> queryFieldsMap = getQueryFieldsMap(cjt);
|
|
|
|
@ -440,6 +442,7 @@ public abstract class SyncAccountsJobAbstract {
|
|
|
|
|
List<String> errorKey = new ArrayList<>();
|
|
|
|
|
//判断当前查询条件内是否存在重复数据
|
|
|
|
|
Map<String, Integer> repeatMap = new HashMap<>();
|
|
|
|
|
List<AppTableRecord> waitUpdateList = new ArrayList<>();
|
|
|
|
|
for (List<String> 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());
|
|
|
|
|
}
|
|
|
|
|