监听回调事件

畅捷通同步方案更新
YXY 1 year ago
parent a57041d8fe
commit 01945b192a

@ -0,0 +1,53 @@
package com.ruoyi.common.enums;
/**
*
*
* @author ruoyi
*/
public enum CjtCallBackOperateEnum {
/**
*
*/
SALE_DISPATCH_CREATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.getCode()),
SALE_DISPATCH_UPDATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.getCode()),
SALE_DISPATCH_DELETE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_DISPATCH_DATA_TO_MULTI_TABLE.getCode()),
MANUFACTURE_ORDER_CREATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE.getCode()),
MANUFACTURE_ORDER_UPDATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE.getCode()),
MANUFACTURE_ORDER_DELETE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_MANUFACTURE_ORDER_DATA_TO_MULTI_TABLE.getCode()),
SALE_ORDER_CREATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_ORDER_DATA_TO_MULTI_TABLE.getCode()),
SALE_ORDER_UPDATE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_ORDER_DATA_TO_MULTI_TABLE.getCode()),
SALE_ORDER_DELETE("SaleDispatchVoucher_Delete", "删除销售出库单",AppType.SYNC_CJT_SALE_ORDER_DATA_TO_MULTI_TABLE.getCode());
private final String code;
private final String desc;
private final String larkCompanyCode;
CjtCallBackOperateEnum(String code, String desc, String larkCompanyCode) {
this.code = code;
this.desc = desc;
this.larkCompanyCode = larkCompanyCode;
}
public String getLarkCompanyCode() {
return larkCompanyCode;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
public static CjtCallBackOperateEnum getByCode(String code){
for (CjtCallBackOperateEnum value : CjtCallBackOperateEnum.values()) {
if (value.getCode().equals(code)){
return value;
}
}
return null;
}
}

@ -184,6 +184,11 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
return new Date();
}
public static Object str2long(String time, String pattern) {
LocalDateTime localDateTime = DateUtils.str2ldt(time, pattern);
return DateUtils.ldt2Long(localDateTime);
}
public static LocalDateTime long2ldt(long time) {
return LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneOffset.ofHours(8));
}

@ -14,11 +14,14 @@ public class ErpLarkRelation extends BaseEntity {
private Long id;
private String cjtId;
private String key;
private String method;
private String larkKey;
private String larkTable;
/**
* @see com.ruoyi.common.enums.FlagStatus
*/

@ -0,0 +1,118 @@
package com.ruoyi.flyingbook.domain.cjt;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.NoArgsConstructor;
import okhttp3.Headers;
import org.springframework.util.StringUtils;
import java.io.Serializable;
/**
* @author yuxiangyong
* @create 2023-07-17 20:31
*/
@Data
@NoArgsConstructor
public class CJTRequest implements Serializable {
/**
*
*/
private String url;
/**
*
*/
private String appKey;
private String appSecret;
/**
* ticketcertificate token
*/
private String appTicket;
private String certificate;
/**
* token
*/
private String openToken;
/**
* ,token
*/
private JSONObject jsonBody;
private String taskSessionId;
/**
*
*/
private CJTRequestBody body;
/**
* ticket
*/
public CJTRequest(String url, String appKey, String appSecret) {
this.url = url;
this.appKey = appKey;
this.appSecret = appSecret;
}
/**
* token
*/
public CJTRequest(String url, String appKey, String appSecret, String appTicket, String certificate) {
this.url = url;
this.appKey = appKey;
this.appSecret = appSecret;
this.appTicket = appTicket;
this.certificate = certificate;
}
/**
*
*/
public CJTRequest(String url, String appKey, String appSecret, String openToken) {
this.url = url;
this.appKey = appKey;
this.appSecret = appSecret;
this.openToken = openToken;
}
public CJTRequest(String url, String appKey, String appSecret, String openToken,CJTRequestBody body) {
this.url = url;
this.appKey = appKey;
this.appSecret = appSecret;
this.openToken = openToken;
this.body = body;
}
public Headers buildHeaders(){
Headers.Builder builder = new Headers.Builder();
builder.add("appKey",appKey);
builder.add("appSecret",appSecret);
builder.add("Content-Type","application/json");
if (!StringUtils.isEmpty(openToken)) {
builder.add("openToken", openToken);
}
return builder.build();
}
/**
* tokenbody
*/
public void buildGenerateBody(){
JSONObject body = new JSONObject();
body.put("appTicket",appTicket);
body.put("certificate",certificate);
this.jsonBody = body;
}
public String getRequestBody(){
if (this.body != null){
return JSONObject.toJSONString(this.body);
}
if (this.jsonBody != null){
return jsonBody.toJSONString();
}
return "{}";
}
}

@ -0,0 +1,34 @@
package com.ruoyi.flyingbook.domain.cjt;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author yuxiangyong
* @create 2023-07-17 20:31
*/
@Data
@NoArgsConstructor
public class CJTRequestBody {
private Integer pageIndex;
private Integer pageSize;
private List<String> selectFields;
private JSONObject paramDic;
private JSONObject param;
public CJTRequestBody(Integer pageIndex, Integer pageSize, List<String> selectFields, JSONObject paramDic) {
this.pageIndex = pageIndex;
this.pageSize = pageSize;
this.selectFields = selectFields;
this.paramDic = paramDic == null ? new JSONObject() : paramDic;
}
public CJTRequestBody(String voucherID) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("voucherID",voucherID);
this.param = jsonObject;
}
}

