|
|
@@ -40,16 +40,20 @@ import com.jeeplus.modules.workinvoice.entity.OMS.InvoiceDown.OMSInvoiceDetailIn
|
|
|
import com.jeeplus.modules.workinvoice.entity.OMS.InvoiceOMSImportInfo;
|
|
|
import com.jeeplus.modules.workinvoice.entity.OMS.OMSAccessTokenInfo;
|
|
|
import com.jeeplus.modules.workinvoice.entity.OMS.OMSInvoiceResultDownloadData;
|
|
|
+import com.jeeplus.modules.workinvoice.entity.OMS.fastRed.OMSRedInvoiceConfirmInfo;
|
|
|
+import com.jeeplus.modules.workinvoice.entity.OMS.fastRed.OMSRedInvoiceConfirmResponse;
|
|
|
import com.jeeplus.modules.workinvoice.entity.TemporaryInvoiceInfo;
|
|
|
import com.jeeplus.modules.workinvoice.service.WorkInvoiceService;
|
|
|
import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
|
|
|
import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
|
|
|
+import com.jeeplus.modules.workinvoice.utils.RedInvoiceScheduledTask;
|
|
|
import com.jeeplus.modules.workinvoice.utils.ThreadPoolUtil;
|
|
|
import com.jeeplus.modules.workreimbursement.service.WorkReimbursementService;
|
|
|
import com.jeeplus.modules.workstaff.service.WorkStaffBasicInfoService;
|
|
|
import freemarker.template.Configuration;
|
|
|
import freemarker.template.Template;
|
|
|
import org.activiti.engine.HistoryService;
|
|
|
+import org.apache.ibatis.annotations.Param;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
@@ -942,23 +946,33 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
|
|
|
|
|
|
/**
|
|
|
+ * 给accessToken查询的有效时间设置为1天
|
|
|
+ */
|
|
|
+ private final int seconds = 86400;
|
|
|
+ private final String appId = "sscs";
|
|
|
+ private final String appKey = "sscs";
|
|
|
+ //如果接口访问不正确,可以循环访问的次数
|
|
|
+ private final int remainRetryTimes = 10;
|
|
|
+ /**
|
|
|
+ * 开具蓝票
|
|
|
* OMS发票测试 完整最终版【最终最终定稿,完全匹配你的所有要求】
|
|
|
* 精准码值规则:
|
|
|
* 0000=成功执行下载 | 9998=5次重试/30秒 | 0003=清token从头执行 | 0001/0002/其他码=直接执行兜底方法修改系统信息
|
|
|
+ * @param workInvoiceId 对应的应该是发票管理中的 id 即 work_invoice表中需要开票的id(这个id应该被传到redis中进行记录,方便后期回调的时候进行处理)
|
|
|
+ * @return
|
|
|
*/
|
|
|
@RequestMapping(value = "/invoiceOMSView")
|
|
|
@ResponseBody
|
|
|
@Transactional(readOnly = false)
|
|
|
- public Map<String,Object> invoiceOMSView(){
|
|
|
+ public Map<String,Object> invoiceOMSView(@Param("orderno") String workInvoiceId){
|
|
|
Map<String,Object> map = new HashMap<>();
|
|
|
// 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
|
|
|
- doInvoiceBusiness(map);
|
|
|
+ doInvoiceBusiness(map, workInvoiceId);
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
// ======================== 抽离核心业务流程:方便0003时从头重新调用 =========================
|
|
|
- private void doInvoiceBusiness(Map<String,Object> map) {
|
|
|
- int seconds = 86400;
|
|
|
+ private void doInvoiceBusiness(Map<String,Object> map, String workInvoiceId) {
|
|
|
Jedis jedis = null;
|
|
|
String accessToken = null;
|
|
|
try {
|
|
|
@@ -966,7 +980,7 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
accessToken = jedis.get("OMSAccessToken");
|
|
|
if(StringUtils.isBlank(accessToken)){
|
|
|
// 获取AccessToken 9998重试5次
|
|
|
- accessToken = getOmsAccessTokenWithRetry(5);
|
|
|
+ accessToken = getOmsAccessTokenWithRetry(5, "accessToken");
|
|
|
if(StringUtils.isNotBlank(accessToken)){
|
|
|
jedis.setex("OMSAccessToken", seconds, accessToken);
|
|
|
map.put("token状态", "重新获取token成功,存入Redis");
|
|
|
@@ -980,11 +994,12 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
}
|
|
|
|
|
|
OMSNationUtil util = new OMSNationUtil();
|
|
|
- String string = util.neatenData();
|
|
|
+ //生成开票基础信息
|
|
|
+ String string = util.neatenData(workInvoiceId);
|
|
|
|
|
|
OMSAccessTokenInfo InvoiceTokenInfo = new OMSAccessTokenInfo();
|
|
|
- InvoiceTokenInfo.setAppId("sscs");
|
|
|
- InvoiceTokenInfo.setAppKey("sscs");
|
|
|
+ InvoiceTokenInfo.setAppId(appId);
|
|
|
+ InvoiceTokenInfo.setAppKey(appKey);
|
|
|
InvoiceTokenInfo.setExchangeId(UUID.randomUUID().toString());
|
|
|
InvoiceTokenInfo.setAccessToken(accessToken);
|
|
|
InvoiceTokenInfo.setData(string);
|
|
|
@@ -998,7 +1013,7 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
if(StringUtils.isNotBlank(jsonInvoicResultStr)){
|
|
|
String finalAccessToken = accessToken;
|
|
|
String finalJsonInvoiceStr = jsonInvoiceStr;
|
|
|
- executeOrderUploadRetry(5, jsonInvoicResultStr, finalJsonInvoiceStr, finalAccessToken, map);
|
|
|
+ executeOrderUploadRetry(remainRetryTimes, jsonInvoicResultStr, finalJsonInvoiceStr, finalAccessToken, workInvoiceId, map,"accessToken", "blueTicket");
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
@@ -1012,11 +1027,11 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
}
|
|
|
|
|
|
// ======================== 原有方法1:获取AccessToken 9998重试5次【无修改】 =========================
|
|
|
- private String getOmsAccessTokenWithRetry(int remainRetryTimes) {
|
|
|
+ private String getOmsAccessTokenWithRetry(int remainRetryTimes, String getKey) {
|
|
|
try {
|
|
|
OMSAccessTokenInfo tokenInfo = new OMSAccessTokenInfo();
|
|
|
- tokenInfo.setAppId("sscs");
|
|
|
- tokenInfo.setAppKey("sscs");
|
|
|
+ tokenInfo.setAppId(appId);
|
|
|
+ tokenInfo.setAppKey(appKey);
|
|
|
tokenInfo.setExchangeId(UUID.randomUUID().toString());
|
|
|
String jsonStr = JSON.toJSONString(tokenInfo);
|
|
|
String accessTokenStr = HttpPostJsonUtil.doPost("https://oms-sandbox.einvoice.js.cn:7079/prod-api/server/accessToken", jsonStr);
|
|
|
@@ -1034,7 +1049,7 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
|
|
|
String code = resultTokenInfo.getResult().getCode();
|
|
|
if ("0000".equals(code)) {
|
|
|
- String token = OMSNationUtil.extractAccessTokenFromBase64(resultTokenInfo.getData().toString());
|
|
|
+ String token = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
|
|
|
System.out.println("✅ 获取AccessToken成功,重试次数剩余:"+remainRetryTimes);
|
|
|
return token;
|
|
|
} else if ("9998".equals(code)) {
|
|
|
@@ -1042,7 +1057,7 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
int nextRetry = remainRetryTimes - 1;
|
|
|
System.err.println("⚠️ 获取AccessToken返回9998接口波动,30秒后重试,剩余次数:"+nextRetry);
|
|
|
Thread.sleep(30 * 1000);
|
|
|
- return getOmsAccessTokenWithRetry(nextRetry);
|
|
|
+ return getOmsAccessTokenWithRetry(nextRetry,getKey);
|
|
|
} else {
|
|
|
System.err.println("❌ 获取AccessToken失败:连续5次返回9998,重试次数耗尽!");
|
|
|
return "";
|
|
|
@@ -1063,7 +1078,19 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
}
|
|
|
|
|
|
// ======================== 核心修改【仅这一处,完美匹配你的最新要求】 =========================
|
|
|
- private void executeOrderUploadRetry(int remainRetryTimes, String jsonInvoicResultStr, String jsonInvoiceStr, String accessToken, Map<String,Object> map) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对方法进行发起并进行处理
|
|
|
+ * @param remainRetryTimes
|
|
|
+ * @param jsonInvoicResultStr
|
|
|
+ * @param jsonInvoiceStr
|
|
|
+ * @param accessToken
|
|
|
+ * @param orderno
|
|
|
+ * @param map
|
|
|
+ * @param getKey
|
|
|
+ * @param initiationType 用来判定是什么类型的,比如蓝票、全类型红票、还是快捷红票
|
|
|
+ */
|
|
|
+ private void executeOrderUploadRetry(int remainRetryTimes, String jsonInvoicResultStr, String jsonInvoiceStr, String accessToken, String orderno, Map<String,Object> map, String getKey, String initiationType) {
|
|
|
String jsonInvoicResult = "";
|
|
|
try {
|
|
|
OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(jsonInvoicResultStr, OMSAccessTokenInfo.class);
|
|
|
@@ -1073,16 +1100,25 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
return;
|
|
|
}
|
|
|
String code = resultTokenInfo.getResult().getCode();
|
|
|
+ String message = resultTokenInfo.getResult().getMessage();
|
|
|
|
|
|
// ======================== 所有码值规则 全部在这里【最终定稿】=========================
|
|
|
if ("0000".equals(code)) {
|
|
|
// ✅ 0000 成功:解析数据+存入map+触发30秒后异步下载发票
|
|
|
- jsonInvoicResult = OMSNationUtil.extractAccessTokenFromBase64(resultTokenInfo.getData().toString());
|
|
|
+ jsonInvoicResult = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
|
|
|
map.put("订单接口返回值",jsonInvoicResult);
|
|
|
System.out.println("✅ 订单上传返回0000成功,触发发票下载接口");
|
|
|
- ThreadPoolUtil.executeDelay(30, () -> {
|
|
|
- executeInvoiceDownloadWithRetry(5, accessToken);
|
|
|
- });
|
|
|
+ if(StringUtils.isNotBlank(jsonInvoicResult)){
|
|
|
+ if(initiationType.equals("fastRed")){
|
|
|
+ orderno = jsonInvoicResult;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String finalOrderno = orderno;
|
|
|
+ // 存入Redis,由InvoiceDownloadTask接管
|
|
|
+ saveInvoiceDownloadTaskToRedis(accessToken, finalOrderno);
|
|
|
+ System.out.println("✅ 解析开票数据任务["+finalOrderno+"]已存入Redis,由InvoiceDownloadTask接管重试");
|
|
|
+
|
|
|
+
|
|
|
} else if ("9998".equals(code)) {
|
|
|
// ✅ 9998 接口波动:延迟30秒+重新调用接口+重试次数-1,最多5次
|
|
|
if (remainRetryTimes > 1) {
|
|
|
@@ -1091,7 +1127,7 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
Thread.sleep(30 * 1000);
|
|
|
String newResultStr = HttpPostJsonUtil.doPost("https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/order/upload", jsonInvoiceStr);
|
|
|
map.put("订单接口信息-重试"+(6-nextRetry), newResultStr);
|
|
|
- executeOrderUploadRetry(nextRetry, newResultStr, jsonInvoiceStr, accessToken, map);
|
|
|
+ executeOrderUploadRetry(nextRetry, newResultStr, jsonInvoiceStr, accessToken, orderno, map,getKey, initiationType);
|
|
|
} else {
|
|
|
System.err.println("❌ 订单上传失败:连续5次9998,重试次数耗尽!");
|
|
|
handleInvoiceRetryAllFail(accessToken); // 5次9998耗尽也执行兜底方法
|
|
|
@@ -1110,10 +1146,11 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
} finally {
|
|
|
if(jedis != null) jedis.close();
|
|
|
}
|
|
|
- doInvoiceBusiness(map);
|
|
|
+ doInvoiceBusiness(map, orderno);
|
|
|
} else {
|
|
|
// ✅ ✅ ✅ 核心修正:0001/0002/其他任意错误码 → 直接调用handleInvoiceRetryAllFail执行修改系统信息逻辑 ✅ ✅ ✅
|
|
|
System.err.println("❌ 订单上传返回业务错误码:"+code+"(0001/0002等),立即执行失败兜底逻辑修改系统信息!");
|
|
|
+ System.err.println("❌ 订单上传返回业务错误原因:"+message);
|
|
|
map.put("订单状态", "失败,错误码:"+code);
|
|
|
handleInvoiceRetryAllFail(accessToken); // 关键:直接执行你的修改逻辑,不抛异常、不重试
|
|
|
}
|
|
|
@@ -1128,14 +1165,21 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // ======================== 原有方法2:发票下载接口重试5次【无任何修改,一行未动】 =========================
|
|
|
- private void executeInvoiceDownloadWithRetry(int remainingRetryTimes, String accessToken) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 临时访问接口
|
|
|
+ * @param accessToken
|
|
|
+ * @param orderno
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/executeInvoiceDownload")
|
|
|
+ @ResponseBody
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public void executeInvoiceDownload(String accessToken, String orderno) {
|
|
|
try {
|
|
|
- System.out.println("✅ 延迟执行成功,剩余重试次数:" + remainingRetryTimes + ",开始调用发票下载接口");
|
|
|
|
|
|
OMSInvoiceResultDownloadData getInvoiceInfo = new OMSInvoiceResultDownloadData();
|
|
|
getInvoiceInfo.setDeptCode("7777");
|
|
|
- getInvoiceInfo.setOrderno("fff79669f3774c2a8be557e909a746d5");
|
|
|
+ getInvoiceInfo.setOrderno(orderno);
|
|
|
getInvoiceInfo.setIsDetail("1");
|
|
|
String jsonInvoiceInfoStr = JSON.toJSONString(getInvoiceInfo);
|
|
|
String base64Str = Base64.getEncoder().encodeToString(jsonInvoiceInfoStr.getBytes(StandardCharsets.UTF_8));
|
|
|
@@ -1152,7 +1196,6 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
System.out.println("发票开票结果invoiceResultStr:" + invoiceResultStr);
|
|
|
|
|
|
String invoceDownJsonStr = null;
|
|
|
- boolean isSuccess = false;
|
|
|
if(StringUtils.isNotBlank(invoiceResultStr)){
|
|
|
OMSAccessTokenInfo resultDownInfo = JSON.parseObject(invoiceResultStr, OMSAccessTokenInfo.class);
|
|
|
if(null != resultDownInfo.getResult() && "0000".equals(resultDownInfo.getResult().getCode())){
|
|
|
@@ -1160,44 +1203,39 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
if(StringUtils.isNotBlank(invoceDownJsonStr)){
|
|
|
OMSInvoiceDetailInfo invoiceInfo = JSONObject.parseObject(invoceDownJsonStr, OMSInvoiceDetailInfo.class);
|
|
|
if (invoiceInfo != null) {
|
|
|
- System.out.println("✅ 第"+(6-remainingRetryTimes)+"次调用发票接口成功,拿到有效数据!");
|
|
|
- System.out.println("getOfdUrl" + invoiceInfo.getOfdUrl());
|
|
|
- System.out.println("getPdfUrl" + invoiceInfo.getPdfUrl());
|
|
|
- System.out.println("getXmlUrl" + invoiceInfo.getXmlUrl());
|
|
|
- isSuccess = true;
|
|
|
+ System.out.println("✅ 第1次调用发票接口成功,拿到有效数据!");
|
|
|
+ System.out.println("allEinVno:" + invoiceInfo.getAllEinVno()); //数电票号码
|
|
|
+ System.out.println("getOfdUrl:" + invoiceInfo.getOfdUrl());
|
|
|
+ System.out.println("getPdfUrl:" + invoiceInfo.getPdfUrl());
|
|
|
+ System.out.println("getXmlUrl:" + invoiceInfo.getXmlUrl());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (isSuccess) {
|
|
|
- System.out.println("✅ 发票接口调用成功,重试流程结束,执行后续业务");
|
|
|
- return;
|
|
|
- } else {
|
|
|
- if (remainingRetryTimes > 1) {
|
|
|
- int nextRetryTimes = remainingRetryTimes - 1;
|
|
|
- System.out.println("❌ 发票接口返回结果异常/数据未就绪,准备重试!剩余重试次数:" + nextRetryTimes);
|
|
|
- ThreadPoolUtil.executeDelay(30, () -> {
|
|
|
- executeInvoiceDownloadWithRetry(nextRetryTimes, accessToken);
|
|
|
- });
|
|
|
- } else {
|
|
|
- System.err.println("❌ 发票接口调用失败,已重试5次全部失败,触发系统信息修改逻辑!");
|
|
|
- handleInvoiceRetryAllFail(accessToken);
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
- System.err.println("❌ 调用发票接口抛出异常,剩余重试次数:" + remainingRetryTimes);
|
|
|
- if (remainingRetryTimes > 1) {
|
|
|
- int nextRetryTimes = remainingRetryTimes - 1;
|
|
|
- ThreadPoolUtil.executeDelay(30, () -> {
|
|
|
- executeInvoiceDownloadWithRetry(nextRetryTimes, accessToken);
|
|
|
- });
|
|
|
- } else {
|
|
|
- System.err.println("❌ 发票接口调用抛出异常,已重试5次全部失败,触发系统信息修改逻辑!");
|
|
|
- handleInvoiceRetryAllFail(accessToken);
|
|
|
- }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // ========== 新增:解析开票数据Redis操作(仅新增,不修改原有) ==========
|
|
|
+ private void saveInvoiceDownloadTaskToRedis(String accessToken, String orderno) {
|
|
|
+ Jedis jedis = null;
|
|
|
+ try {
|
|
|
+ jedis = JedisUtils.getResource();
|
|
|
+ String redisKey = "OMS_invoice_download:" + orderno;
|
|
|
+ jedis.hset(redisKey, "accessToken", accessToken);
|
|
|
+ jedis.hset(redisKey, "orderno", orderno);
|
|
|
+ jedis.hset(redisKey, "firstExecTime", String.valueOf(System.currentTimeMillis()));
|
|
|
+ jedis.expire(redisKey, 86400); // 1天过期
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (jedis != null) jedis.close();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1228,4 +1266,207 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开具红票(快速红冲)
|
|
|
+ * OMS发票测试 完整最终版【最终最终定稿,完全匹配你的所有要求】
|
|
|
+ * 精准码值规则:
|
|
|
+ * 0000=成功执行下载 | 9998=5次重试/30秒 | 0003=清token从头执行 | 0001/0002/其他码=直接执行兜底方法修改系统信息
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/invoiceFastRedOMSView")
|
|
|
+ @ResponseBody
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public Map<String,Object> invoiceFastRedOMSView(String allEinvno){
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ // 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
|
|
|
+ doFastRedInvoiceBusiness(map, allEinvno);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ======================== 抽离核心业务流程:方便0003时从头重新调用 =========================
|
|
|
+ private void doFastRedInvoiceBusiness(Map<String,Object> map, String allEinvno) {
|
|
|
+ int seconds = 86400;
|
|
|
+ Jedis jedis = null;
|
|
|
+ String accessToken = null;
|
|
|
+ try {
|
|
|
+ jedis = JedisUtils.getResource();
|
|
|
+ accessToken = jedis.get("OMSAccessToken");
|
|
|
+ if(StringUtils.isBlank(accessToken)){
|
|
|
+ // 获取AccessToken 9998重试5次
|
|
|
+ accessToken = getOmsAccessTokenWithRetry(5, "accessToken");
|
|
|
+ if(StringUtils.isNotBlank(accessToken)){
|
|
|
+ jedis.setex("OMSAccessToken", seconds, accessToken);
|
|
|
+ map.put("token状态", "重新获取token成功,存入Redis");
|
|
|
+ } else {
|
|
|
+ accessToken = "";
|
|
|
+ map.put("token状态", "获取token失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ map.put("token状态", "从Redis获取token成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ OMSNationUtil util = new OMSNationUtil();
|
|
|
+ String string = util.neatenFastRedInvoiceData(allEinvno);
|
|
|
+
|
|
|
+ OMSAccessTokenInfo InvoiceTokenInfo = new OMSAccessTokenInfo();
|
|
|
+ InvoiceTokenInfo.setAppId("sscs");
|
|
|
+ InvoiceTokenInfo.setAppKey("sscs");
|
|
|
+ InvoiceTokenInfo.setExchangeId(UUID.randomUUID().toString());
|
|
|
+ InvoiceTokenInfo.setAccessToken(accessToken);
|
|
|
+ InvoiceTokenInfo.setData(string);
|
|
|
+ String jsonInvoiceStr = JSON.toJSONString(InvoiceTokenInfo);
|
|
|
+
|
|
|
+ String jsonInvoicResultStr = HttpPostJsonUtil.doPost("https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/invoice/makeredinv", jsonInvoiceStr);
|
|
|
+ System.out.println("✅ 快速红冲订单提交接口返回值:" + jsonInvoicResultStr);
|
|
|
+ map.put("快速红冲订单接口信息", jsonInvoicResultStr);
|
|
|
+
|
|
|
+ // 调用订单上传重试方法(包含所有码值规则)
|
|
|
+ if(StringUtils.isNotBlank(jsonInvoicResultStr)){
|
|
|
+ String finalAccessToken = accessToken;
|
|
|
+ String finalJsonInvoiceStr = jsonInvoiceStr;
|
|
|
+ executeOrderUploadRetry(5, jsonInvoicResultStr, finalJsonInvoiceStr, finalAccessToken, allEinvno, map, "orderno", "fastRed");
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ map.put("errorMsg", "系统异常:" + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ if(jedis != null){
|
|
|
+ jedis.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开具红票(全场景红冲,包含已入账红冲处理。我方发起)
|
|
|
+ * @param applyNo 申请单号
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/invoiceAllScenarioRedOMSView")
|
|
|
+ @ResponseBody
|
|
|
+ @Transactional(readOnly = false)
|
|
|
+ public Map<String,Object> invoiceAllScenarioRedOMSView(String applyNo, String originalInvno){
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ // 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
|
|
|
+ doAllScenarioRedInvoiceBusiness(map, applyNo, originalInvno);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用生成红字确认申请单
|
|
|
+ * @param map
|
|
|
+ * @param applyNo
|
|
|
+ * @param originalInvno
|
|
|
+ */
|
|
|
+ private void doAllScenarioRedInvoiceBusiness(Map<String,Object> map, String applyNo, String originalInvno) {
|
|
|
+ int seconds = 86400;
|
|
|
+ Jedis jedis = null;
|
|
|
+ String accessToken = null;
|
|
|
+ try {
|
|
|
+ jedis = JedisUtils.getResource();
|
|
|
+ accessToken = jedis.get("OMSAccessToken");
|
|
|
+ if(StringUtils.isBlank(accessToken)){
|
|
|
+ // 获取AccessToken 9998重试5次
|
|
|
+ accessToken = getOmsAccessTokenWithRetry(5, "accessToken");
|
|
|
+ if(StringUtils.isNotBlank(accessToken)){
|
|
|
+ jedis.setex("OMSAccessToken", seconds, accessToken);
|
|
|
+ map.put("token状态", "重新获取token成功,存入Redis");
|
|
|
+ } else {
|
|
|
+ accessToken = "";
|
|
|
+ map.put("token状态", "获取token失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ map.put("token状态", "从Redis获取token成功");
|
|
|
+ }
|
|
|
+
|
|
|
+ OMSNationUtil util = new OMSNationUtil();
|
|
|
+ //生成红冲的数据
|
|
|
+ String string = util.neatenAllScenarioRedInvoiceData(applyNo, originalInvno);
|
|
|
+
|
|
|
+ OMSAccessTokenInfo InvoiceTokenInfo = new OMSAccessTokenInfo();
|
|
|
+ InvoiceTokenInfo.setAppId("sscs");
|
|
|
+ InvoiceTokenInfo.setAppKey("sscs");
|
|
|
+ InvoiceTokenInfo.setExchangeId(UUID.randomUUID().toString());
|
|
|
+ InvoiceTokenInfo.setAccessToken(accessToken);
|
|
|
+ InvoiceTokenInfo.setData(string);
|
|
|
+ String jsonInvoiceStr = JSON.toJSONString(InvoiceTokenInfo);
|
|
|
+
|
|
|
+ String jsonInvoicResultStr = HttpPostJsonUtil.doPost("https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/redApply/apply", jsonInvoiceStr);
|
|
|
+ System.out.println("✅ 全场景红冲订单提交接口返回值:" + jsonInvoicResultStr);
|
|
|
+ map.put("全场景红冲订单接口信息", jsonInvoicResultStr);
|
|
|
+
|
|
|
+ // 调用订单上传重试方法(包含所有码值规则)
|
|
|
+ if(StringUtils.isNotBlank(jsonInvoicResultStr)){
|
|
|
+ String finalAccessToken = accessToken;
|
|
|
+ queryRedInvoiceConfirm (5, jsonInvoicResultStr, finalAccessToken, applyNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ map.put("errorMsg", "系统异常:" + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ if(jedis != null){
|
|
|
+ jedis.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 全类型红冲--红字确认单查询接口(仅存Redis,不执行业务)
|
|
|
+ * @param remainRetryTimes 剩余重试次数
|
|
|
+ * @param jsonInvoicResultStr 需要解析的返回值密文
|
|
|
+ * @param accessToken accessToken
|
|
|
+ * @param applyNo
|
|
|
+ */
|
|
|
+ private void queryRedInvoiceConfirm (int remainRetryTimes, String jsonInvoicResultStr, String accessToken, String applyNo) {
|
|
|
+ try {
|
|
|
+ OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(jsonInvoicResultStr, OMSAccessTokenInfo.class);
|
|
|
+ if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
|
|
|
+ System.err.println("❌ 全场景红冲订单提交接口返回值解析失败,剩余重试次数:"+remainRetryTimes);
|
|
|
+ handleInvoiceRetryAllFail(accessToken); // 解析失败直接兜底
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String code = resultTokenInfo.getResult().getCode();
|
|
|
+
|
|
|
+ if ("0000".equals(code)) {
|
|
|
+ // 仅存入Redis,删除所有业务执行逻辑
|
|
|
+ saveRedInvoiceTaskToRedis(remainRetryTimes, jsonInvoicResultStr, accessToken, applyNo, System.currentTimeMillis());
|
|
|
+ System.out.println("✅ 红冲任务["+applyNo+"]已存入Redis,由定时任务接管执行");
|
|
|
+ } else {
|
|
|
+ String message = resultTokenInfo.getResult().getMessage();
|
|
|
+ System.err.println("❌ 订单上传返回业务错误码:"+code+",触发兜底逻辑!");
|
|
|
+ handleInvoiceRetryAllFail(accessToken);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ handleInvoiceRetryAllFail(accessToken);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 存储红冲任务到Redis(供原有业务代码调用,参数完整)
|
|
|
+ */
|
|
|
+ private void saveRedInvoiceTaskToRedis(int remainRetryTimes, String jsonInvoicResultStr, String accessToken, String applyNo, long startTime) {
|
|
|
+ Jedis jedis = null;
|
|
|
+ try {
|
|
|
+ jedis = JedisUtils.getResource();
|
|
|
+ String redisKey = "red_invoice_task:" + applyNo;
|
|
|
+ // 存储所有执行所需的参数(确保定时任务能独立执行)
|
|
|
+ jedis.hset(redisKey, "remainRetryTimes", String.valueOf(remainRetryTimes));
|
|
|
+ jedis.hset(redisKey, "jsonInvoicResultStr", jsonInvoicResultStr);
|
|
|
+ jedis.hset(redisKey, "accessToken", accessToken);
|
|
|
+ jedis.hset(redisKey, "applyNo", applyNo);
|
|
|
+ jedis.hset(redisKey, "startTime", String.valueOf(startTime));
|
|
|
+ jedis.expire(redisKey, 259200 + 3600); // 3天+1小时过期
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ handleInvoiceRetryAllFail(accessToken);
|
|
|
+ } finally {
|
|
|
+ if (jedis != null) jedis.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|