|
|
|
@ -0,0 +1,331 @@
|
|
|
|
|
package com.glxp.api.task;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
|
|
import cn.hutool.core.thread.ThreadUtil;
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
|
|
import com.glxp.api.constant.ThirdSysConstant;
|
|
|
|
|
import com.glxp.api.dao.schedule.ScheduledDao;
|
|
|
|
|
import com.glxp.api.dao.system.SyncDataSetDao;
|
|
|
|
|
import com.glxp.api.dao.thrsys.ThrSystemDetailDao;
|
|
|
|
|
import com.glxp.api.entity.system.ScheduledEntity;
|
|
|
|
|
import com.glxp.api.entity.thrsys.ThrSystemDetailEntity;
|
|
|
|
|
import com.glxp.api.req.system.ScheduledRequest;
|
|
|
|
|
import com.glxp.api.res.thrsys.ThirdSysInterfaceExecuteVo;
|
|
|
|
|
import com.glxp.api.service.inout.IoOrderService;
|
|
|
|
|
import com.glxp.api.service.thrsys.IThrBusTypeOriginService;
|
|
|
|
|
import com.glxp.api.service.thrsys.ThrCorpService;
|
|
|
|
|
import com.glxp.api.service.thrsys.ThrInvWarehouseService;
|
|
|
|
|
import com.glxp.api.service.thrsys.ThrProductsService;
|
|
|
|
|
import com.glxp.api.util.RedisUtil;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
|
|
|
|
import org.springframework.scheduling.annotation.SchedulingConfigurer;
|
|
|
|
|
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|
|
|
|
import org.springframework.scheduling.support.CronTrigger;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
|
|
|
|
|
@Component
|
|
|
|
|
@EnableScheduling
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class SyncThirdSysTask implements SchedulingConfigurer {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* redis key 前缀
|
|
|
|
|
*/
|
|
|
|
|
private static final Map<String, Map<String, String>> keyMap = new ConcurrentHashMap<>(5);
|
|
|
|
|
|
|
|
|
|
private volatile ExecutorService executor;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private RedisUtil redisUtil;
|
|
|
|
|
@Resource
|
|
|
|
|
private ThrSystemDetailDao thrSystemDetailDao;
|
|
|
|
|
@Resource
|
|
|
|
|
private ThrInvWarehouseService thrInvWarehouseService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ThrCorpService thrCorpService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ThrProductsService thrProductsService;
|
|
|
|
|
@Resource
|
|
|
|
|
private IThrBusTypeOriginService thrBusTypeOriginService;
|
|
|
|
|
@Resource
|
|
|
|
|
private IoOrderService orderService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final Logger logger = LoggerFactory.getLogger(SyncHeartTask.class);
|
|
|
|
|
@Resource
|
|
|
|
|
protected ScheduledDao scheduledDao;
|
|
|
|
|
@Resource
|
|
|
|
|
private SyncDataSetDao syncDataSetDao;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
|
|
|
|
|
|
|
|
|
|
scheduledTaskRegistrar.addTriggerTask(() -> process(),
|
|
|
|
|
triggerContext -> {
|
|
|
|
|
ScheduledRequest scheduledRequest = new ScheduledRequest();
|
|
|
|
|
scheduledRequest.setCronName("dlThrSysHeartTask");
|
|
|
|
|
ScheduledEntity scheduledEntity = scheduledDao.findScheduled(scheduledRequest);
|
|
|
|
|
if (scheduledEntity != null) {
|
|
|
|
|
String cron = scheduledEntity.getCron();
|
|
|
|
|
if (cron.isEmpty()) {
|
|
|
|
|
logger.error("cron is null");
|
|
|
|
|
}
|
|
|
|
|
return new CronTrigger(cron).nextExecutionTime(triggerContext);
|
|
|
|
|
} else
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ExecutorService getExecutor() {
|
|
|
|
|
if (null == executor) {
|
|
|
|
|
synchronized (this) {
|
|
|
|
|
log.info("初始化第三方系统接口执行线程池");
|
|
|
|
|
executor = ThreadUtil.newExecutor(10, 100, Integer.MAX_VALUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return executor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void process() {
|
|
|
|
|
|
|
|
|
|
log.info("开始扫描自动执行的第三方接口列表");
|
|
|
|
|
List<ThrSystemDetailEntity> list = thrSystemDetailDao.selectAutoExecuteList();
|
|
|
|
|
if (CollUtil.isNotEmpty(list)) {
|
|
|
|
|
log.info("本次查询到的接口列表数量:{}", list.size());
|
|
|
|
|
list.parallelStream().forEach(thrSystemDetailEntity -> {
|
|
|
|
|
switch (thrSystemDetailEntity.getKey()) {
|
|
|
|
|
case ThirdSysConstant.WAREHOUSE_QUERY_URL:
|
|
|
|
|
//下载第三方仓库信息
|
|
|
|
|
downloadThrInv(thrSystemDetailEntity);
|
|
|
|
|
break;
|
|
|
|
|
case ThirdSysConstant.CORP_URL:
|
|
|
|
|
//下载往来单位信息
|
|
|
|
|
downloadThrCorp(thrSystemDetailEntity);
|
|
|
|
|
break;
|
|
|
|
|
case ThirdSysConstant.PI_QUERY_URL:
|
|
|
|
|
//下载第三方产品信息
|
|
|
|
|
downloadThrPi(thrSystemDetailEntity);
|
|
|
|
|
break;
|
|
|
|
|
case ThirdSysConstant.BUS_TYPE_QUERY_URL:
|
|
|
|
|
//下载第三方单据类型
|
|
|
|
|
downloadThrBusType(thrSystemDetailEntity);
|
|
|
|
|
break;
|
|
|
|
|
case ThirdSysConstant.ORDER_SUBMIT_URL:
|
|
|
|
|
//提交单据
|
|
|
|
|
submitOrder(thrSystemDetailEntity);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
//其他接口暂不处理
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
log.info("未配置自动执行的第三方接口列表");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 提交单据到第三方系统
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
*/
|
|
|
|
|
private void submitOrder(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
//校验任务并更新redis数据执行标识
|
|
|
|
|
if (verifyTask(thrSystemDetailEntity)) {
|
|
|
|
|
getExecutor().submit(() -> {
|
|
|
|
|
log.info("开始提交单据到第三方系统");
|
|
|
|
|
try {
|
|
|
|
|
orderService.submitOrderToThrSys(thrSystemDetailEntity);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("提交单据到第三方系统异常", e);
|
|
|
|
|
} finally {
|
|
|
|
|
updateTask(getTaskKey(thrSystemDetailEntity));
|
|
|
|
|
}
|
|
|
|
|
log.info("提交单据到第三方系统完成");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载第三方单据类型
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
*/
|
|
|
|
|
private void downloadThrBusType(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
//校验任务并更新redis数据执行标识
|
|
|
|
|
if (verifyTask(thrSystemDetailEntity)) {
|
|
|
|
|
getExecutor().submit(() -> {
|
|
|
|
|
log.info("开始下载第三方单据类型");
|
|
|
|
|
try {
|
|
|
|
|
thrBusTypeOriginService.downloadThrBusType(thrSystemDetailEntity);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("下载第三方单据类型异常", e);
|
|
|
|
|
} finally {
|
|
|
|
|
updateTask(getTaskKey(thrSystemDetailEntity));
|
|
|
|
|
}
|
|
|
|
|
log.info("第三方单据类型下载完成");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载第三方产品信息
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
*/
|
|
|
|
|
private void downloadThrPi(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
//校验任务并更新redis数据执行标识
|
|
|
|
|
if (verifyTask(thrSystemDetailEntity)) {
|
|
|
|
|
getExecutor().submit(() -> {
|
|
|
|
|
log.info("开始下载第三方产品信息");
|
|
|
|
|
try {
|
|
|
|
|
thrProductsService.downloadThrPi(thrSystemDetailEntity);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("下载第三方产品信息异常", e);
|
|
|
|
|
} finally {
|
|
|
|
|
updateTask(getTaskKey(thrSystemDetailEntity));
|
|
|
|
|
}
|
|
|
|
|
log.info("第三方产品信息下载完成");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载第三方往来单位
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
*/
|
|
|
|
|
private void downloadThrCorp(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
//校验任务并更新redis数据执行标识
|
|
|
|
|
if (verifyTask(thrSystemDetailEntity)) {
|
|
|
|
|
getExecutor().submit(() -> {
|
|
|
|
|
log.info("开始下载第三方往来单位信息");
|
|
|
|
|
try {
|
|
|
|
|
thrCorpService.downloadThrCorp(thrSystemDetailEntity);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("下载第三方往来单位异常", e);
|
|
|
|
|
} finally {
|
|
|
|
|
updateTask(getTaskKey(thrSystemDetailEntity));
|
|
|
|
|
}
|
|
|
|
|
log.info("第三方往来单位信息下载完成");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 下载第三方系统仓库
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
*/
|
|
|
|
|
private void downloadThrInv(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
//校验任务并更新redis数据执行标识
|
|
|
|
|
if (verifyTask(thrSystemDetailEntity)) {
|
|
|
|
|
getExecutor().submit(() -> {
|
|
|
|
|
log.info("开始下载第三方仓库信息");
|
|
|
|
|
try {
|
|
|
|
|
thrInvWarehouseService.downloadThrInv(thrSystemDetailEntity);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("下载第三方仓库信息异常", e);
|
|
|
|
|
} finally {
|
|
|
|
|
//保证任务标识一定会被修改回去
|
|
|
|
|
updateTask(getTaskKey(thrSystemDetailEntity));
|
|
|
|
|
}
|
|
|
|
|
log.info("第三方仓库信息下载完成");
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 更新任务状态为已完成
|
|
|
|
|
*
|
|
|
|
|
* @param taskKey
|
|
|
|
|
*/
|
|
|
|
|
private void updateTask(String taskKey) {
|
|
|
|
|
ThirdSysInterfaceExecuteVo vo = getLastResult(taskKey);
|
|
|
|
|
vo.setFinished(true);
|
|
|
|
|
redisUtil.set(taskKey, vo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校验当前任务是否可以执行
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private boolean verifyTask(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
String taskKey = getTaskKey(thrSystemDetailEntity);
|
|
|
|
|
ThirdSysInterfaceExecuteVo vo = getLastResult(taskKey);
|
|
|
|
|
if (null != vo && !vo.isFinished()) {
|
|
|
|
|
log.info("有任务尚未执行完成,当前任务key:{}", taskKey);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
long nextTime = DateUtil.offsetMonth(new Date(), thrSystemDetailEntity.getTime()).getTime();
|
|
|
|
|
if (vo != null) {
|
|
|
|
|
if (vo.getNextTime() - new Date().getTime() > thrSystemDetailEntity.getTime() * 1000 * 60) {
|
|
|
|
|
log.info("定时任务时间未到", taskKey);
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
vo = Optional.ofNullable(vo).orElse(new ThirdSysInterfaceExecuteVo());
|
|
|
|
|
vo.setKey(taskKey);
|
|
|
|
|
vo.setNextTime(nextTime);
|
|
|
|
|
vo.setFinished(false);
|
|
|
|
|
redisUtil.set(taskKey, vo);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取上一次执行结果
|
|
|
|
|
*
|
|
|
|
|
* @param taskKey
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private ThirdSysInterfaceExecuteVo getLastResult(String taskKey) {
|
|
|
|
|
String json = redisUtil.getJSON(taskKey);
|
|
|
|
|
return StrUtil.isBlank(json) ? null : JSONUtil.toBean(json, ThirdSysInterfaceExecuteVo.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 拼接redis Key
|
|
|
|
|
*
|
|
|
|
|
* @param thrSystemDetailEntity
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private String getTaskKey(ThrSystemDetailEntity thrSystemDetailEntity) {
|
|
|
|
|
String key = "";
|
|
|
|
|
Map<String, String> keys = keyMap.get(thrSystemDetailEntity.getThirdSysFk());
|
|
|
|
|
if (CollUtil.isEmpty(keys)) {
|
|
|
|
|
Map<String, String> map = new HashMap<>(1);
|
|
|
|
|
key = "thirdI:" + thrSystemDetailEntity.getThirdSysFk() + ":" + thrSystemDetailEntity.getKey();
|
|
|
|
|
map.put(thrSystemDetailEntity.getKey(), key);
|
|
|
|
|
keyMap.put(thrSystemDetailEntity.getThirdSysFk(), map);
|
|
|
|
|
} else {
|
|
|
|
|
key = keys.get(thrSystemDetailEntity.getKey());
|
|
|
|
|
if (StrUtil.isBlank(key)) {
|
|
|
|
|
key = "thirdI:" + thrSystemDetailEntity.getThirdSysFk() + ":" + thrSystemDetailEntity.getKey();
|
|
|
|
|
Map<String, String> map = new HashMap<>(1);
|
|
|
|
|
map.put(thrSystemDetailEntity.getKey(), key);
|
|
|
|
|
keyMap.put(thrSystemDetailEntity.getThirdSysFk(), map);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|