Jelajahi Sumber

OMS发票信息部分代码上传

徐滕 1 bulan lalu
induk
melakukan
56bec26d31

+ 13 - 413
src/main/java/com/jeeplus/modules/ruralprojectrecords/web/RuralProjectSignatureOldMessageDisposeController.java

@@ -43,6 +43,7 @@ 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.OMS.OMSDisposeService;
 import com.jeeplus.modules.workinvoice.service.WorkInvoiceService;
 import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
 import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
@@ -129,6 +130,8 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
     private MilitaryIndustryConfidentialityService militaryIndustryConfidentialityService;
     @Autowired
     private WorkStaffBasicInfoService workStaffBasicInfoService;
+    @Autowired
+    private OMSDisposeService omsDisposeService;
 
     private static final String HTTPTOP = Global.getConfig("signature_http_top");
 
@@ -948,11 +951,10 @@ 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;
+    private final String appId = "hyc1";
+    private final String appKey = "hyc1";
+    private final String deptCode = "500102204228315131";
+
     /**
      * 开具蓝票
      * OMS发票测试 完整最终版【最终最终定稿,完全匹配你的所有要求】
@@ -967,203 +969,13 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
     public Map<String,Object> invoiceOMSView(@Param("orderno") String workInvoiceId){
         Map<String,Object> map = new HashMap<>();
         // 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
-        doInvoiceBusiness(map, workInvoiceId);
+        omsDisposeService.doInvoiceBusiness(map, workInvoiceId);
         return map;
     }
 
-    // ======================== 抽离核心业务流程:方便0003时从头重新调用 =========================
-    private void doInvoiceBusiness(Map<String,Object> map, String workInvoiceId) {
-        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.neatenData(workInvoiceId);
-
-            OMSAccessTokenInfo InvoiceTokenInfo = new OMSAccessTokenInfo();
-            InvoiceTokenInfo.setAppId(appId);
-            InvoiceTokenInfo.setAppKey(appKey);
-            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/order/upload", jsonInvoiceStr);
-            System.out.println("✅ 订单提交接口返回值:" + jsonInvoicResultStr);
-            map.put("订单接口信息", jsonInvoicResultStr);
-
-            // 调用订单上传重试方法(包含所有码值规则)
-            if(StringUtils.isNotBlank(jsonInvoicResultStr)){
-                String finalAccessToken = accessToken;
-                String finalJsonInvoiceStr = jsonInvoiceStr;
-                executeOrderUploadRetry(remainRetryTimes, jsonInvoicResultStr, finalJsonInvoiceStr, finalAccessToken, workInvoiceId, map,"accessToken", "blueTicket");
-            }
 
-        } catch (Exception e) {
-            e.printStackTrace();
-            map.put("errorMsg", "系统异常:" + e.getMessage());
-        } finally {
-            if(jedis != null){
-                jedis.close();
-            }
-        }
-    }
 
-    // ======================== 原有方法1:获取AccessToken 9998重试5次【无修改】 =========================
-    private String getOmsAccessTokenWithRetry(int remainRetryTimes, String getKey) {
-        try {
-            OMSAccessTokenInfo tokenInfo = new OMSAccessTokenInfo();
-            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);
-
-            if(StringUtils.isBlank(accessTokenStr)){
-                System.err.println("获取AccessToken失败:接口返回空,剩余重试次数:"+remainRetryTimes);
-                return "";
-            }
-
-            OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(accessTokenStr, OMSAccessTokenInfo.class);
-            if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
-                System.err.println("获取AccessToken失败:返回结果解析异常,剩余重试次数:"+remainRetryTimes);
-                return "";
-            }
-
-            String code = resultTokenInfo.getResult().getCode();
-            if ("0000".equals(code)) {
-                String token = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
-                System.out.println("✅ 获取AccessToken成功,重试次数剩余:"+remainRetryTimes);
-                return token;
-            } else if ("9998".equals(code)) {
-                if (remainRetryTimes > 1) {
-                    int nextRetry = remainRetryTimes - 1;
-                    System.err.println("⚠️ 获取AccessToken返回9998接口波动,30秒后重试,剩余次数:"+nextRetry);
-                    Thread.sleep(30 * 1000);
-                    return getOmsAccessTokenWithRetry(nextRetry,getKey);
-                } else {
-                    System.err.println("❌ 获取AccessToken失败:连续5次返回9998,重试次数耗尽!");
-                    return "";
-                }
-            } else {
-                System.err.println("❌ 获取AccessToken失败:返回业务错误码,code="+code);
-                return "";
-            }
-        } catch (InterruptedException e) {
-            System.err.println("❌ 获取AccessToken失败:重试延迟被中断");
-            Thread.currentThread().interrupt();
-            return "";
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.err.println("❌ 获取AccessToken失败:调用接口异常,剩余重试次数:"+remainRetryTimes);
-            return "";
-        }
-    }
-
-    // ======================== 核心修改【仅这一处,完美匹配你的最新要求】 =========================
-
-    /**
-     * 对方法进行发起并进行处理
-     * @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);
-            if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
-                System.err.println("❌ 订单上传解析失败,剩余重试次数:"+remainRetryTimes);
-                handleInvoiceRetryAllFail(accessToken); // 解析失败也执行兜底方法
-                return;
-            }
-            String code = resultTokenInfo.getResult().getCode();
-            String message = resultTokenInfo.getResult().getMessage();
-
-            // ======================== 所有码值规则 全部在这里【最终定稿】=========================
-            if ("0000".equals(code)) {
-                // ✅ 0000 成功:解析数据+存入map+触发30秒后异步下载发票
-                jsonInvoicResult = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
-                map.put("订单接口返回值",jsonInvoicResult);
-                System.out.println("✅ 订单上传返回0000成功,触发发票下载接口");
-                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) {
-                    int nextRetry = remainRetryTimes - 1;
-                    System.err.println("⚠️ 订单上传返回9998接口波动,30秒后重试,剩余次数:"+nextRetry);
-                    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, orderno, map,getKey, initiationType);
-                } else {
-                    System.err.println("❌ 订单上传失败:连续5次9998,重试次数耗尽!");
-                    handleInvoiceRetryAllFail(accessToken); // 5次9998耗尽也执行兜底方法
-                    map.put("订单状态", "失败:接口波动次数超限");
-                }
-            } else if ("0003".equals(code)) {
-                // ✅ 0003 token失效:清除旧token → 重新获取token → 从头完整执行所有流程
-                System.err.println("⚠️ 订单上传返回0003(token失效),开始重新获取token并从头执行流程");
-                Jedis jedis = null;
-                try {
-                    jedis = JedisUtils.getResource();
-                    jedis.del("OMSAccessToken");
-                    map.put("0003处理", "已清除旧token,准备重新获取");
-                } catch (Exception e) {
-                    e.printStackTrace();
-                } finally {
-                    if(jedis != null) jedis.close();
-                }
-                doInvoiceBusiness(map, orderno);
-            } else {
-                // ✅ ✅ ✅ 核心修正:0001/0002/其他任意错误码 → 直接调用handleInvoiceRetryAllFail执行修改系统信息逻辑 ✅ ✅ ✅
-                System.err.println("❌ 订单上传返回业务错误码:"+code+"(0001/0002等),立即执行失败兜底逻辑修改系统信息!");
-                System.err.println("❌ 订单上传返回业务错误原因:"+message);
-                map.put("订单状态", "失败,错误码:"+code);
-                handleInvoiceRetryAllFail(accessToken); // 关键:直接执行你的修改逻辑,不抛异常、不重试
-            }
-        } catch (InterruptedException e) {
-            System.err.println("❌ 订单上传重试被中断");
-            Thread.currentThread().interrupt();
-            handleInvoiceRetryAllFail(accessToken); // 中断也执行兜底方法
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.err.println("❌ 订单上传重试异常,剩余次数:"+remainRetryTimes);
-            handleInvoiceRetryAllFail(accessToken); // 异常也执行兜底方法
-        }
-    }
 
 
     /**
@@ -1178,15 +990,15 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
         try {
 
             OMSInvoiceResultDownloadData getInvoiceInfo = new OMSInvoiceResultDownloadData();
-            getInvoiceInfo.setDeptCode("7777");
+            getInvoiceInfo.setDeptCode(deptCode);
             getInvoiceInfo.setOrderno(orderno);
             getInvoiceInfo.setIsDetail("1");
             String jsonInvoiceInfoStr = JSON.toJSONString(getInvoiceInfo);
             String base64Str = Base64.getEncoder().encodeToString(jsonInvoiceInfoStr.getBytes(StandardCharsets.UTF_8));
 
             OMSAccessTokenInfo invoiceDownInfo = new OMSAccessTokenInfo();
-            invoiceDownInfo.setAppId("sscs");
-            invoiceDownInfo.setAppKey("sscs");
+            invoiceDownInfo.setAppId(appId);
+            invoiceDownInfo.setAppKey(appKey);
             invoiceDownInfo.setExchangeId(UUID.randomUUID().toString());
             invoiceDownInfo.setAccessToken(accessToken);
             invoiceDownInfo.setData(base64Str);
@@ -1222,50 +1034,6 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
 
 
 
-    // ========== 新增:解析开票数据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();
-        }
-    }
-
-    // ======================== 原有方法3:失败兜底修改系统信息【无任何修改,你的业务逻辑写这里即可】 =========================
-    private void handleInvoiceRetryAllFail(String accessToken) {
-        // ============ 你的所有【修改系统信息/更新订单状态/写失败日志】逻辑 全部写在这里!!! ============
-        try {
-            System.err.println("============ 开始执行【失败兜底-系统信息修改逻辑】 ============");
-
-            // 示例1:更新订单表的发票状态为【开票失败】
-            // orderService.updateInvoiceStatusByToken(accessToken, "99");
-
-            // 示例2:写入失败日志到数据库,方便人工排查和补偿处理
-            // invoiceFailLogService.saveFailLog(accessToken, "开票失败,错误码非0000/9998/0003", new Date());
-
-            // 示例3:标记该单据为异常,方便后台运维查看
-            // abnormalOrderService.saveAbnormalOrder(accessToken, "开票失败");
-
-            // 示例4:调用其他系统接口,同步失败状态
-            // otherSystemApi.notifyInvoiceFail(accessToken);
-
-            System.err.println("============ 【失败兜底-系统信息修改逻辑】执行完成 ============");
-
-        } catch (Exception e) {
-            // 必加:捕获这个方法的异常,避免兜底方法报错导致线程异常
-            e.printStackTrace();
-            System.err.println("❌ 执行失败兜底方法时抛出异常:" + e.getMessage());
-        }
-    }
-
 
     /**
      * 开具红票(快速红冲)
@@ -1279,64 +1047,11 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
     public Map<String,Object> invoiceFastRedOMSView(String allEinvno){
         Map<String,Object> map = new HashMap<>();
         // 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
-        doFastRedInvoiceBusiness(map, allEinvno);
+        omsDisposeService.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();
-            }
-        }
-    }
 
 
     /**
@@ -1350,123 +1065,8 @@ public class RuralProjectSignatureOldMessageDisposeController extends BaseContro
     public Map<String,Object> invoiceAllScenarioRedOMSView(String applyNo, String originalInvno){
         Map<String,Object> map = new HashMap<>();
         // 调用抽离后的核心业务方法,实现流程复用(0003时可重新调用)
-        doAllScenarioRedInvoiceBusiness(map, applyNo, originalInvno);
+        omsDisposeService.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();
-        }
-    }
-
 }

+ 16 - 3
src/main/java/com/jeeplus/modules/workcalendar/service/WorkCalendarTaskService.java

@@ -14,6 +14,7 @@ import com.jeeplus.modules.sys.utils.UserUtils;
 import com.jeeplus.modules.workcalendar.entity.WorkCalendar;
 import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
 import com.jeeplus.modules.workinvoice.service.OMS.InvoiceDownloadService;
+import com.jeeplus.modules.workinvoice.service.OMS.RedInvoiceRetryScheduledService;
 import com.jeeplus.modules.workinvoice.service.OMS.RedInvoiceScheduledService;
 import com.jeeplus.modules.workinvoice.service.WorkInvoiceService;
 import com.jeeplus.modules.workstaff.service.WorkStaffBasicInfoService;
@@ -70,6 +71,9 @@ public class WorkCalendarTaskService  {
     @Autowired
     private RedInvoiceScheduledService redInvoiceScheduledService;
 
+    @Autowired
+    private RedInvoiceRetryScheduledService redInvoiceRetryScheduledService;
+
     //@Scheduled(cron= "0 0/1 * * * ?")
     public void notifyTask() {
         logger.info("-----------定时任务开始------------------");
@@ -497,18 +501,27 @@ public class WorkCalendarTaskService  {
      * 用于发票开票获取数电票信息处理
      * 和开票系统相关的定时任务
      */
