|
|
@@ -1,6 +1,8 @@
|
|
|
package com.jeeplus.modules.workinvoice.service.OMS;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.jeeplus.common.config.Global;
|
|
|
import com.jeeplus.common.utils.JedisUtils;
|
|
|
import com.jeeplus.common.utils.StringUtils;
|
|
|
@@ -21,6 +23,7 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import redis.clients.jedis.Jedis;
|
|
|
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.UUID;
|
|
|
@@ -37,6 +40,7 @@ public class OMSDisposeService {
|
|
|
private static final String appId = Global.getConfig("omsAppId");
|
|
|
private static final String appKey = Global.getConfig("omsAppKey");
|
|
|
private static final String deptCode = Global.getConfig("omsDeptCode");
|
|
|
+ private static final String omsUrl = Global.getConfig("omsUrl");
|
|
|
//如果接口访问不正确,可以循环访问的次数
|
|
|
private final int remainRetryTimes = 20;
|
|
|
|
|
|
@@ -51,6 +55,10 @@ public class OMSDisposeService {
|
|
|
@Autowired
|
|
|
private WorkInvoiceService workInvoiceService;
|
|
|
|
|
|
+ // 注入SpringBoot内置的JSON序列化工具(无额外依赖)
|
|
|
+ @Autowired
|
|
|
+ private ObjectMapper objectMapper;
|
|
|
+
|
|
|
/**
|
|
|
* 用于生成开蓝票信息
|
|
|
* @param map
|
|
|
@@ -130,7 +138,7 @@ public class OMSDisposeService {
|
|
|
InvoiceTokenInfo.setData(string);
|
|
|
String jsonInvoiceStr = JSON.toJSONString(InvoiceTokenInfo);
|
|
|
|
|
|
- String jsonInvoicResultStr = HttpPostJsonUtil.doPost("https://www.oms.ejinshui-cloud.com:8899/prod-api/output/server/order/upload", jsonInvoiceStr);
|
|
|
+ String jsonInvoicResultStr = HttpPostJsonUtil.doPost(omsUrl + "/prod-api/output/server/order/upload", jsonInvoiceStr);
|
|
|
System.out.println("✅ 订单提交接口返回值:" + jsonInvoicResultStr);
|
|
|
map.put("订单接口信息", jsonInvoicResultStr);
|
|
|
|
|
|
@@ -184,17 +192,53 @@ public class OMSDisposeService {
|
|
|
tokenInfo.setAppKey(appKey);
|
|
|
tokenInfo.setExchangeId(UUID.randomUUID().toString());
|
|
|
String jsonStr = JSON.toJSONString(tokenInfo);
|
|
|
- String accessTokenStr = HttpPostJsonUtil.doPost("https://www.oms.ejinshui-cloud.com:8899/prod-api/server/accessToken", jsonStr);
|
|
|
+ String accessTokenStr = HttpPostJsonUtil.doPost(omsUrl + "/prod-api/server/accessToken", jsonStr);
|
|
|
|
|
|
if(StringUtils.isBlank(accessTokenStr)){
|
|
|
System.err.println("获取AccessToken失败:接口返回空,剩余重试次数:"+remainRetryTimes);
|
|
|
- return "";
|
|
|
+ if (remainRetryTimes > 1) {
|
|
|
+ int nextRetry = remainRetryTimes - 1;
|
|
|
+ System.err.println("⚠️ 获取AccessToken失败:接口返回空,剩余重试次数:"+nextRetry);
|
|
|
+ Thread.sleep(30 * 1000);
|
|
|
+ return getOmsAccessTokenWithRetry(nextRetry, getKey, workInvoiceId, informType);
|
|
|
+ } else {
|
|
|
+ System.err.println("❌ 获取AccessToken失败:接口返回空,重试次数耗尽!");
|
|
|
+ //需要将错误信息保存到对应开票信息表中
|
|
|
+ WorkInvoice workInvoice = workInvoiceDao.get(workInvoiceId);
|
|
|
+ if(null != workInvoice){
|
|
|
+ workInvoice.setOmsAccessTokenError("获取AccessToken失败:接口返回空");
|
|
|
+ //修改结果
|
|
|
+ workInvoiceDao.updateAccessTokenErrorById(workInvoice);
|
|
|
+ }
|
|
|
+ //如果需要 可以将执行失败信息通过短信通知业务发起人
|
|
|
+ handleInvoiceRetryAllFail("", workInvoiceId, "获取AccessToken失败:接口返回空", informType); // 解析失败也执行兜底方法
|
|
|
+
|
|
|
+ return "";
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(accessTokenStr, OMSAccessTokenInfo.class);
|
|
|
if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
|
|
|
System.err.println("获取AccessToken失败:返回结果解析异常,剩余重试次数:"+remainRetryTimes);
|
|
|
- return "";
|
|
|
+ if (remainRetryTimes > 1) {
|
|
|
+ int nextRetry = remainRetryTimes - 1;
|
|
|
+ System.err.println("⚠️ 获取AccessToken失败:返回结果解析异常,剩余重试次数:"+nextRetry);
|
|
|
+ Thread.sleep(30 * 1000);
|
|
|
+ return getOmsAccessTokenWithRetry(nextRetry, getKey, workInvoiceId, informType);
|
|
|
+ } else {
|
|
|
+ System.err.println("❌ 获取AccessToken失败:返回结果解析异常,重试次数耗尽!");
|
|
|
+ //需要将错误信息保存到对应开票信息表中
|
|
|
+ WorkInvoice workInvoice = workInvoiceDao.get(workInvoiceId);
|
|
|
+ if(null != workInvoice){
|
|
|
+ workInvoice.setOmsAccessTokenError("获取AccessToken失败:返回结果解析异常");
|
|
|
+ //修改结果
|
|
|
+ workInvoiceDao.updateAccessTokenErrorById(workInvoice);
|
|
|
+ }
|
|
|
+ //如果需要 可以将执行失败信息通过短信通知业务发起人
|
|
|
+ handleInvoiceRetryAllFail("", workInvoiceId, "获取AccessToken失败:返回结果解析异常", informType); // 解析失败也执行兜底方法
|
|
|
+
|
|
|
+ return "";
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
String code = resultTokenInfo.getResult().getCode();
|
|
|
@@ -331,6 +375,7 @@ public class OMSDisposeService {
|
|
|
* @param getKey 获取token的key
|
|
|
* @param initiationType 开票类型(蓝票/红票)
|
|
|
*/
|
|
|
+ @Transactional(readOnly = false)
|
|
|
public void saveInvoiceRetryScheduledTaskToRedis(String jsonInvoiceStr ,String accessToken, String workInvoiceId, String getKey, String initiationType) {
|
|
|
Jedis jedis = null;
|
|
|
// 硬编码:初始重试次数100次
|
|
|
@@ -359,6 +404,36 @@ public class OMSDisposeService {
|
|
|
|
|
|
jedis.expire(redisKey, REDIS_EXPIRE_SECONDS); // 1天过期
|
|
|
System.out.println("✅ 9998重试任务已存入Redis,订单号:" + workInvoiceId + ",剩余重试次数:" + retryTimes);
|
|
|
+
|
|
|
+
|
|
|
+ // ========== 追加:Redis数据转JSON,持久化到发票表(兜底逻辑) ==========
|
|
|
+ long redisStoreTime = System.currentTimeMillis() / 1000; // 秒级存储时间,用于后期回滚
|
|
|
+ // 封装Map:包含Redis所有哈希字段 + redisKey/过期时间/存储时间,保留redisKey(按你要求)
|
|
|
+ Map<String, Object> retryTaskMap = new HashMap<>(12);
|
|
|
+ // Redis哈希中所有原字段(和Redis完全一致)
|
|
|
+ retryTaskMap.put("jsonInvoiceStr", jsonInvoiceStr);
|
|
|
+ retryTaskMap.put("accessToken", accessToken);
|
|
|
+ retryTaskMap.put("workInvoiceId", workInvoiceId);
|
|
|
+ retryTaskMap.put("getKey", getKey);
|
|
|
+ retryTaskMap.put("initiationType", initiationType);
|
|
|
+ retryTaskMap.put("firstExecTime", String.valueOf(System.currentTimeMillis()));
|
|
|
+ retryTaskMap.put("retryTimes", retryTimes);
|
|
|
+ // 额外兜底字段(保留redisKey)
|
|
|
+ retryTaskMap.put("redisKey", redisKey);
|
|
|
+ retryTaskMap.put("redisExpireSeconds", REDIS_EXPIRE_SECONDS);
|
|
|
+ retryTaskMap.put("redisStoreTime", redisStoreTime);
|
|
|
+ retryTaskMap.put("initRetryCount", INIT_RETRY_COUNT); // 追加初始重试次数,后期回滚可参考
|
|
|
+
|
|
|
+ // Map转JSON字符串(单独捕获序列化异常,不影响Redis核心逻辑)
|
|
|
+ String retryTaskJson = objectMapper.writeValueAsString(retryTaskMap);
|
|
|
+
|
|
|
+ // 更新发票表(和之前红冲/下载任务用相同的DAO和实体,风格统一)
|
|
|
+ WorkInvoice workInvoice = new WorkInvoice();
|
|
|
+ workInvoice.setId(workInvoiceId);
|
|
|
+ workInvoice.setRetryInvoiceJson(retryTaskJson);
|
|
|
+ // 处理DAO更新结果,按你的风格打印控制台信息
|
|
|
+ workInvoiceDao.updateRedInvoiceJsonByWorkInvoiceId(workInvoice);
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
System.err.println("❌ 存入9998重试任务到Redis失败,订单号:" + workInvoiceId + ",原因:" + e.getMessage());
|
|
|
@@ -373,6 +448,7 @@ public class OMSDisposeService {
|
|
|
* @param accessToken
|
|
|
* @param workInvoiceId 开票的id
|
|
|
*/
|
|
|
+ @Transactional(readOnly = false)
|
|
|
public void saveInvoiceDownloadTaskToRedis(String accessToken, String workInvoiceId, String informType) {
|
|
|
Jedis jedis = null;
|
|
|
try {
|
|
|
@@ -383,6 +459,28 @@ public class OMSDisposeService {
|
|
|
jedis.hset(redisKey, "informType", informType);
|
|
|
jedis.hset(redisKey, "firstExecTime", String.valueOf(System.currentTimeMillis()));
|
|
|
jedis.expire(redisKey, seconds); // 1天过期
|
|
|
+
|
|
|
+ // ========== 追加:封装Redis数据→转JSON→更新发票表(和红冲方法逻辑一致) ==========
|
|
|
+ long redisStoreTime = System.currentTimeMillis() / 1000; // 秒级存储时间,用于后期回滚
|
|
|
+ // 封装Map:和Redis中存储的键值完全一致,方便后期回滚解析
|
|
|
+ Map<String, Object> downloadTaskMap = new HashMap<>(10);
|
|
|
+ downloadTaskMap.put("accessToken", accessToken);
|
|
|
+ downloadTaskMap.put("workInvoiceId", workInvoiceId);
|
|
|
+ downloadTaskMap.put("informType", informType);
|
|
|
+ downloadTaskMap.put("firstExecTime", String.valueOf(System.currentTimeMillis())); // 和Redis保持一致的毫秒数字符串
|
|
|
+ downloadTaskMap.put("redisKey", redisKey);
|
|
|
+ downloadTaskMap.put("redisExpireSeconds", seconds);
|
|
|
+ downloadTaskMap.put("redisStoreTime", redisStoreTime); // 新增秒级存储时间
|
|
|
+
|
|
|
+ // Map转JSON字符串(单独捕获序列化异常,不影响核心逻辑)
|
|
|
+ String downloadTaskJson = objectMapper.writeValueAsString(downloadTaskMap);
|
|
|
+
|
|
|
+ // 更新发票表(和红冲方法用相同的DAO/实体,保持风格统一)
|
|
|
+ WorkInvoice workInvoice = new WorkInvoice();
|
|
|
+ workInvoice.setId(workInvoiceId);
|
|
|
+ workInvoice.setBlueDownloadInvoiceJson(downloadTaskJson);
|
|
|
+ workInvoiceDao.updateRedInvoiceJsonByWorkInvoiceId(workInvoice);
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
} finally {
|
|
|
@@ -463,7 +561,7 @@ public class OMSDisposeService {
|
|
|
InvoiceTokenInfo.setData(string);
|
|
|
String jsonInvoiceStr = JSON.toJSONString(InvoiceTokenInfo);
|
|
|
|
|
|
- String jsonInvoicResultStr = HttpPostJsonUtil.doPost("https://www.oms.ejinshui-cloud.com:8899/prod-api/output/server/invoice/makeredinv", jsonInvoiceStr);
|
|
|
+ String jsonInvoicResultStr = HttpPostJsonUtil.doPost(omsUrl + "/prod-api/output/server/invoice/makeredinv", jsonInvoiceStr);
|
|
|
System.out.println("✅ 快速红冲订单提交接口返回值:" + jsonInvoicResultStr);
|
|
|
map.put("快速红冲订单接口信息", jsonInvoicResultStr);
|
|
|
|
|
|
@@ -582,7 +680,7 @@ public class OMSDisposeService {
|
|
|
InvoiceTokenInfo.setData(string);
|
|
|
String jsonInvoiceStr = JSON.toJSONString(InvoiceTokenInfo);
|
|
|
|
|
|
- String jsonInvoicResultStr = HttpPostJsonUtil.doPost("https://www.oms.ejinshui-cloud.com:8899/prod-api/output/server/redApply/apply", jsonInvoiceStr);
|
|
|
+ String jsonInvoicResultStr = HttpPostJsonUtil.doPost(omsUrl + "/prod-api/output/server/redApply/apply", jsonInvoiceStr);
|
|
|
System.out.println("✅ 全场景红冲订单提交接口返回值:" + jsonInvoicResultStr);
|
|
|
map.put("全场景红冲订单接口信息", jsonInvoicResultStr);
|
|
|
|
|
|
@@ -663,6 +761,7 @@ public class OMSDisposeService {
|
|
|
* @param applyNo 发票id
|
|
|
* @param startTime 这个任务开始时间。限制:开始3天内如果双方没有全部确认,则本次红冲失败
|
|
|
*/
|
|
|
+ @Transactional(readOnly = false)
|
|
|
public void saveRedInvoiceTaskToRedis(String workInvoiceId, int remainRetryTimes, String jsonInvoicResultStr, String accessToken, String applyNo, long startTime, String informType) {
|
|
|
Jedis jedis = null;
|
|
|
try {
|
|
|
@@ -676,6 +775,31 @@ public class OMSDisposeService {
|
|
|
jedis.hset(redisKey, "informType", informType);
|
|
|
jedis.hset(redisKey, "startTime", String.valueOf(startTime));
|
|
|
jedis.expire(redisKey, 259200 + 3600); // 3天+1小时过期
|
|
|
+
|
|
|
+
|
|
|
+ //将对应的redis中数据进行存储到数据库中,放置redis数据崩溃丢失
|
|
|
+ // 1. 封装Redis中所有存储的参数到Map(和Redis键值完全一致,方便后期回滚解析)
|
|
|
+ long redisStoreTime = System.currentTimeMillis() / 1000; // 核心:精确到秒,long类型
|
|
|
+ Map<String, Object> redInvoiceMap = new HashMap<>(); // 容量从8改为10,适配新字段
|
|
|
+ redInvoiceMap.put("remainRetryTimes", remainRetryTimes);
|
|
|
+ redInvoiceMap.put("jsonInvoicResultStr", jsonInvoicResultStr);
|
|
|
+ redInvoiceMap.put("accessToken", accessToken);
|
|
|
+ redInvoiceMap.put("workInvoiceId", workInvoiceId);
|
|
|
+ redInvoiceMap.put("informType", informType);
|
|
|
+ redInvoiceMap.put("startTime", startTime);
|
|
|
+ redInvoiceMap.put("redisKey", redisKey);
|
|
|
+ redInvoiceMap.put("redisExpireSeconds", 259200 + 3600);
|
|
|
+ redInvoiceMap.put("redisStoreTime", redisStoreTime); // 新增:Redis存储时间(秒级时间戳)
|
|
|
+
|
|
|
+ // 2. Map转JSON字符串(Spring内置Jackson,无额外依赖)
|
|
|
+ String redInvoiceJson = objectMapper.writeValueAsString(redInvoiceMap);
|
|
|
+
|
|
|
+ WorkInvoice workInvoice = new WorkInvoice();
|
|
|
+ workInvoice.setId(workInvoiceId);
|
|
|
+ workInvoice.setRedInvoiceJson(redInvoiceJson);
|
|
|
+ // 3. 更新现有发票表的JSON字段(根据发票ID精准更新)
|
|
|
+ workInvoiceDao.updateRedInvoiceJsonByWorkInvoiceId(workInvoice);
|
|
|
+
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
handleInvoiceRetryAllFail(accessToken, workInvoiceId, "全类型红冲--红字确认单查询接口发起失败,请重新发起", informType); // 解析失败也执行兜底方法
|