@ -0,0 +1,18 @@
package com.ruoyi.flyingbook.domain.cjt;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author yuxiangyong
* @create 2023-07-17 20:31
*/
@Data
@NoArgsConstructor
public class CJTResponseBody {
private String code;
private String message;
private String exception;
private JSONObject data;
}

@ -1,5 +1,10 @@
package com.ruoyi.flyingbook.domain.edi;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.CjtAccountEnum;
import com.ruoyi.common.enums.CjtCallBackOperateEnum;
import com.ruoyi.flyingbook.domain.LarkCompanyRelation;
import com.ruoyi.flyingbook.domain.LarkTableRelation;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -15,16 +20,62 @@ public class CJTEdiCallbackRequestVo {
*
* APP_TICKET ticket
* SaleDispatchVoucher_Delete
*
* @see com.ruoyi.common.enums.CjtCallBackOperateEnum
*/
private String msgType;
private CjtCallBackOperateEnum msgTypeEnum;
/**
*
*/
private String voucherCode;
/**
*
*/
private String voucherId;
/**
*
*/
private JSONObject body;
/**
*
* @see com.ruoyi.common.enums.CjtAccountEnum
*/
private String appId;
private CjtAccountEnum cjtAccountEnum;
/**
* token
*/
private String ticket;
/**
* token
*/
private String openToken;
/**
*
*/
private LarkCompanyRelation companyRelation;
private LarkTableRelation tableRelation;
/**
* id
*/
private Long tempId;
public CJTEdiCallbackRequestVo(String msgType, String voucherCode) {
this.msgType = msgType;
this.voucherCode = voucherCode;
}
public CJTEdiCallbackRequestVo(String appId,String msgType, JSONObject body) {
this.msgType = msgType;
this.body = body;
this.appId = appId;
this.cjtAccountEnum = CjtAccountEnum.getByCode(appId);
this.msgTypeEnum = CjtCallBackOperateEnum.getByCode(msgType);
}
}

@ -0,0 +1,48 @@
package com.ruoyi.flyingbook.helper;
import com.ruoyi.flyingbook.domain.cjt.CJTRequest;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
/**
* @author yuxiangyong
* @create 2023-04-18 22:25
*/
@Slf4j
public class OkHttpHelper {
private static OkHttpClient client = new OkHttpClient().newBuilder()
.callTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.build();
public static String post(CJTRequest req) {
Request request = new Request.Builder()
.headers(req.buildHeaders())
.method("POST",
RequestBody.create(MediaType.get("application/json"),
req.getRequestBody().getBytes(StandardCharsets.UTF_8)))
.url(req.getUrl())
.build();
try {
Response execute = client.newCall(request).execute();
ResponseBody responseBody = execute.body();
if (responseBody != null){
return responseBody.string();
}
} catch (Exception e) {
log.error("http get 请求失败--{}", e);
}
return null;
}
}

@ -68,7 +68,6 @@ public interface ErpLarkRelationMapper
public List<ErpLarkRelation> queryListByKeyListAndRemark(@Param("keyList") List<String> keyList,@Param("method") String method,@Param("remark") String remark);
public List<String> queryWaitDeleteRecordList(@Param("currentDay") String currentDay,@Param("method") String method,@Param("remark") String remark);
public void deleteRecordList(@Param("currentDay") String currentDay,@Param("method") String method,@Param("remark") String remark);
/**
*
*/

@ -65,6 +65,7 @@ public interface ErpLarkTempRelationMapper
public Long selectMaxId(@Param("method") String method, @Param("flag") Long flag,@Param("key") String key);
public int updateByMethod(@Param("method") String method, @Param("flag") Long flag,@Param("id") Long id,@Param("key") String key);
public int updateForCjt(@Param("flag") Long flag,@Param("id") Long id,@Param("remark") String remark);
public int deleteByMethod(@Param("method") String method,@Param("flag") Long flag,@Param("id") Long id,@Param("key") String key);