-    @Scheduled(cron = "0 */2 * * * ?")
+    //@Scheduled(cron = "0 */1 * * * ?")
     public void processInvoiceDownloadTasks() {
         invoiceDownloadService.processInvoiceDownloadTasks();
     }
 
     /**
-     * 用于发票开票获取数电票信息处理
+     * 用于发票开票红冲定时任务信息处理
      * 和开票系统相关的定时任务
      */
-    @Scheduled(cron = "0 */3 * * * ?")
+    //@Scheduled(cron = "0 */3 * * * ?")
     public void processRedInvoiceScheduledTask() {
         redInvoiceScheduledService.processAllRedInvoiceTasks();
     }
 
+    /**
+     * 用于发票开票时报9998错误时进行重新处理的方法
+     * 和开票系统相关的定时任务
+     */
+    //@Scheduled(cron = "0 */2 * * * ?")
+    public void redInvoiceRetryScheduledTask() {
+        redInvoiceRetryScheduledService.handleInvoice9998RetryTask();
+    }
+
 }

+ 15 - 13
src/main/java/com/jeeplus/modules/workinvoice/service/OMS/InvoiceDownloadService.java

@@ -9,6 +9,7 @@ import com.jeeplus.modules.workinvoice.entity.OMS.OMSInvoiceResultDownloadData;
 import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
 import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -24,6 +25,16 @@ import java.util.UUID;
 @Lazy
 public class InvoiceDownloadService {
 
+
+    private final String appId = "hyc1";
+    private final String appKey = "hyc1";
+    private final String deptCode = "500102204228315131";
+
+
+    @Autowired
+    private OMSDisposeService omsDisposeService;
+
+
     public void processInvoiceDownloadTasks() {
         Jedis jedis = null;
         try {
@@ -55,7 +66,7 @@ public class InvoiceDownloadService {
                 // 23*60*60*1000 = 82800000 ms(原86400000是24小时)
                 if (System.currentTimeMillis() - firstExecTime > 82800000L) {
                     System.err.println("[InvoiceDownloadTask] 任务["+orderno+"]已重试23小时,触发兜底");
-                    handleInvoiceRetryAllFail(accessToken);
+                    omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                     //需要修改项目相关信息
 
 
@@ -81,15 +92,15 @@ public class InvoiceDownloadService {
 
             // ========== 原始解析逻辑 —— 完全不变 ==========
             OMSInvoiceResultDownloadData getInvoiceInfo = new OMSInvoiceResultDownloadData();
-            getInvoiceInfo.setDeptCode("7777");
+            getInvoiceInfo.setDeptCode(deptCode);
             getInvoiceInfo.setOrderno(orderno);
             getInvoiceInfo.setIsDetail("1");
             String jsonInvoiceInfoStr = JSON.toJSONString(getInvoiceInfo);
             String base64Str = Base64.getEncoder().encodeToString(jsonInvoiceInfoStr.getBytes(StandardCharsets.UTF_8));
 
             OMSAccessTokenInfo invoiceDownInfo = new OMSAccessTokenInfo();
-            invoiceDownInfo.setAppId("sscs");
-            invoiceDownInfo.setAppKey("sscs");
+            invoiceDownInfo.setAppId(appId);
+            invoiceDownInfo.setAppKey(appKey);
             invoiceDownInfo.setExchangeId(UUID.randomUUID().toString());
             invoiceDownInfo.setAccessToken(accessToken);
             invoiceDownInfo.setData(base64Str);
@@ -151,13 +162,4 @@ public class InvoiceDownloadService {
         }
     }
 
-
-
-    /**
-     * 兜底逻辑
-     */
-    public void handleInvoiceRetryAllFail(String accessToken) {
-        System.err.println("📢 执行失败兜底逻辑:更新系统状态 + 通知发起人");
-        // 此处替换为你的实际兜底逻辑(如更新数据库、发送通知等)
-    }
 }

+ 493 - 0
src/main/java/com/jeeplus/modules/workinvoice/service/OMS/OMSDisposeService.java

@@ -0,0 +1,493 @@
+package com.jeeplus.modules.workinvoice.service.OMS;
+
+import com.alibaba.fastjson.JSON;
+import com.jeeplus.common.utils.JedisUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.workinvoice.entity.OMS.OMSAccessTokenInfo;
+import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
+import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import redis.clients.jedis.Jedis;
+
+import java.util.Map;
+import java.util.UUID;
+
+@Service
+@Transactional(readOnly = true)
+@Lazy
+public class OMSDisposeService {
+
+    /**
+     * 给accessToken查询的有效时间设置为1天
+     */
+    private final int seconds = 86400;
+    private final String appId = "hyc1";
+    private final String appKey = "hyc1";
+    private final String deptCode = "500102204228315131";
+    //如果接口访问不正确,可以循环访问的次数
+    private final int remainRetryTimes = 20;
+
+    /**
+     * 用于生成开蓝票信息
+     * @param map
+     * @param workInvoiceId
+     */
+    public void doInvoiceBusiness(Map<String,Object> map, String workInvoiceId) {
+        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.neatenData(workInvoiceId);
+
+            OMSAccessTokenInfo InvoiceTokenInfo = new OMSAccessTokenInfo();
+            InvoiceTokenInfo.setAppId(appId);
+            InvoiceTokenInfo.setAppKey(appKey);
+            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/order/upload", jsonInvoiceStr);
+            System.out.println("✅ 订单提交接口返回值:" + jsonInvoicResultStr);
+            map.put("订单接口信息", jsonInvoicResultStr);
+
+            // 调用订单上传重试方法(包含所有码值规则)
+            if(StringUtils.isNotBlank(jsonInvoicResultStr)){
+                String finalAccessToken = accessToken;
+                String finalJsonInvoiceStr = jsonInvoiceStr;
+                executeOrderUploadRetry(remainRetryTimes, jsonInvoicResultStr, finalJsonInvoiceStr, finalAccessToken, workInvoiceId, map,"accessToken", "blueTicket");
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.put("errorMsg", "系统异常:" + e.getMessage());
+        } finally {
+            if(jedis != null){
+                jedis.close();
+            }
+        }
+    }
+
+    /**
+     * 用于调用accessToken
+     * @param remainRetryTimes
+     * @param getKey
+     * @return
+     */
+    public String getOmsAccessTokenWithRetry(int remainRetryTimes, String getKey) {
+        try {
+            OMSAccessTokenInfo tokenInfo = new OMSAccessTokenInfo();
+            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);
+
+            if(StringUtils.isBlank(accessTokenStr)){
+                System.err.println("获取AccessToken失败:接口返回空,剩余重试次数:"+remainRetryTimes);
+                return "";
+            }
+
+            OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(accessTokenStr, OMSAccessTokenInfo.class);
+            if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
+                System.err.println("获取AccessToken失败:返回结果解析异常,剩余重试次数:"+remainRetryTimes);
+                return "";
+            }
+
+            String code = resultTokenInfo.getResult().getCode();
+            if ("0000".equals(code)) {
+                String token = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
+                System.out.println("✅ 获取AccessToken成功,重试次数剩余:"+remainRetryTimes);
+                return token;
+            } else if ("9998".equals(code)) {
+                if (remainRetryTimes > 1) {
+                    int nextRetry = remainRetryTimes - 1;
+                    System.err.println("⚠️ 获取AccessToken返回9998接口波动,30秒后重试,剩余次数:"+nextRetry);
+                    Thread.sleep(30 * 1000);
+                    return getOmsAccessTokenWithRetry(nextRetry,getKey);
+                } else {
+                    System.err.println("❌ 获取AccessToken失败:连续5次返回9998,重试次数耗尽!");
+                    return "";
+                }
+            } else {
+                System.err.println("❌ 获取AccessToken失败:返回业务错误码,code="+code);
+                return "";
+            }
+        } catch (InterruptedException e) {
+            System.err.println("❌ 获取AccessToken失败:重试延迟被中断");
+            Thread.currentThread().interrupt();
+            return "";
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println("❌ 获取AccessToken失败:调用接口异常,剩余重试次数:"+remainRetryTimes);
+            return "";
+        }
+    }
+
+
+    /**
+     * 对方法进行发起并进行处理
+     * @param remainRetryTimes
+     * @param jsonInvoicResultStr
+     * @param jsonInvoiceStr
+     * @param accessToken
+     * @param orderno
+     * @param map
+     * @param getKey
+     * @param initiationType    用来判定是什么类型的,比如蓝票、全类型红票、还是快捷红票
+     */
+    public 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);
+            if(null == resultTokenInfo || null == resultTokenInfo.getResult()){
+                System.err.println("❌ 订单上传解析失败,剩余重试次数:"+remainRetryTimes);
+                handleInvoiceRetryAllFail(accessToken); // 解析失败也执行兜底方法
+                return;
+            }
+            String code = resultTokenInfo.getResult().getCode();
+            String message = resultTokenInfo.getResult().getMessage();
+
+            // ======================== 所有码值规则 全部在这里【最终定稿】=========================
+            if ("0000".equals(code)) {
+                // ✅ 0000 成功:解析数据+存入map+触发30秒后异步下载发票
+                jsonInvoicResult = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
+                map.put("订单接口返回值",jsonInvoicResult);
+                System.out.println("✅ 订单上传返回0000成功,触发发票下载接口");
+                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)) {
+                // 通过redis调用 方式系统崩溃导致的数据丢失
+                // ✅ 9998 接口波动,放入redis中 用于定时任务进行处理
+                saveInvoiceRetryScheduledTaskToRedis(jsonInvoiceStr, accessToken, orderno, getKey, initiationType);
+
+            } else if ("0003".equals(code)) {
+                // ✅ 0003 token失效:清除旧token → 重新获取token → 从头完整执行所有流程
+                System.err.println("⚠️ 订单上传返回0003(token失效),开始重新获取token并从头执行流程");
+                Jedis jedis = null;
+                try {
+                    jedis = JedisUtils.getResource();
+                    jedis.del("OMSAccessToken");
+                    map.put("0003处理", "已清除旧token,准备重新获取");
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    if(jedis != null) jedis.close();
+                }
+                doInvoiceBusiness(map, orderno);
+            } else {
+                // ✅ ✅ ✅ 核心修正:0001/0002/其他任意错误码 → 直接调用handleInvoiceRetryAllFail执行修改系统信息逻辑 ✅ ✅ ✅
+                System.err.println("❌ 订单上传返回业务错误码:"+code+"(0001/0002等),立即执行失败兜底逻辑修改系统信息!");
+                System.err.println("❌ 订单上传返回业务错误原因:"+message);
+                map.put("订单状态", "失败,错误码:"+code);
+                handleInvoiceRetryAllFail(accessToken); // 关键:直接执行你的修改逻辑,不抛异常、不重试
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println("❌ 订单上传重试异常,剩余次数:"+remainRetryTimes);
+            handleInvoiceRetryAllFail(accessToken); // 异常也执行兜底方法
+        }
+    }
+
+    /**
+     * 用于访问接口返回9998时使用,存入Redis供定时任务处理
+     * 硬编码配置:初始重试次数20次,Redis过期时间1天(86400秒)
+     * @param jsonInvoiceStr 订单上传的JSON参数
+     * @param accessToken    AccessToken
+     * @param orderno        订单号
+     * @param getKey         获取token的key
+     * @param initiationType 开票类型(蓝票/红票)
+     */
+    public void saveInvoiceRetryScheduledTaskToRedis(String jsonInvoiceStr ,String accessToken, String orderno, String getKey, String initiationType) {
+        Jedis jedis = null;
+        // 硬编码:初始重试次数20次
+        final int INIT_RETRY_COUNT = 20;
+        // 硬编码:Redis任务过期时间1天(86400秒)
+        final int REDIS_EXPIRE_SECONDS = 86400;
+
+        try {
+            jedis = JedisUtils.getResource();
+            String redisKey = "OMS_invoice_retry_scheduled:" + orderno;
+
+            // 先检查是否已存在,存在则复用原有重试次数,不存在则初始化20次
+            String retryTimes = jedis.hget(redisKey, "retryTimes");
+            if (StringUtils.isBlank(retryTimes)) {
+                retryTimes = String.valueOf(INIT_RETRY_COUNT); // 初始20次
+            }
+
+            // 存储所有需要的字段
+            jedis.hset(redisKey, "jsonInvoiceStr", jsonInvoiceStr);
+            jedis.hset(redisKey, "accessToken", accessToken);
+            jedis.hset(redisKey, "orderno", orderno);
+            jedis.hset(redisKey, "getKey", getKey);
+            jedis.hset(redisKey, "initiationType", initiationType);
+            jedis.hset(redisKey, "firstExecTime", String.valueOf(System.currentTimeMillis()));
+            jedis.hset(redisKey, "retryTimes", retryTimes); // 重试次数
+
+            jedis.expire(redisKey, REDIS_EXPIRE_SECONDS); // 1天过期
+            System.out.println("✅ 9998重试任务已存入Redis,订单号:" + orderno + ",剩余重试次数:" + retryTimes);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println("❌ 存入9998重试任务到Redis失败,订单号:" + orderno + ",原因:" + e.getMessage());
+        } finally {
+            if (jedis != null) jedis.close();
+        }
+    }
+
+
+    /**
+     * 新增开蓝票生成的下载用的redis
+     * @param accessToken
+     * @param orderno
+     */
+    public 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, seconds); // 1天过期
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (jedis != null) jedis.close();
+        }
+    }
+
+    /**
+     * 兜底方法
+     * @param accessToken
+     */
+    public void handleInvoiceRetryAllFail(String accessToken) {
+        // ============ 你的所有【修改系统信息/更新订单状态/写失败日志】逻辑 全部写在这里!!! ============
+        try {
+            System.err.println("============ 开始执行【失败兜底-系统信息修改逻辑】 ============");
+
+            // 示例1:更新订单表的发票状态为【开票失败】
+            // orderService.updateInvoiceStatusByToken(accessToken, "99");
+
+            // 示例2:写入失败日志到数据库,方便人工排查和补偿处理
+            // invoiceFailLogService.saveFailLog(accessToken, "开票失败,错误码非0000/9998/0003", new Date());
+
+            // 示例3:标记该单据为异常,方便后台运维查看
+            // abnormalOrderService.saveAbnormalOrder(accessToken, "开票失败");
+
+            // 示例4:调用其他系统接口,同步失败状态
+            // otherSystemApi.notifyInvoiceFail(accessToken);
+
+            System.err.println("============ 【失败兜底-系统信息修改逻辑】执行完成 ============");
+
+        } catch (Exception e) {
+            // 必加:捕获这个方法的异常,避免兜底方法报错导致线程异常
+            e.printStackTrace();
+            System.err.println("❌ 执行失败兜底方法时抛出异常:" + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 快速开红票的调用方法
+     * @param map
+     * @param allEinvno
+     */
+    public void doFastRedInvoiceBusiness(Map<String,Object> map, String allEinvno) {
+        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(appId);
+            InvoiceTokenInfo.setAppKey(appKey);
+            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 map
+     * @param applyNo
+     * @param originalInvno
+     */
+    public 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(appId);
+            InvoiceTokenInfo.setAppKey(appKey);
+            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
+     */
+    public 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(供原有业务代码调用,参数完整)
+     */
+    public void saveRedInvoiceTaskToRedis(int remainRetryTimes, String jsonInvoicResultStr, String accessToken, String applyNo, long startTime) {
+        Jedis jedis = null;
+        try {
+            jedis = JedisUtils.getResource();
+            String redisKey = "OMS_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();
+        }
+    }
+
+
+}

+ 98 - 363
src/main/java/com/jeeplus/modules/workinvoice/service/OMS/RedInvoiceRetryScheduledService.java

@@ -1,24 +1,24 @@
 package com.jeeplus.modules.workinvoice.service.OMS;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.jeeplus.common.utils.JedisUtils;
+import com.jeeplus.modules.ruralprojectrecords.web.RuralProjectSignatureOldMessageDisposeController;
 import com.jeeplus.modules.workinvoice.entity.OMS.OMSAccessTokenInfo;
-import com.jeeplus.modules.workinvoice.entity.OMS.fastRed.OMSRedInvoiceConfirmResponse;
 import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
-import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import redis.clients.jedis.Jedis;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 
 /**
- * 红冲发票定时重试任务处理类(无时段/超时限制版)
+ * 用于开发票都用订单接口推送时使用,用来当返回值时9998时进行处理
  * 核心规则:
  * 1. 每2分钟执行一次定时任务(无时段限制)
  * 2. 单个任务最多重试20次(每次间隔2分钟,由定时任务频率控制)
@@ -30,379 +30,114 @@ import java.util.UUID;
 @Lazy(false) // 非懒加载,项目启动即初始化
 public class RedInvoiceRetryScheduledService {
 
-    // ========== 核心配置常量(仅保留重试次数限制) ==========
-    /** 最大重试次数:20次 */
-    private static final int MAX_RETRY_TIMES = 20;
-    /** Redis任务Key前缀 */
-    private static final String REDIS_TASK_PREFIX = "red_invoice_task:";
+    // 原业务类中的核心方法需要能被定时任务调用,建议将executeOrderUploadRetry、handleInvoiceRetryAllFail等方法改为public,
+    // 或通过@Autowired注入业务类实例(假设你的业务类叫InvoiceOMSService)
+    @Autowired
+    private OMSDisposeService invoiceOMSService; // 替换为你实际的业务类名
 
-    // ========== 定时任务入口(每2分钟执行一次,无时段限制) ==========
-    @Scheduled(cron = "0 */2 * * * ?") // cron表达式:每2分钟执行一次
-    public void processRedInvoiceRetryTask() {
+    /**
+     * 定时任务:每5分钟执行一次(硬编码300000毫秒=5分钟)
+     * fixedRate:固定间隔执行,直接写死5分钟
+     */
+    public void handleInvoice9998RetryTask() {
         Jedis jedis = null;
         try {
-            // 1. 获取Redis连接,扫描所有待处理任务
             jedis = JedisUtils.getResource();
-            Set<String> taskKeys = jedis.keys(REDIS_TASK_PREFIX + "*");
-            if (taskKeys.isEmpty()) {
-                System.out.println("[红冲发票定时任务] 暂无待处理的红冲发票任务");
+            // 1. 扫描所有9998重试任务的Redis Key
+            Set<String> redisKeys = jedis.keys("OMS_invoice_retry_scheduled:*");
+            if (redisKeys == null || redisKeys.isEmpty()) {
+                System.out.println("ℹ️ 暂无9998重试任务需要处理");
                 return;
             }
-            System.out.println("[红冲发票定时任务] 发现待处理任务数:" + taskKeys.size());
+            System.out.println("ℹ️ 发现" + redisKeys.size() + "个9998重试任务,开始处理");
 
-            // 2. 遍历处理每个任务(有值就执行,无则跳过)
-            for (String taskKey : taskKeys) {
-                String applyNo = taskKey.replace(REDIS_TASK_PREFIX, "");
-                handleSingleRedInvoiceTask(jedis, applyNo, taskKey);
-            }
-        } catch (Exception e) {
-            System.err.println("[红冲发票定时任务] 批量处理任务异常:" + e.getMessage());
-            e.printStackTrace();
-        } finally {
-            // 3. 释放Redis连接
-            if (jedis != null) {
+            // 2. 遍历每个任务Key,逐个处理
+            for (String redisKey : redisKeys) {
+                String orderNo = redisKey.split(":")[1];
                 try {
-                    jedis.close();
+                    // 3. 获取Redis中的任务数据
+                    Map<String, String> taskMap = jedis.hgetAll(redisKey);
+                    String jsonInvoiceStr = taskMap.get("jsonInvoiceStr");
+                    String accessToken = taskMap.get("accessToken");
+                    String getKey = taskMap.get("getKey");
+                    String initiationType = taskMap.get("initiationType");
+                    String retryTimesStr = taskMap.get("retryTimes");
+
+                    // 校验必要参数
+                    if (StringUtils.isBlank(jsonInvoiceStr) || StringUtils.isBlank(orderNo) || StringUtils.isBlank(retryTimesStr)) {
+                        System.err.println("❌ 订单" + orderNo + "任务数据不完整,删除无效任务");
+                        jedis.del(redisKey);
+                        continue;
+                    }
+
+                    // 4. 核心:重试次数扣减(先减1,再判断逻辑)
+                    int remainRetryTimes = Integer.parseInt(retryTimesStr);
+                    int newRemainTimes = remainRetryTimes - 1; // 每次处理减1
+
+                    // 5. 判断是否耗尽次数(第20次,newRemainTimes=0)
+                    if (newRemainTimes <= 0) {
+                        System.err.println("❌ 订单" + orderNo + "重试次数已耗尽(累计20次),执行兜底逻辑handleInvoiceRetryAllFail");
+                        invoiceOMSService.handleInvoiceRetryAllFail(accessToken);
+                        jedis.del(redisKey); // 删除Redis任务,不再重试
+                        continue;
+                    }
+
+                    // 6. 次数未耗尽:更新Redis中的重试次数,再调用接口重试
+                    jedis.hset(redisKey, "retryTimes", String.valueOf(newRemainTimes));
+                    System.out.println("ℹ️ 订单" + orderNo + "剩余重试次数更新为:" + newRemainTimes);
+
+                    // 7. 调用OMS订单上传接口重试
+                    String newResultStr = HttpPostJsonUtil.doPost(
+                            "https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/order/upload",
+                            jsonInvoiceStr
+                    );
+                    System.out.println("✅ 订单" + orderNo + "9998重试调用接口返回:" + newResultStr);
+
+                    // 8. 调用核心重试逻辑处理返回结果
+                    Map<String, Object> resultMap = new HashMap<>();
+                    invoiceOMSService.executeOrderUploadRetry(
+                            newRemainTimes, // 传入扣减后的剩余次数
+                            newResultStr,
+                            jsonInvoiceStr,
+                            accessToken,
+                            orderNo,
+                            resultMap,
+                            getKey,
+                            initiationType
+                    );
+
+                    // 9. 根据接口返回码处理Redis任务
+                    OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(newResultStr, OMSAccessTokenInfo.class);
+                    if (resultTokenInfo != null && resultTokenInfo.getResult() != null) {
+                        String code = resultTokenInfo.getResult().getCode();
+                        if ("0000".equals(code)) {
+                            // 0000成功:删除Redis任务,结束重试
+                            System.out.println("✅ 订单" + orderNo + "9998重试成功,删除Redis任务");
+                            jedis.del(redisKey);
+                        } else if (!"9998".equals(code)) {
+                            // 非9998错误码(如0001/0002等):执行兜底+删除任务
+                            System.err.println("❌ 订单" + orderNo + "9998重试返回错误码:" + code + ",执行兜底逻辑");
+                            invoiceOMSService.handleInvoiceRetryAllFail(accessToken);
+                            jedis.del(redisKey);
+                        }
+                        // 仍返回9998:不删除Redis任务(已更新次数,下次定时任务继续重试)
+                    } else {
+                        // 解析返回结果失败:执行兜底+删除任务
+                        System.err.println("❌ 订单" + orderNo + "9998重试返回结果解析失败,执行兜底逻辑");
+                        invoiceOMSService.handleInvoiceRetryAllFail(accessToken);
+                        jedis.del(redisKey);
+                    }
                 } catch (Exception e) {
-                    System.err.println("[红冲发票定时任务] 关闭Redis连接异常:" + e.getMessage());
-                }
-            }
-        }
-    }
-
-    // ========== 处理单个红冲发票任务(无超时限制) ==========
-    private void handleSingleRedInvoiceTask(Jedis jedis, String applyNo, String taskKey) {
-        try {
-            // 1. 读取Redis中任务参数
-            String remainRetryTimesStr = jedis.hget(taskKey, "remainRetryTimes");
-            String jsonInvoicResultStr = jedis.hget(taskKey, "jsonInvoicResultStr");
-            String accessToken = jedis.hget(taskKey, "accessToken");
-            String getKey = jedis.hget(taskKey, "getKey"); // 解析AccessToken的key
-
-            // 2. 重试次数初始化&校验(仅保留20次限制)
-            int remainRetryTimes = StringUtils.isBlank(remainRetryTimesStr) ? MAX_RETRY_TIMES : Integer.parseInt(remainRetryTimesStr);
-
-            // 2.1 重试次数用尽 → 触发失败逻辑+删除Redis
-            if (remainRetryTimes <= 0) {
-                System.err.println("[红冲发票任务] 任务[" + applyNo + "]重试次数用尽(20次),触发失败逻辑");
-                triggerTaskFailLogic(jedis, taskKey, accessToken, "重试次数用尽(20次)");
-                return;
-            }
-
-            // 3. 优先获取/刷新AccessToken(适配9998重试逻辑)
-            AccessTokenResult tokenResult = getOmsAccessTokenWithRetry(remainRetryTimes, getKey);
-            if (tokenResult.isSuccess()) {
-                // 3.1 AccessToken获取成功 → 更新Redis中的token
-                accessToken = tokenResult.getToken();
-                jedis.hset(taskKey, "accessToken", accessToken);
-            } else if (tokenResult.isNeedRetry()) {
-                // 3.2 AccessToken需要重试 → 更新重试次数,等待下次定时任务
-                updateTaskRetryTimes(jedis, taskKey, tokenResult.getRemainRetryTimes(), jsonInvoicResultStr, accessToken);
-                System.out.println("[红冲发票任务] 任务[" + applyNo + "]AccessToken需重试,剩余次数:" + tokenResult.getRemainRetryTimes());
-                return;
-            } else if (tokenResult.getRemainRetryTimes() <= 0) {
-                // 3.3 AccessToken重试次数用尽 → 触发失败逻辑
-                triggerTaskFailLogic(jedis, taskKey, accessToken, "AccessToken重试次数用尽");
-                return;
-            }
-
-            // 4. 执行核心业务逻辑(红冲发票查询)
-            boolean taskSuccess = executeRedInvoiceBusinessLogic(applyNo, accessToken, jsonInvoicResultStr);
-            if (taskSuccess) {
-                // 5. 任务成功 → 删除Redis任务
-                jedis.del(taskKey);
-                System.out.println("[红冲发票任务] 任务[" + applyNo + "]处理成功,已删除Redis任务");
-            } else {
-                // 6. 任务未成功 → 重试次数-1,更新Redis
-                int newRetryTimes = remainRetryTimes - 1;
-                updateTaskRetryTimes(jedis, taskKey, newRetryTimes, jsonInvoicResultStr, accessToken);
-                System.out.println("[红冲发票任务] 任务[" + applyNo + "]处理未成功,剩余重试次数:" + newRetryTimes);
-            }
-        } catch (Exception e) {
-            System.err.println("[红冲发票任务] 处理单个任务[" + applyNo + "]异常:" + e.getMessage());
-            e.printStackTrace();
-            // 异常时重试次数-1,更新Redis
-            try {
-                String remainRetryTimesStr = jedis.hget(taskKey, "remainRetryTimes");
-                int remainRetryTimes = StringUtils.isBlank(remainRetryTimesStr) ? MAX_RETRY_TIMES : Integer.parseInt(remainRetryTimesStr);
-                int newRetryTimes = remainRetryTimes - 1;
-                updateTaskRetryTimes(jedis, taskKey, newRetryTimes, jedis.hget(taskKey, "jsonInvoicResultStr"), jedis.hget(taskKey, "accessToken"));
-            } catch (Exception ex) {
-                System.err.println("[红冲发票任务] 更新重试次数异常:" + ex.getMessage());
-            }
-        }
-    }
-
-    // ========== 执行核心业务逻辑(红冲发票查询) ==========
-    private boolean executeRedInvoiceBusinessLogic(String applyNo, String accessToken, String jsonInvoicResultStr) {
-        try {
-            // 1. 首次执行:解析初始化结果(jsonInvoicResultStr非空)
-            if (StringUtils.isNotBlank(jsonInvoicResultStr)) {
-                OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(jsonInvoicResultStr, OMSAccessTokenInfo.class);
-                if (null == resultTokenInfo || null == resultTokenInfo.getResult() || !"0000".equals(resultTokenInfo.getResult().getCode())) {
-                    System.err.println("[红冲发票业务] 任务[" + applyNo + "]初始化结果解析失败");
-                    return false;
+                    e.printStackTrace();
+                    System.err.println("❌ 处理订单" + orderNo + "9998重试任务异常:" + e.getMessage());
+                    // 异常时不删除任务,下次继续重试(避免因临时异常丢失任务)
                 }
             }
-
-            // 2. 组装查询参数
-            OMSNationUtil util = new OMSNationUtil();
-            String queryData = util.neatenAllScenarioRedInvoiceConfirmQueryData(applyNo);
-            OMSAccessTokenInfo invoiceDownInfo = new OMSAccessTokenInfo();
-            invoiceDownInfo.setAppId("sscs");
-            invoiceDownInfo.setAppKey("sscs");
-            invoiceDownInfo.setExchangeId(UUID.randomUUID().toString());
-            invoiceDownInfo.setAccessToken(accessToken);
-            invoiceDownInfo.setData(queryData);
-            String jsonInvoiceDownStr = JSON.toJSONString(invoiceDownInfo);
-
-            // 3. 调用OMS红字确认单查询接口
-            String invoiceResultStr = HttpPostJsonUtil.doPost(
-                    "https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/redApply/query",
-                    jsonInvoiceDownStr
-            );
-            if (StringUtils.isBlank(invoiceResultStr)) {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]查询接口返回空");
-                return false;
-            }
-
-            // 4. 解析查询结果
-            OMSAccessTokenInfo resultDownInfo = JSON.parseObject(invoiceResultStr, OMSAccessTokenInfo.class);
-            if (null == resultDownInfo.getResult()) {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]查询结果无返回体");
-                return false;
-            }
-
-            String resultCode = resultDownInfo.getResult().getCode();
-            // 4.1 接口返回成功(0000)→ 解析发票状态
-            if ("0000".equals(resultCode)) {
-                String invoceDownJsonStr = OMSNationUtil.extractFromBase64OnClassStr(resultDownInfo.getData().toString());
-                OMSRedInvoiceConfirmResponse invoiceInfo = JSONObject.parseObject(invoceDownJsonStr, OMSRedInvoiceConfirmResponse.class);
-
-                // 打印调试信息
-                System.out.println("[红冲发票业务] 任务[" + applyNo + "]查询结果:");
-                System.out.println("  - 确认状态:" + invoiceInfo.getConfirmStatus());
-                System.out.println("  - 开票状态:" + invoiceInfo.getMakeStatus());
-                System.out.println("  - 失败原因:" + invoiceInfo.getFailCause());
-
-                // 5. 判断发票状态是否处理完成
-                return judgeInvoiceStatusCompleted(invoiceInfo, applyNo, accessToken);
-            }
-            // 4.2 接口返回9998(接口波动)→ 纳入重试
-            else if ("9998".equals(resultCode)) {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]查询接口返回9998(接口波动),需重试");
-                return false;
-            }
-            // 4.3 其他错误码 → 任务失败
-            else {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]查询接口返回错误码:" + resultCode);
-                return false;
-            }
         } catch (Exception e) {
-            System.err.println("[红冲发票业务] 任务[" + applyNo + "]执行异常:" + e.getMessage());
-            e.printStackTrace();
-            return false;
-        }
-    }
-
-    // ========== 判断发票状态是否处理完成 ==========
-    private boolean judgeInvoiceStatusCompleted(OMSRedInvoiceConfirmResponse invoiceInfo, String applyNo, String accessToken) {
-        String confirmStatus = invoiceInfo.getConfirmStatus();
-        String makeStatus = invoiceInfo.getMakeStatus();
-
-        // 1. 确认状态为无需确认/已确认(01/04)
-        if ("01".equals(confirmStatus) || "04".equals(confirmStatus)) {
-            // 1.1 开票状态为已开票(03)→ 任务完成
-            if ("3".equals(makeStatus)) {
-                String redInvOrderNo = invoiceInfo.getRedInvOrderNo();
-                // 存入下载任务Redis,由下载任务接管(保留你的原有逻辑)
-                saveInvoiceDownloadTaskToRedis(accessToken, redInvOrderNo);
-                System.out.println("[红冲发票业务] 任务[" + applyNo + "]开票完成,订单号:" + redInvOrderNo);
-                return true;
-            }
-            // 1.2 开票状态为开票中(01/04)→ 需重试
-            else if ("1".equals(makeStatus) || "4".equals(makeStatus)) {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]开票中,需继续重试");
-                return false;
-            }
-            // 1.3 其他开票状态 → 任务失败
-            else {
-                System.err.println("[红冲发票业务] 任务[" + applyNo + "]开票状态异常:" + makeStatus);
-                return false;
-            }
-        }
-        // 2. 确认状态为待确认/申请中(02/03/15)→ 需重试
-        else if ("02".equals(confirmStatus) || "03".equals(confirmStatus) || "15".equals(confirmStatus)) {
-            System.err.println("[红冲发票业务] 任务[" + applyNo + "]待确认/申请中,需继续重试");
-            return false;
-        }
-        // 3. 确认状态为作废/失败(05/06/07/08/09/10/16)→ 任务失败
-        else if ("05".equals(confirmStatus) || "06".equals(confirmStatus) || "07".equals(confirmStatus) ||
-                "08".equals(confirmStatus) || "09".equals(confirmStatus) || "10".equals(confirmStatus) || "16".equals(confirmStatus)) {
-            System.err.println("[红冲发票业务] 任务[" + applyNo + "]作废/申请失败,状态:" + confirmStatus);
-            return false;
-        }
-        // 4. 未知状态 → 任务失败
-        else {
-            System.err.println("[红冲发票业务] 任务[" + applyNo + "]未知确认状态:" + confirmStatus);
-            return false;
-        }
-    }
-
-    // ========== AccessToken获取(适配9998重试,20次限制) ==========
-    private AccessTokenResult getOmsAccessTokenWithRetry(int remainRetryTimes, String getKey) {
-        // 兼容getKey为空的场景
-        if (StringUtils.isBlank(getKey)) {
-            System.err.println("[AccessToken] getKey为空,无需重试");
-            return new AccessTokenResult(false, "", false, remainRetryTimes);
-        }
-
-        try {
-            // 1. 组装请求参数
-            OMSAccessTokenInfo tokenInfo = new OMSAccessTokenInfo();
-            tokenInfo.setAppId("sscs"); // 替换为你的实际appId
-            tokenInfo.setAppKey("sscs"); // 替换为你的实际appKey
-            tokenInfo.setExchangeId(UUID.randomUUID().toString());
-            String jsonStr = JSON.toJSONString(tokenInfo);
-
-            // 2. 调用AccessToken接口
-            String accessTokenStr = HttpPostJsonUtil.doPost(
-                    "https://oms-sandbox.einvoice.js.cn:7079/prod-api/server/accessToken",
-                    jsonStr
-            );
-
-            // 3. 空值校验
-            if (StringUtils.isBlank(accessTokenStr)) {
-                System.err.println("获取AccessToken失败:接口返回空,剩余重试次数:"+remainRetryTimes);
-                return new AccessTokenResult(false, "", false, remainRetryTimes);
-            }
-
-            // 4. 解析结果
-            OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(accessTokenStr, OMSAccessTokenInfo.class);
-            if (null == resultTokenInfo || null == resultTokenInfo.getResult()) {
-                System.err.println("获取AccessToken失败:返回结果解析异常,剩余重试次数:"+remainRetryTimes);
-                return new AccessTokenResult(false, "", false, remainRetryTimes);
-            }
-
-            String code = resultTokenInfo.getResult().getCode();
-            // 5. 0000成功:返回token
-            if ("0000".equals(code)) {
-                String token = OMSNationUtil.extractAccessTokenFromBase64(getKey, resultTokenInfo.getData().toString());
-                System.out.println("✅ 获取AccessToken成功,重试次数剩余:"+remainRetryTimes);
-                return new AccessTokenResult(true, token, false, remainRetryTimes);
-            }
-            // 6. 9998错误:判断是否需要重试
-            else if ("9998".equals(code)) {
-                if (remainRetryTimes > 1) {
-                    int nextRetry = remainRetryTimes - 1;
-                    System.err.println("⚠️ 获取AccessToken返回9998接口波动,剩余重试次数:"+nextRetry);
-                    return new AccessTokenResult(false, "", true, nextRetry);
-                } else {
-                    System.err.println("❌ 获取AccessToken失败:连续20次返回9998,重试次数耗尽!");
-                    return new AccessTokenResult(false, "", false, 0);
-                }
-            }
-            // 7. 其他错误码:返回失败
-            else {
-                System.err.println("❌ 获取AccessToken失败:返回业务错误码,code="+code);
-                return new AccessTokenResult(false, "", false, remainRetryTimes);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            System.err.println("❌ 获取AccessToken失败:调用接口异常,剩余重试次数:"+remainRetryTimes);
-            // 异常场景:判断是否还有重试次数
-            if (remainRetryTimes > 1) {
-                return new AccessTokenResult(false, "", true, remainRetryTimes - 1);
-            } else {
-                return new AccessTokenResult(false, "", false, 0);
-            }
-        }
-    }
-
-    // ========== 辅助方法(保留你的原有逻辑) ==========
-    /**
-     * 任务失败兜底逻辑
-     */
-    private void triggerTaskFailLogic(Jedis jedis, String taskKey, String accessToken, String failReason) {
-        try {
-            // 1. 执行失败兜底(可扩展:更新数据库/发送通知)
-            System.err.println("[红冲发票失败兜底] 任务失败原因:" + failReason + ",执行兜底逻辑");
-            handleInvoiceRetryAllFail(accessToken);
-
-            // 2. 删除Redis任务
-            jedis.del(taskKey);
-            System.out.println("[红冲发票失败兜底] 已删除Redis任务:" + taskKey);
-        } catch (Exception e) {
-            System.err.println("[红冲发票失败兜底] 执行异常:" + e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * 更新Redis任务重试次数(移除startTime,无超时限制)
-     */
-    private void updateTaskRetryTimes(Jedis jedis, String taskKey, int newRetryTimes, String jsonInvoicResultStr, String accessToken) {
-        try {
-            jedis.hset(taskKey, "remainRetryTimes", String.valueOf(newRetryTimes));
-            jedis.hset(taskKey, "jsonInvoicResultStr", StringUtils.defaultString(jsonInvoicResultStr));
-            jedis.hset(taskKey, "accessToken", StringUtils.defaultString(accessToken));
-            // 仅保留Redis过期时间(避免任务永久残留)
-            jedis.expire(taskKey, 86400 * 7); // 7天过期(可自定义)
-        } catch (Exception e) {
-            System.err.println("[红冲发票任务] 更新Redis重试次数异常:" + e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * 兜底逻辑(可扩展)
-     */
-    public void handleInvoiceRetryAllFail(String accessToken) {
-        // 此处实现失败后的具体逻辑:更新数据库/发送通知等
-        System.err.println("[兜底逻辑] 执行失败处理:accessToken=" + 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天过期
-            System.out.println("[下载任务] 已存入Redis:" + redisKey);
-        } catch (Exception e) {
-            System.err.println("[下载任务] 存入Redis异常:" + e.getMessage());
             e.printStackTrace();
+            System.err.println("❌ 9998重试定时任务执行异常:" + e.getMessage());
         } finally {
             if (jedis != null) jedis.close();
         }
     }
-
-    /**
-     * AccessToken获取结果封装类
-     */
-    private static class AccessTokenResult {
-        private boolean success; // 是否获取成功
-        private String token;    // 成功时返回token
-        private boolean needRetry; // 是否需要重试
-        private int remainRetryTimes; // 剩余重试次数
-
-        public AccessTokenResult(boolean success, String token, boolean needRetry, int remainRetryTimes) {
-            this.success = success;
-            this.token = token;
-            this.needRetry = needRetry;
-            this.remainRetryTimes = remainRetryTimes;
-        }
-
-        // getter
-        public boolean isSuccess() { return success; }
-        public String getToken() { return token; }
-        public boolean isNeedRetry() { return needRetry; }
-        public int getRemainRetryTimes() { return remainRetryTimes; }
-    }
 }

+ 19 - 24
src/main/java/com/jeeplus/modules/workinvoice/service/OMS/RedInvoiceScheduledService.java

@@ -8,6 +8,7 @@ import com.jeeplus.modules.workinvoice.entity.OMS.fastRed.OMSRedInvoiceConfirmRe
 import com.jeeplus.modules.workinvoice.utils.HttpPostJsonUtil;
 import com.jeeplus.modules.workinvoice.utils.OMSNationUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -22,6 +23,12 @@ import java.util.UUID;
 @Lazy
 public class RedInvoiceScheduledService {
 
+    private final String appId = "hyc1";
+    private final String appKey = "hyc1";
+
+    @Autowired
+    private OMSDisposeService omsDisposeService;
+
     public void processAllRedInvoiceTasks() {
         // 时间窗口校验
         Calendar now = Calendar.getInstance();
@@ -34,7 +41,7 @@ public class RedInvoiceScheduledService {
         Jedis jedis = null;
         try {
             jedis = JedisUtils.getResource();
-            Set<String> taskKeys = jedis.keys("red_invoice_task:*");
+            Set<String> taskKeys = jedis.keys("OMS_red_invoice_task:*");
             if (taskKeys.isEmpty()) {
                 System.out.println("[定时任务] 暂无待处理任务");
                 return;
@@ -42,7 +49,7 @@ public class RedInvoiceScheduledService {
 
             // 遍历处理所有Redis任务
             for (String taskKey : taskKeys) {
-                String applyNo = taskKey.replace("red_invoice_task:", "");
+                String applyNo = taskKey.replace("OMS_red_invoice_task:", "");
                 // 读取Redis参数
                 String remainRetryTimesStr = jedis.hget(taskKey, "remainRetryTimes");
                 String jsonInvoicResultStr = jedis.hget(taskKey, "jsonInvoicResultStr");
@@ -77,7 +84,7 @@ public class RedInvoiceScheduledService {
             // 步骤1:3天超时判断
             if (System.currentTimeMillis() - startTime > 259200000L) {
                 System.err.println("❌ 任务["+applyNo+"]超时,触发兜底逻辑");
-                handleInvoiceRetryAllFail(accessToken);
+                omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                 deleteRedInvoiceTaskFromRedis(applyNo);
                 return;
             }
@@ -87,7 +94,7 @@ public class RedInvoiceScheduledService {
                 OMSAccessTokenInfo resultTokenInfo = JSON.parseObject(jsonInvoicResultStr, OMSAccessTokenInfo.class);
                 if (null == resultTokenInfo || null == resultTokenInfo.getResult() || !"0000".equals(resultTokenInfo.getResult().getCode())) {
                     System.err.println("❌ 任务["+applyNo+"]解析失败,触发兜底");
-                    handleInvoiceRetryAllFail(accessToken);
+                    omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                     deleteRedInvoiceTaskFromRedis(applyNo);
                     return;
                 }
@@ -105,7 +112,7 @@ public class RedInvoiceScheduledService {
             if (remainRetryTimes > 1) {
                 saveRedInvoiceTaskToRedis(remainRetryTimes - 1, jsonInvoicResultStr, accessToken, applyNo, startTime);
             } else {
-                handleInvoiceRetryAllFail(accessToken);
+                omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                 deleteRedInvoiceTaskFromRedis(applyNo);
             }
         }
@@ -120,8 +127,8 @@ public class RedInvoiceScheduledService {
             OMSNationUtil util = new OMSNationUtil();
             String queryData = util.neatenAllScenarioRedInvoiceConfirmQueryData(applyNo);
             OMSAccessTokenInfo invoiceDownInfo = new OMSAccessTokenInfo();
-            invoiceDownInfo.setAppId("sscs");
-            invoiceDownInfo.setAppKey("sscs");
+            invoiceDownInfo.setAppId(appId);
+            invoiceDownInfo.setAppKey(appKey);
             invoiceDownInfo.setExchangeId(UUID.randomUUID().toString());
             invoiceDownInfo.setAccessToken(accessToken);
             invoiceDownInfo.setData(queryData);
@@ -188,7 +195,7 @@ public class RedInvoiceScheduledService {
                         // 开票中,重新存入Redis等待下次重试
                         saveRedInvoiceTaskToRedis(remainRetryTimes, "", accessToken, applyNo, startTime);
                     } else {
-                        handleInvoiceRetryAllFail(accessToken);
+                        omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                         deleteRedInvoiceTaskFromRedis(applyNo);
                     }
                     break;
@@ -207,15 +214,11 @@ public class RedInvoiceScheduledService {
                 case "10":
                 case "16":
                     // 终止本次红冲操作,通知发起人确认后重新处理
-                    handleInvoiceRetryAllFail(accessToken);
+                    omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                     // 失败后删除Redis任务
                     deleteRedInvoiceTaskFromRedis(applyNo);
                     break;
                 default:
-                    //终止本次红冲操作,通知发起人确认后重新处理
-                    // 失败状态,兜底+删除Redis
-                    handleInvoiceRetryAllFail(accessToken);
-                    deleteRedInvoiceTaskFromRedis(applyNo);
                     break;
             }
         } catch (Exception e) {
@@ -224,28 +227,20 @@ public class RedInvoiceScheduledService {
             if (remainRetryTimes > 1) {
                 saveRedInvoiceTaskToRedis(remainRetryTimes - 1, "", accessToken, applyNo, startTime);
             } else {
-                handleInvoiceRetryAllFail(accessToken);
+                omsDisposeService.handleInvoiceRetryAllFail(accessToken);
                 deleteRedInvoiceTaskFromRedis(applyNo);
             }
         }
     }
 
     /**
-     * 兜底逻辑
-     */
-    public void handleInvoiceRetryAllFail(String accessToken) {
-        System.err.println("📢 执行失败兜底逻辑:更新系统状态 + 通知发起人");
-        // 此处替换为你的实际兜底逻辑(如更新数据库、发送通知等)
-    }
-
-    /**
      * 存入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;
+            String redisKey = "OMS_red_invoice_task:" + applyNo;
             jedis.hset(redisKey, "remainRetryTimes", String.valueOf(remainRetryTimes));
             jedis.hset(redisKey, "jsonInvoicResultStr", jsonInvoicResultStr);
             jedis.hset(redisKey, "accessToken", accessToken);
@@ -266,7 +261,7 @@ public class RedInvoiceScheduledService {
         Jedis jedis = null;
         try {
             jedis = JedisUtils.getResource();
-            jedis.del("red_invoice_task:" + applyNo);
+            jedis.del("OMS_red_invoice_task:" + applyNo);
         } catch (Exception e) {
             e.printStackTrace();
         } finally {

+ 35 - 67
src/main/java/com/jeeplus/modules/workinvoice/utils/OMSNationUtil.java

@@ -19,15 +19,6 @@ import java.util.List;
 
 public class OMSNationUtil {
 
-    public static void main(String[] args) {
-        OMSNationUtil util = new OMSNationUtil();
-        String string = util.neatenData("");
-        String accessToken = extractAccessTokenFromBase64("accessToken", string);
-        String string1 = HttpPostJsonUtil.doPost("https://oms-sandbox.einvoice.js.cn:7079/prod-api/output/server/order/upload", accessToken);
-        System.out.println("✅ 提取到的accessToken:" + accessToken);
-        System.out.println("✅ 提取到的string1:" + string1);
-    }
-
     /**
      * 从Base64编码的JSON响应中提取accessToken
      */
@@ -58,27 +49,6 @@ public class OMSNationUtil {
         return jsonObject.toJSONString();
     }
 
-    public static InvoiceOMSImportInfo getInvoiceInfo(String base64Str) {
-        // 1. 调用你的解码方法,获取JSON字符串
-        String jsonResult = getDownFromBase64(base64Str);
-
-        // 2. 非空校验
-        if (StringUtils.isBlank(jsonResult)) {
-            System.err.println("解码后返回的JSON字符串为空,无法转换实体类");
-            return null;
-        }
-
-        // 3. 转换实体类+异常捕获
-        InvoiceOMSImportInfo invoiceInfo = null;
-        try {
-            invoiceInfo = JSONObject.parseObject(jsonResult, InvoiceOMSImportInfo.class);
-        } catch (Exception e) {
-            System.err.println("JSON字符串转InvoiceOMSImportInfo实体类失败:" + e.getMessage());
-            e.printStackTrace();
-        }
-        return invoiceInfo;
-    }
-
     // ========== 你的原方法(无需修改,保持不变) ==========
     public static String getDownFromBase64(String base64Str) {
         if (StringUtils.isBlank(base64Str)) {
@@ -113,20 +83,12 @@ public class OMSNationUtil {
         }
     }
 
-    /**
-     * Base64加密(编码)方法 - 配套上面的解码方法
-     * 入参:原始JSON字符串
-     * 出参:Base64编码后的字符串 (UTF-8编码,防中文乱码,和解码逻辑完全匹配)
-     */
-    public static String encryptJsonToBase64(String jsonStr) {
-        if (jsonStr == null || com.jeeplus.common.utils.StringUtils.isBlank(jsonStr)) {
-            return "";
-        }
-        // 1. JSON字符串转字节数组(必须指定UTF-8,你的JSON有中文,防止乱码)
-        byte[] jsonBytes = jsonStr.getBytes(StandardCharsets.UTF_8);
-        // 2. 进行Base64编码(加密)
-        return Base64.getEncoder().encodeToString(jsonBytes);
-    }
+
+    private final String deptCode = "500102204228315131";
+    private final String sellerTaxno = "500102204228315131";
+    private final String goodstaxno = "109050901"; //税收分类编码(电脑)
+    //private final String goodstaxno = "3070401"; //税收分类编码(餐饮)
+    private final String goodsName = "电脑配件"; //税收分类编码(餐饮)
 
 
     /**
@@ -137,16 +99,17 @@ public class OMSNationUtil {
         List<OrderItem> orderItems = Lists.newArrayList();
 
         InvoiceOMSImportInfo omsImportInfo = new InvoiceOMSImportInfo();
-        omsImportInfo.setDeptCode("7777");
+        omsImportInfo.setDeptCode(deptCode);
         omsImportInfo.setOrderno(orderno);
         omsImportInfo.setSellerName("深圳市松胜电子有限公司");
-        omsImportInfo.setSellerTaxno("500102204228315131");
+        omsImportInfo.setSellerTaxno(sellerTaxno); //销方纳税人识别号,必填
         omsImportInfo.setInvKind("02");
         omsImportInfo.setInvType("01");
 
         //添加购买方信息
-        omsImportInfo.setBuyerName("江苏兴光项目管理有限公司");
-        omsImportInfo.setBuyerTaxno("91320000746823994F");
+        omsImportInfo.setBuyerName("深圳市爱人人餐饮服务有限公司");
+        omsImportInfo.setBuyerTaxno("500102203117204029");
+        //omsImportInfo.setRemarks("zzsytdm01,xfsytdm01");
 
 
         OrderItem orderItem = new OrderItem();
@@ -154,15 +117,16 @@ public class OMSNationUtil {
         orderItem.setLineType("00");
         //添加商品名称
         //orderItem.setGoodsCode("1001");
-        orderItem.setGoodsName("电脑配件");
+        orderItem.setGoodsName(goodsName);
         orderItem.setQty(BigDecimal.valueOf(1));
-        orderItem.setPrice(BigDecimal.valueOf(100.00));
-        orderItem.setPriceTaxFlag("0"); //含税状态
+        //orderItem.setPrice(BigDecimal.valueOf(100.00));
+        orderItem.setPriceTaxFlag("1"); //含税状态 0不含税;1含税
         orderItem.setTaxrate(BigDecimal.valueOf(0.01)); //税率
-        orderItem.setAmount(BigDecimal.valueOf(100.00)); //金额
-        orderItem.setTax(BigDecimal.valueOf(1.00));//税额
+        //orderItem.setAmount(BigDecimal.valueOf(100.00)); //金额
+        //orderItem.setTax(BigDecimal.valueOf(1.00));//税额
         orderItem.setTaxamount(BigDecimal.valueOf(101.00));//含税金额
-        orderItem.setGoodstaxno("109050901");//税收分类编码
+        //orderItem.setGoodstaxno("109050901");//税收分类编码(电脑)
+        orderItem.setGoodstaxno(goodstaxno);//税收分类编码(餐饮)
 
         orderItems.add(orderItem);
 
@@ -179,7 +143,7 @@ public class OMSNationUtil {
         orderItem2.setAmount(BigDecimal.valueOf(50.00)); //金额
         orderItem2.setTax(BigDecimal.valueOf(0.5));//税额
         orderItem2.setTaxamount(BigDecimal.valueOf(50.5));//含税金额
-        orderItem2.setGoodstaxno("109050901");//税收分类编码
+        orderItem2.setGoodstaxno(goodstaxno);//税收分类编码
 
 
         orderItems.add(orderItem2);*/
@@ -202,7 +166,7 @@ public class OMSNationUtil {
     public String neatenFastRedInvoiceData(String allEinvno) {
 
         OMSFastRedInvoiceInfo omsImportInfo = new OMSFastRedInvoiceInfo();
-        omsImportInfo.setDeptCode("7777");
+        omsImportInfo.setDeptCode(deptCode);
         omsImportInfo.setAllEinvno(allEinvno);
         omsImportInfo.setRedReason("02");
 
@@ -224,13 +188,14 @@ public class OMSNationUtil {
         List<OMSApplyItem> orderItems = Lists.newArrayList();
 
         OMSAllScenarioRedInvoiceInfo omsAllScenarioRedInvoiceInfo = new OMSAllScenarioRedInvoiceInfo();
-        omsAllScenarioRedInvoiceInfo.setDeptCode("7777");
-        omsAllScenarioRedInvoiceInfo.setApplyNo(applyNo);
+        omsAllScenarioRedInvoiceInfo.setDeptCode(deptCode);
+        omsAllScenarioRedInvoiceInfo.setApplyNo(applyNo);   //红字发票申请单号
         omsAllScenarioRedInvoiceInfo.setApplyIdentity("0");
-        omsAllScenarioRedInvoiceInfo.setSellerTaxno("500102204228315131");
+        omsAllScenarioRedInvoiceInfo.setSellerTaxno(sellerTaxno);
         omsAllScenarioRedInvoiceInfo.setSellerName("深圳市松胜电子有限公司");
         //添加购买方信息
-        omsAllScenarioRedInvoiceInfo.setBuyerName("江苏兴光项目管理有限公司");
+        omsAllScenarioRedInvoiceInfo.setBuyerName("深圳市爱人人餐饮服务有限公司");
+        omsAllScenarioRedInvoiceInfo.setBuyerTaxno("500102203117204029");
         //原蓝票发票号码
         omsAllScenarioRedInvoiceInfo.setOriginalInvno(originalInvno);
         //原蓝票发票类型
@@ -242,11 +207,14 @@ public class OMSNationUtil {
         //合计金额(不含税)
         omsAllScenarioRedInvoiceInfo.setTotalAmount("-100");
         //合计税额
-        omsAllScenarioRedInvoiceInfo.setTotalTax("-1");
+        omsAllScenarioRedInvoiceInfo.setTotalTax("-1.00");
         //价税合计
-        omsAllScenarioRedInvoiceInfo.setTotalTaxamount("-101");
-        //redReason
-        omsAllScenarioRedInvoiceInfo.setRedReason("04");
+        omsAllScenarioRedInvoiceInfo.setTotalTaxamount("-101.00");
+
+        //* 冲红原因(必填)
+        //* 01:开票有误 02:销货退回 03:服务中止 04:销售折让
+
+        omsAllScenarioRedInvoiceInfo.setRedReason("01");
         //是否自动开票
         omsAllScenarioRedInvoiceInfo.setAutoMakeInv("Y");
 
@@ -254,7 +222,7 @@ public class OMSNationUtil {
         OMSApplyItem orderItem = new OMSApplyItem();
         orderItem.setLineCode("1");
         //添加商品名称
-        orderItem.setGoodsName("电脑配件");
+        orderItem.setGoodsName(goodsName);
 
         //orderItem.setQty(BigDecimal.valueOf(1));
         //orderItem.setPrice(BigDecimal.valueOf(100.00));
@@ -263,7 +231,7 @@ public class OMSNationUtil {
         orderItem.setTax(BigDecimal.valueOf(-1.00));//税额
         orderItem.setTaxrate(BigDecimal.valueOf(0.01)); //税率
         orderItem.setTaxamount(BigDecimal.valueOf(-101.00));//含税金额
-        orderItem.setGoodstaxno("109050901");//税收分类编码
+        orderItem.setGoodstaxno(goodstaxno);//税收分类编码
         orderItem.setOriLineCode("1");//对应蓝票明细序号
 
         orderItems.add(orderItem);
@@ -287,7 +255,7 @@ public class OMSNationUtil {
     public String neatenAllScenarioRedInvoiceConfirmQueryData(String applyNo) {
 
         OMSRedInvoiceConfirmQueryRequest omsImportInfo = new OMSRedInvoiceConfirmQueryRequest();
-        omsImportInfo.setDeptCode("7777");
+        omsImportInfo.setDeptCode(deptCode);
         omsImportInfo.setApplyNo(applyNo);
         omsImportInfo.setApplyIdentity("0");
 

+ 8 - 6
src/main/java/com/jeeplus/modules/workinvoice/utils/RedInvoiceScheduledTask.java

@@ -18,6 +18,8 @@ import java.util.UUID;
 @Component
 public class RedInvoiceScheduledTask {
 
+    private final String appId = "hyc1";
+    private final String appKey = "hyc1";
 
 
     // ========== 2. 定时任务入口(8:00-18:00每小时执行) ==========
@@ -34,7 +36,7 @@ public class RedInvoiceScheduledTask {
         Jedis jedis = null;
         try {
             jedis = JedisUtils.getResource();
-            Set<String> taskKeys = jedis.keys("red_invoice_task:*");
+            Set<String> taskKeys = jedis.keys("OMS_red_invoice_task:*");
             if (taskKeys.isEmpty()) {
                 System.out.println("[定时任务] 暂无待处理任务");
                 return;
@@ -42,7 +44,7 @@ public class RedInvoiceScheduledTask {
 
             // 遍历处理所有Redis任务
             for (String taskKey : taskKeys) {
-                String applyNo = taskKey.replace("red_invoice_task:", "");
+                String applyNo = taskKey.replace("OMS_red_invoice_task:", "");
                 // 读取Redis参数
                 String remainRetryTimesStr = jedis.hget(taskKey, "remainRetryTimes");
                 String jsonInvoicResultStr = jedis.hget(taskKey, "jsonInvoicResultStr");
@@ -120,8 +122,8 @@ public class RedInvoiceScheduledTask {
             OMSNationUtil util = new OMSNationUtil();
             String queryData = util.neatenAllScenarioRedInvoiceConfirmQueryData(applyNo);
             OMSAccessTokenInfo invoiceDownInfo = new OMSAccessTokenInfo();
-            invoiceDownInfo.setAppId("sscs");
-            invoiceDownInfo.setAppKey("sscs");
+            invoiceDownInfo.setAppId(appId);
+            invoiceDownInfo.setAppKey(appKey);
             invoiceDownInfo.setExchangeId(UUID.randomUUID().toString());
             invoiceDownInfo.setAccessToken(accessToken);
             invoiceDownInfo.setData(queryData);
@@ -207,7 +209,7 @@ public class RedInvoiceScheduledTask {
         Jedis jedis = null;
         try {
             jedis = JedisUtils.getResource();
-            String redisKey = "red_invoice_task:" + applyNo;
+            String redisKey = "OMS_red_invoice_task:" + applyNo;
             jedis.hset(redisKey, "remainRetryTimes", String.valueOf(remainRetryTimes));
             jedis.hset(redisKey, "jsonInvoicResultStr", jsonInvoicResultStr);
             jedis.hset(redisKey, "accessToken", accessToken);
@@ -228,7 +230,7 @@ public class RedInvoiceScheduledTask {
         Jedis jedis = null;
         try {
             jedis = JedisUtils.getResource();
-            jedis.del("red_invoice_task:" + applyNo);
+            jedis.del("OMS_red_invoice_task:" + applyNo);
         } catch (Exception e) {
             e.printStackTrace();
         } finally {

+ 2 - 2
src/main/webapp/webpage/modules/ruralprojectrecords/cost/ruralCostProjectMessageList.jsp

@@ -1553,11 +1553,11 @@
 						}
 						if(paperNoArchivedDays != null && paperNoArchivedDays != undefined && '' != paperNoArchivedDays){
 							if (d.submitMoney=="1"){
-								if(5 != d.downProjectReportRecordStatus){
+								if(5 != d.downProjectReportRecordStatus && "10" != d.downProjectReportRecordStatus){
 									xml+="<span style='margin-left: 5px;' title='超期天数'>" + paperNoArchivedDays + "天" + "</span>";
 								}
 							}else if (d.submitMoney=="2"){
-								if(5 != d.paperFilingStatus){
+								if(5 != d.paperFilingStatus && "10" != d.paperFilingStatus){
 									xml+="<span style='margin-left: 5px;' title='超期天数'>" + paperNoArchivedDays + "天" + "</span>";
 								}
 							}