@ -0,0 +1,412 @@
package com.ruoyi.flyingbook.strategy.cjt;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lark.oapi.service.bitable.v1.model.CreateAppTableRecordRespBody;
import com.ruoyi.common.constant.RedisConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.AppType;
import com.ruoyi.common.enums.CjtAccountEnum;
import com.ruoyi.common.enums.FlagStatus;
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.cjt.CJTRequest;
import com.ruoyi.flyingbook.domain.cjt.CJTRequestBody;
import com.ruoyi.flyingbook.domain.cjt.CJTResponseBody;
import com.ruoyi.flyingbook.domain.edi.CJTEdiCallbackRequestVo;
import com.ruoyi.flyingbook.domain.lark.LarkTableRequest;
import com.ruoyi.flyingbook.helper.OkHttpHelper;
import com.ruoyi.flyingbook.mapper.ErpLarkRelationMapper;
import com.ruoyi.flyingbook.mapper.ErpLarkTempRelationMapper;
import com.ruoyi.flyingbook.mapper.LarkCompanyRelationMapper;
import com.ruoyi.flyingbook.mapper.LarkTableRelationMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* @author yuxiangyong
* @create 2023-10-11 19:54
*/
@Slf4j
public abstract class CJTOperateCallBackAbstract {
@Autowired
private RedisCache redisCache;
@Resource
private LarkCompanyRelationMapper larkCompanyRelationMapper;
@Resource
private LarkTableRelationMapper larkTableRelationMapper;
@Autowired
private LarkRobotHelper larkRobotHelper;
@Autowired
private LarkTableHelper larkTableHelper;
@Autowired
protected ErpLarkRelationMapper erpLarkRelationMapper;
@Autowired
protected ErpLarkTempRelationMapper erpLarkTempRelationMapper;
@Value("${lark.robot.group}")
private String ROBOT_GROUP;
/**
*
*/
protected static final String REQUEST_ROOT_PATH = "https://openapi.chanjet.com";
/**
* ticket
*/
private static final String REQUEST_RESET_TICKET_PATH = REQUEST_ROOT_PATH + "/auth/appTicket/resend";
/**
* token
*/
private static final String REQUEST_GENERATE_TOKEN_PATH = REQUEST_ROOT_PATH + "/v1/common/auth/selfBuiltApp/generateToken";
public void execute(CJTEdiCallbackRequestVo req){
try {
preHandle(req);
initContext(req);
resetTicket(req);
sync(req);
endHandle(req);
}catch (Exception e){
errorHandle(req,e);
log.error("{} execute error",this.getClass().getSimpleName(),e);
larkRobotHelper.sendMessageByBot(ROBOT_GROUP, buildRobotErrorCountMessage(req,e));
}
}
private void preHandle(CJTEdiCallbackRequestVo req){
Date date = new Date();
ErpLarkTempRelation erpLarkTempRelation = new ErpLarkTempRelation();
erpLarkTempRelation.setKey(req.getBody().getString("voucherID"));
erpLarkTempRelation.setMethod(req.getMsgType());
erpLarkTempRelation.setLarkKey(req.getAppId());
erpLarkTempRelation.setCreateBy("System");
erpLarkTempRelation.setCreateTime(date);
erpLarkTempRelation.setUpdateTime(date);
erpLarkTempRelation.setFlag(FlagStatus.OK.getCode());
erpLarkTempRelationMapper.insertErpLarkTempRelation(erpLarkTempRelation);
req.setTempId(erpLarkTempRelation.getId());
}
private void endHandle(CJTEdiCallbackRequestVo req){
if (req.getTempId() != null){
erpLarkTempRelationMapper.updateForCjt(FlagStatus.DELETED.getCode(), req.getTempId(),"");
}
}
private void errorHandle(CJTEdiCallbackRequestVo req,Exception e){
if (req.getTempId() != null){
erpLarkTempRelationMapper.updateForCjt(FlagStatus.OK.getCode(), req.getTempId(),e.getMessage());
}
}
private void sync(CJTEdiCallbackRequestVo req){
JSONObject body = req.getBody();
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
String voucherID = body.getString("voucherID");
req.setVoucherId(voucherID);
CJTRequestBody cjtRequestBody = new CJTRequestBody(req.getVoucherId());
CJTRequest cjtRequest = new CJTRequest(getRequestUrl(), cjtAccountEnum.getAppKey(), cjtAccountEnum.getAppSecret(), generateToken(req),cjtRequestBody);
OkHttpHelper.post(cjtRequest);
JSONObject jsonObject = requestCjt(cjtRequest);
syncRecord(req,jsonObject);
}
/**
*
* @param req
*/
protected abstract void syncRecord(CJTEdiCallbackRequestVo req,JSONObject returnBody);
/**
*
*/
protected abstract String getRequestUrl();
/**
*
*/
protected abstract String getMethodUrl();
private void initContext(CJTEdiCallbackRequestVo req){
LarkCompanyRelation queryCompany = new LarkCompanyRelation();
String larkCompanyCode = req.getMsgTypeEnum().getLarkCompanyCode();
queryCompany.setAppType(larkCompanyCode);
queryCompany.setFlag(FlagStatus.OK.getCode());
queryCompany.setRemark(req.getAppId());
List<LarkCompanyRelation> larkCompanyRelations = larkCompanyRelationMapper.selectLarkCompanyRelationList(queryCompany);
if (CollectionUtils.isEmpty(larkCompanyRelations)){
throw new RuntimeException(String.format("%s 无larkCompany配置信息 appId:%s appType:%s",req.getMsgType(),req.getAppId(),larkCompanyCode));
}
LarkCompanyRelation companyRelation = larkCompanyRelations.get(0);
req.setCompanyRelation(companyRelation);
LarkTableRelation queryTable = new LarkTableRelation();
queryTable.setLarkCompanyRelationId(companyRelation.getId());
queryTable.setFlag(FlagStatus.OK.getCode());
List<LarkTableRelation> larkTableRelations = larkTableRelationMapper.selectLarkTableRelationList(queryTable);
if (CollectionUtils.isEmpty(larkTableRelations)){
throw new RuntimeException(String.format("%s 无larkTableRelation配置信息 appId:%s appType:%s larkCompanyId:%s",req.getMsgType(),req.getAppId(),larkCompanyCode,companyRelation.getId()));
}
LarkTableRelation tableRelation = larkTableRelations.get(0);
req.setTableRelation(tableRelation);
}
private String buildRobotErrorCountMessage(CJTEdiCallbackRequestVo req,Exception e){
JSONObject body = new JSONObject();
body.put("cjtId",req.getAppId());
body.put("msgType",req.getMsgType());
LarkCompanyRelation companyRelation = req.getCompanyRelation();
if (companyRelation != null){
body.put("companyRelationId",companyRelation.getId());
}
LarkTableRelation tableRelation = req.getTableRelation();
if (tableRelation != null){
body.put("tableRelationId",tableRelation.getId());
}
body.put("errorInfo",e.getMessage());
return body.toJSONString();
}
protected LarkTableRequest buildLarkTableRequest(LarkCompanyRelation companyRelation,LarkTableRelation tableRelation){
LarkTableRequest request = new LarkTableRequest();
request.setAppId(companyRelation.getAppId());
request.setAppSecret(companyRelation.getSecret());
request.setAppToken(tableRelation.getToAppToken());
request.setAppTable(tableRelation.getToTableId());
return request;
}
protected void addRecord(CJTEdiCallbackRequestVo req, JSONObject returnBody) {
LarkTableRelation tableRelation = req.getTableRelation();
//多维表格id
String toTableId = tableRelation.getToTableId();
//头部信息
JSONObject header = returnBody.getJSONObject("data");
//明细信息
JSONArray saleOrderDetails = header.getJSONArray(getDetailName());
//待创建关联关系
List<ErpLarkRelation> relationList = new ArrayList<>();
LarkTableRequest request = this.buildLarkTableRequest(req.getCompanyRelation(), req.getTableRelation());
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
for (int i = 0; i < saleOrderDetails.size(); i++) {
JSONObject detail = saleOrderDetails.getJSONObject(i);
String uniqueKey = buildUniqueKey(toTableId, header, detail,cjtAccountEnum);
Map<String, Object> larkBody = buildLarkBody(header, detail,cjtAccountEnum);
request.setBody(larkBody);
CreateAppTableRecordRespBody respBody = larkTableHelper.addTableRecord(request);
String larkKey = respBody.getRecord().getRecordId();
relationList.add(buildErpLarkRelation(uniqueKey, larkKey, cjtAccountEnum.getCode()));
}
if (!org.springframework.util.CollectionUtils.isEmpty(relationList)) {
erpLarkRelationMapper.batchInsert(relationList);
}
}
protected void updateRecord(CJTEdiCallbackRequestVo req, JSONObject returnBody) {
LarkTableRelation tableRelation = req.getTableRelation();
//多维表格id
String toTableId = tableRelation.getToTableId();
//头部信息
JSONObject header = returnBody.getJSONObject("data");
//明细信息
JSONArray saleOrderDetails = header.getJSONArray(getDetailName());
//待创建关联关系
List<ErpLarkRelation> waitCreateRelationList = new ArrayList<>();
LarkTableRequest request = this.buildLarkTableRequest(req.getCompanyRelation(), req.getTableRelation());
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
//获取已经存在的明细
Map<String, ErpLarkRelation> existMap = getExistRecords(req).stream().collect(Collectors.toMap(ErpLarkRelation::getKey, Function.identity(), (K1, k2) -> K1));
for (int i = 0; i < saleOrderDetails.size(); i++) {
JSONObject detail = saleOrderDetails.getJSONObject(i);
String uniqueKey = buildUniqueKey(toTableId, header, detail,cjtAccountEnum);
Map<String, Object> larkBody = buildLarkBody(header, detail,cjtAccountEnum);
request.setBody(larkBody);
if (existMap.containsKey(uniqueKey)){
ErpLarkRelation erpLarkRelation = existMap.get(uniqueKey);
request.setRecord(erpLarkRelation.getLarkKey());
request.setAppTable(erpLarkRelation.getLarkTable());
larkTableHelper.updateTableRecord(request);
}else {
request.setRecord(null);
request.setAppTable(toTableId);
CreateAppTableRecordRespBody respBody = larkTableHelper.addTableRecord(request);
String larkKey = respBody.getRecord().getRecordId();
waitCreateRelationList.add(buildErpLarkRelation(uniqueKey, larkKey, cjtAccountEnum.getCode()));
}
}
if (!org.springframework.util.CollectionUtils.isEmpty(waitCreateRelationList)) {
erpLarkRelationMapper.batchInsert(waitCreateRelationList);
}
}
protected abstract String getDetailName();
/**
* key
* @return
*/
protected abstract String buildUniqueKey(String toTableId, JSONObject header, JSONObject detail,CjtAccountEnum cjtAccountEnum);
/**
* body
* @return
*/
protected abstract Map<String, Object> buildLarkBody(JSONObject header, JSONObject detail,CjtAccountEnum cjtAccountEnum);
//构建飞书行与cjt唯一键的对应关系对象
private ErpLarkRelation buildErpLarkRelation(String key, String larkKey, String cjt) {
ErpLarkRelation erpLarkRelation = new ErpLarkRelation();
erpLarkRelation.setKey(key);
erpLarkRelation.setLarkKey(larkKey);
erpLarkRelation.setMethod(getRequestUrl());
erpLarkRelation.setFlag(FlagStatus.OK.getCode());
erpLarkRelation.setRemark(cjt);
erpLarkRelation.setCreateBy("SYSTEM");
erpLarkRelation.setCreateTime(new Date());
erpLarkRelation.setUpdateTime(new Date());
return erpLarkRelation;
}
protected Object getSpecialKey(JSONObject detail,String key){
JSONArray dynamicPropertyKeys = detail.getJSONArray("DynamicPropertyKeys");
for (int i = 0; i < dynamicPropertyKeys.size(); i++) {
if (key.equals(dynamicPropertyKeys.get(i))) {
JSONArray DynamicPropertyValues = detail.getJSONArray("DynamicPropertyValues");
return DynamicPropertyValues.get(i);
}
}
return null;
}
/**
*
* @param req
*/
protected void deleteRecord(CJTEdiCallbackRequestVo req){
LarkCompanyRelation companyRelation = req.getCompanyRelation();
LarkTableRelation tableRelation = req.getTableRelation();
LarkTableRequest request = new LarkTableRequest(companyRelation.getAppId(), companyRelation.getSecret(), tableRelation.getToAppToken());
Map<String,List<String>> waitDeleteLarkMap = new HashMap<>();
List<ErpLarkRelation> relationList = getExistRecords(req);
List<Long> waitDeleteIdList = new ArrayList<>();
for (ErpLarkRelation record : relationList) {
String[] s = record.getKey().split("_");
String appTable = s[s.length-1];
List<String> waitDeleteLarkList = waitDeleteLarkMap.getOrDefault(appTable, new ArrayList<>());
waitDeleteLarkList.add(record.getLarkKey());
waitDeleteLarkMap.put(appTable,waitDeleteLarkList);
waitDeleteIdList.add(record.getId());
}
if (!waitDeleteLarkMap.isEmpty()) {
for (Map.Entry<String, List<String>> entry : waitDeleteLarkMap.entrySet()) {
request.setAppTable(entry.getKey());
request.setRecords(entry.getValue().toArray(new String[0]));
larkTableHelper.deleteTableRecordBatch(request);
}
}
if (CollectionUtils.isNotEmpty(waitDeleteIdList)) {
erpLarkRelationMapper.deleteErpLarkRelationByIds(waitDeleteIdList);
}
}
protected List<ErpLarkRelation> getExistRecords(CJTEdiCallbackRequestVo req){
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
ErpLarkRelation erpLarkRelation = new ErpLarkRelation();
erpLarkRelation.setRemark(cjtAccountEnum.getCode());
erpLarkRelation.setCjtId(req.getVoucherId());
erpLarkRelation.setMethod(getMethodUrl());
return erpLarkRelationMapper.selectErpLarkRelationList(erpLarkRelation);
}
/**
* ticket,
*/
private void resetTicket(CJTEdiCallbackRequestVo req) {
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
String ticketCacheKey = buildCacheUniqueKey(RedisConstants.CJT_TICKET_CACHE_KEY, cjtAccountEnum.getAppKey());
Long expireTime = redisCache.getExpireTime(ticketCacheKey);
//重置ticket存在响应时间提前十秒重置
if (expireTime == null || expireTime < 10) {
log.info("重置ticket");
CJTRequest cjtRequest = new CJTRequest(REQUEST_RESET_TICKET_PATH
, cjtAccountEnum.getAppKey()
, cjtAccountEnum.getAppSecret());
OkHttpHelper.post(cjtRequest);
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
String ticket = (String) redisCache.getCacheObject(ticketCacheKey);
req.setTicket(ticket);
}
private String buildCacheUniqueKey(String key, String appKey) {
return String.format("%s:%s", key, appKey);
}
/**
* token
*/
private String generateToken(CJTEdiCallbackRequestVo req) {
CjtAccountEnum cjtAccountEnum = req.getCjtAccountEnum();
String tokenCacheKey = buildCacheUniqueKey(RedisConstants.CJT_TOKEN_CACHE_KEY, cjtAccountEnum.getAppKey());
String openToken = (String) redisCache.getCacheObject(tokenCacheKey);
if (StringUtils.isEmpty(openToken)) {
CJTRequest cjtRequest = new CJTRequest(REQUEST_GENERATE_TOKEN_PATH
, cjtAccountEnum.getAppKey()
, cjtAccountEnum.getAppSecret()
, req.getTicket()
, cjtAccountEnum.getCertificate());
cjtRequest.buildGenerateBody();
JSONObject body = JSONObject.parseObject(OkHttpHelper.post(cjtRequest));
JSONObject value = body.getJSONObject("value");
String token = value.getString("accessToken");
req.setOpenToken(token);
redisCache.setCacheObject(tokenCacheKey, token, 5, TimeUnit.MINUTES);
return token;
} else {
req.setOpenToken(openToken);
return openToken;
}
}
/**
*
*/
protected JSONObject requestCjt(CJTRequest req) {
String post = OkHttpHelper.post(req);
CJTResponseBody responseBody = JSONObject.parseObject(post, CJTResponseBody.class);
if (!"0".equals(responseBody.getCode())) {
log.error("{} exception", this.getClass().getSimpleName(), responseBody.getMessage());
throw new RuntimeException(buildErrorBody(req, responseBody.getMessage()));
}
return responseBody.getData();
}
protected String buildErrorBody(CJTRequest req, String errorMessage) {
JSONObject errorInfo = new JSONObject();
errorInfo.put("url", req.getUrl());
errorInfo.put("body", JSONObject.toJSONString(req.getBody()));
errorInfo.put("errorMessage", errorMessage);
return errorInfo.toJSONString();
}
}

@ -0,0 +1,118 @@
package com.ruoyi.flyingbook.strategy.cjt;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.flyingbook.domain.edi.CJTEdiCallbackRequestVo;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author yuxiangyong
* @create 2023-07-17 21:21
*/
@Component("manufactureOrderSyncCallOperate")
public class ManufactureOrderSyncCallOperate extends CJTOperateCallBackAbstract {
@Override
protected void syncRecord(CJTEdiCallbackRequestVo req, JSONObject returnBody) {
CjtCallBackOperateEnum msgTypeEnum = req.getMsgTypeEnum();
switch (msgTypeEnum) {
case MANUFACTURE_ORDER_CREATE:
addRecord(req, returnBody);
break;
case MANUFACTURE_ORDER_UPDATE:
updateRecord(req,returnBody);
break;
case MANUFACTURE_ORDER_DELETE:
deleteRecord(req);
break;
default:
break;
}
}
@Override
protected String buildUniqueKey(String toTableId, JSONObject header, JSONObject detail,CjtAccountEnum cjtAccountEnum) {
StringBuilder sb = new StringBuilder();
if (cjtAccountEnum.getCode().equals(CjtAccountEnum.TWO.getCode())){
sb.append(detail.get("Quantity")).append("_");
sb.append(getSpecialKey(detail, "pubuserdefnvc3")).append("_");
sb.append(getSpecialKey(detail, "pubuserdefnvc3")).append("_");
}else {
sb.append(detail.get("SourceVoucherCode")).append("_");
sb.append(header.get("Code")).append("_");
JSONObject inventory = detail.getJSONObject("Inventory");
if (inventory == null) {
sb.append("null").append("_");
} else {
sb.append(inventory.get("Code")).append("_");
}
sb.append(detail.get("Quantity")).append("_");
sb.append(getSpecialKey(detail, "pubuserdefnvc2")).append("_");
}
sb.append(toTableId);
return sb.toString();
}
@Override
protected Map<String, Object> buildLarkBody(JSONObject header, JSONObject detail, CjtAccountEnum cjtAccountEnum) {
Map<String, Object> body = new HashMap<>();
body.put("单据日期", DateUtils.str2long(header.getString("VoucherDate"), DateUtils.YYYY_MM_DD));
body.put("来源单号", detail.getString("SourceVoucherCode"));
body.put("单据编号", header.getString("Code"));
//创建时间只有年月日
body.put("创建时间", DateUtils.str2long(header.getString("CreatedTime"), DateUtils.YYYY_MM_DD));
JSONObject department = detail.getJSONObject("Department");
body.put("生产车间", department.getString("Name"));
JSONObject person = detail.getJSONObject("Person");
body.put("负责人", person.getString("Name"));
JSONObject inventory = detail.getJSONObject("Inventory");
body.put("存货编码", inventory.getString("Code"));
body.put("存货", inventory.getString("Name"));
body.put("规格型号", inventory.getString("Specification"));
JSONObject unit = detail.getJSONObject("Unit");
body.put("生产单位", unit.getString("Name"));
body.put("数量", detail.getDoubleValue("Quantity"));
body.put("备注1", getSpecialKey(detail, "pubuserdefnvc2"));
JSONObject customer = detail.getJSONObject("Customer");
body.put("客户", customer.getString("Name"));
body.put("合并字段", getSpecialKey(detail, "priuserdefnvc1"));
switch (cjtAccountEnum) {
case ONE:
break;
case TWO:
body.put("钢板面", getSpecialKey(detail, "pubuserdefnvc1"));
break;
}
return body;
}
@Override
protected String getRequestUrl() {
return "/tplus/api/v2/ManufactureOrderOpenApi/GetVoucherDTO";
}
@Override
protected String getMethodUrl() {
return REQUEST_ROOT_PATH + "/tplus/api/v2/ManufactureOrderOpenApi/FindVoucherList";
}
@Override
protected String getDetailName() {
return "ManufactureOrderDetails";
}
}

@ -0,0 +1,117 @@
package com.ruoyi.flyingbook.strategy.cjt;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.CjtAccountEnum;
import com.ruoyi.common.enums.CjtCallBackOperateEnum;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.flyingbook.domain.edi.CJTEdiCallbackRequestVo;
import org.springframework.stereotype.Component;
import java.util.*;
/**
*
*
* @author yuxiangyong
* @create 2023-07-17 21:21
*/
@Component("saleDispatchSyncCallOperate")
public class SaleDispatchSyncCallOperate extends CJTOperateCallBackAbstract {
@Override
protected void syncRecord(CJTEdiCallbackRequestVo req, JSONObject returnBody) {
CjtCallBackOperateEnum msgTypeEnum = req.getMsgTypeEnum();
switch (msgTypeEnum) {
case SALE_DISPATCH_CREATE:
addRecord(req, returnBody);
break;
case SALE_DISPATCH_UPDATE:
updateRecord(req,returnBody);
break;
case SALE_DISPATCH_DELETE:
deleteRecord(req);
break;
default:
break;
}
}
@Override
protected String buildUniqueKey(String toTableId, JSONObject header, JSONObject detail,CjtAccountEnum cjtAccountEnum) {
StringBuilder sb = new StringBuilder();
sb.append(detail.get("SourceVoucherCode")).append("_");
sb.append(header.get("Code")).append("_");
JSONObject inventory = detail.getJSONObject("Inventory");
if (inventory == null) {
sb.append("null").append("_");
} else {
sb.append(inventory.get("Code")).append("_");
}
sb.append(detail.get("Quantity")).append("_");
sb.append(detail.get("DetailMemo")).append("_");
sb.append(header.get("SaleOrderCode")).append("_");
sb.append(getSpecialKey(detail, "pubuserdefnvc3")).append("_");
sb.append(toTableId);
return sb.toString();
}
@Override
protected Map<String, Object> buildLarkBody(JSONObject header, JSONObject detail, CjtAccountEnum cjtAccountEnum) {
Map<String, Object> body = new HashMap<>();
body.put("来源单号", detail.getString("SourceVoucherCode"));
body.put("单据日期", DateUtils.str2long(header.getString("VoucherDate"), DateUtils.YYYY_MM_DD));
body.put("单据编号", header.getString("Code"));
JSONObject partner = header.getJSONObject("Partner");
body.put("客户", partner.getString("Name"));
body.put("客户编码", partner.getString("Code"));
body.put("客服", partner.getString("priuserdefnvc1"));
body.put("配送路线", partner.getString("priuserdefnvc2"));
JSONObject inventory = detail.getJSONObject("Inventory");
body.put("存货编码", inventory.getString("Code"));
body.put("存货", inventory.getString("Name"));
body.put("规格型号", inventory.getString("Specification"));
JSONObject unit = detail.getJSONObject("Unit");
body.put("计量单位", unit.getString("Name"));
body.put("数量", detail.getDoubleValue("Quantity"));
body.put("送货地址", header.getString("DispatchAddress"));
//创建时间只有年月日
body.put("创建时间", DateUtils.str2long(header.getString("CreatedTime"), DateUtils.YYYY_MM_DD));
body.put("备注", detail.getString("DetailMemo"));
body.put("售价", detail.getDoubleValue("OrigSalePrice"));
body.put("销售金额", detail.getDoubleValue("OrigSaleAmount"));
body.put("订单编号", header.getString("SaleOrderCode"));
body.put("客户备注", getSpecialKey(detail, "pubuserdefnvc3"));
switch (cjtAccountEnum) {
case ONE:
body.put("联系人", header.getString("contact"));
body.put("联系电话", header.getString("contactphone"));
break;
case TWO:
break;
}
return body;
}
@Override
protected String getRequestUrl() {
return "/tplus/api/v2/SaleDispatchOpenApi/GetVoucherDTO";
}
@Override
protected String getMethodUrl() {
return REQUEST_ROOT_PATH + "/tplus/api/v2/SaleDispatchOpenApi/FindVoucherList";
}
@Override
protected String getDetailName() {
return "RDRecordDetails";
}
}

@ -0,0 +1,126 @@
package com.ruoyi.flyingbook.strategy.cjt;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.enums.*;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.flyingbook.domain.edi.CJTEdiCallbackRequestVo;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yuxiangyong
* @create 2023-07-17 21:21
*/
@Component("saleOrderSyncCallBack")
public class SaleOrderSyncCallBack extends CJTOperateCallBackAbstract{
@Override
protected void syncRecord(CJTEdiCallbackRequestVo req, JSONObject returnBody) {
CjtCallBackOperateEnum msgTypeEnum = req.getMsgTypeEnum();
switch (msgTypeEnum) {
case SALE_ORDER_CREATE:
addRecord(req, returnBody);
break;
case SALE_ORDER_UPDATE:
updateRecord(req,returnBody);
break;
case SALE_ORDER_DELETE:
deleteRecord(req);
break;
default:
break;
}
}
@Override
protected String buildUniqueKey(String toTableId, JSONObject header, JSONObject detail,CjtAccountEnum cjtAccountEnum) {
StringBuilder sb = new StringBuilder();
if (cjtAccountEnum.getCode().equals(CjtAccountEnum.TWO.getCode())){
sb.append(header.get("Code")).append("_");
JSONObject inventory = detail.getJSONObject("Inventory");
if (inventory == null) {
sb.append("null").append("_");
} else {
sb.append(inventory.get("Code")).append("_");
}
sb.append(detail.get("Quantity")).append("_");
sb.append(getSpecialKey(detail, "pubuserdefnvc1")).append("_");
sb.append(detail.get("DetailMemo")).append("_");
}else {
sb.append(header.get("Code")).append("_");
JSONObject inventory = detail.getJSONObject("Inventory");
if (inventory == null) {
sb.append("null").append("_");
} else {
sb.append(inventory.get("Code")).append("_");
}
sb.append(detail.get("Quantity")).append("_");
sb.append(detail.get("DetailMemo")).append("_");
}
sb.append(toTableId);
return sb.toString();
}
@Override
protected Map<String, Object> buildLarkBody(JSONObject header, JSONObject detail, CjtAccountEnum cjtAccountEnum) {
Map<String, Object> body = new HashMap<>();
body.put("单据日期", DateUtils.str2long(header.getString("VoucherDate"), DateUtils.YYYY_MM_DD));
body.put("编号", header.getString("Code"));
body.put("生单时间", DateUtils.str2long(header.getString("CreatedTime"), DateUtils.YYYY_MM_DD));
JSONObject customer = header.getJSONObject("Customer");
body.put("客户", customer.getString("Name"));
body.put("审核日期", DateUtils.str2long(header.getString("AuditedDate"), DateUtils.YYYY_MM_DD));
JSONObject voucherState = header.getJSONObject("VoucherState");
body.put("单据状态", voucherState.getString("Name"));
JSONObject inventory = detail.getJSONObject("Inventory");
body.put("存货编码", inventory.getString("Code"));
body.put("存货", inventory.getString("Name"));
body.put("规格型号", inventory.getString("Specification"));
JSONObject unit = detail.getJSONObject("Unit");
body.put("销售单位", unit.getString("Name"));
body.put("数量", detail.getDoubleValue("Quantity"));
body.put("累计执行数量", detail.getDoubleValue("累计执行数量"));
body.put("明细备注", detail.getString("DetailMemo"));
body.put("钢板面", getSpecialKey(detail, "pubuserdefnvc1"));
switch (cjtAccountEnum) {
case ONE:
body.put("客户备注", header.getString("CustomerMemo"));
body.put("备注1", header.getString("Memo"));
break;
case TWO:
body.put("备注1", getSpecialKey(detail, "pubuserdefnvc2"));
break;
}
return body;
}
@Override
protected String getRequestUrl() {
return "/tplus/api/v2/SaleOrderOpenApi/GetVoucherDTO";
}
@Override
protected String getMethodUrl() {
return REQUEST_ROOT_PATH + "/tplus/api/v2/SaleOrderOpenApi/FindVoucherList";
}
@Override
protected String getDetailName() {
return "SaleOrderDetails";
}
}

@ -127,6 +127,11 @@
and `key` = #{key}
and #{id} >= id
</update>
<update id="updateForCjt">
update erp_lark_temp_relation
set flag = #{flag},remark = #{remark}
where #{id} = id
</update>
<insert id="batchInsert" parameterType="com.ruoyi.flyingbook.domain.ErpLarkTempRelation" useGeneratedKeys="true"
keyProperty="id">

Loading…
Cancel
Save