فهرست منبع

加入发送验证码重试机制

skyfffire 4 هفته پیش
والد
کامیت
6b774099f8
2فایلهای تغییر یافته به همراه58 افزوده شده و 5 حذف شده
  1. 55 2
      src/main/java/modules/user/UserController.java
  2. 3 3
      src/main/java/modules/user/UserTeamShareTask.java

+ 55 - 2
src/main/java/modules/user/UserController.java

@@ -36,6 +36,10 @@ public class UserController extends MyController {
     public static final int ROLE_SUPER_ADMIN = 0;                               // 超级管理员
     public static final int ROLE_CHECK_ADMIN = 1;                               // 审核管理员
     public static final int ROLE_USER = 2;                                      // 普通用户
+
+    // 常量定义,避免魔法数字
+    private static final int MAX_RETRY_TIMES = 5;
+    private static final long RETRY_INTERVAL_MS = 100; // 重试间隔,可以根据需要调整
     
     @Inject
     private UserService service;
@@ -78,8 +82,10 @@ public class UserController extends MyController {
         
         // 4. 实际发送验证码
         try {
-            BatchSendResponse response = SMS.sendVerifyCodeByMobileNumber(mobileNumber, verifyCode);
-            String jsonResponse = JSONObject.toJSONString(response);
+            // 调用带有重试机制的发送方法
+            BatchSendResponse response = sendVerifyCodeWithRetry(mobileNumber, verifyCode, 1); // 初始重试次数为1
+            String jsonResponse = JSONObject.toJSONString(response); // 或者使用 JsonKit.toJson(response);
+
             boolean isSentSuccessfully = response.getResult().getStatus();
 
             if (isSentSuccessfully) {
@@ -91,9 +97,12 @@ public class UserController extends MyController {
                 renderJson(MyRet.ok("验证码已发送,请注意查收。").setData(jsonResponse));
             } else {
                 // 短信服务商返回发送失败的情况处理
+                AppConfig.LOGGER.error("发送验证码到 {} 失败,服务商返回失败状态。Response: {}", mobileNumber, jsonResponse);
                 renderJson(MyRet.fail("验证码发送失败,请稍后再试").setData(jsonResponse));
             }
         } catch (Exception e) {
+            // 达到最大重试次数后仍然失败
+            AppConfig.LOGGER.error("发送验证码到 {} 最终失败,已重试 {} 次。异常信息: {}", mobileNumber, MAX_RETRY_TIMES, e.getMessage(), e);
             renderJson(MyRet.fail("验证码发送失败,请重试: " + e.getMessage()));
         }
     }
@@ -631,6 +640,50 @@ public class UserController extends MyController {
     }
     * 
     * */
+
+    /**
+     * 私有辅助方法:发送验证码并进行重试
+     *
+     * @param mobileNumber 手机号码
+     * @param verifyCode 验证码
+     * @param retryCount 当前重试次数 (1到MAX_RETRY_TIMES)
+     * @return BatchSendResponse 短信发送结果
+     * @throws Exception 如果达到最大重试次数后仍然失败
+     */
+    private BatchSendResponse sendVerifyCodeWithRetry(String mobileNumber, String verifyCode, int retryCount) throws Exception {
+        try {
+            AppConfig.LOGGER.info("尝试发送验证码到 {} (第 {} 次尝试)", mobileNumber, retryCount);
+            BatchSendResponse response = SMS.sendVerifyCodeByMobileNumber(mobileNumber, verifyCode);
+
+            // 检查短信服务商返回的状态,如果认为虽然没抛异常但实际失败了,也可以在这里触发重试
+            // 例如:response.errorCode != 0
+            if (!response.getResult().getStatus()) {
+                // 如果服务商明确返回失败(比如手机号不合法等业务错误,并不是网络异常)
+                // 此时不应该重试,直接抛出异常,让上层处理
+                AppConfig.LOGGER.warn("短信服务商返回失败状态,不进行重试。Mobile: {}, Code: {}, Response: {}", mobileNumber, verifyCode, JSONObject.toJSONString(response));
+                throw new RuntimeException("短信服务商返回失败码,请检查手机号或稍后再试。");
+            }
+            return response; // 成功发送,直接返回
+        } catch (Exception e) {
+            AppConfig.LOGGER.warn("发送验证码到 {} 失败 (第 {} 次尝试),准备重试。异常信息: {}", mobileNumber, retryCount, e.getMessage());
+
+            if (retryCount < MAX_RETRY_TIMES) {
+                // 短暂等待再重试,避免立即再次请求导致服务崩溃
+                try {
+                    Thread.sleep(RETRY_INTERVAL_MS * retryCount); // 逐渐增加重试间隔
+                } catch (InterruptedException ie) {
+                    Thread.currentThread().interrupt(); // 恢复中断状态
+                    AppConfig.LOGGER.error("重试等待被中断,立即进行下次重试或抛出异常。");
+                    // 这里可以选择不立即重试,直接抛出异常,或继续进行下次重试
+                }
+                return sendVerifyCodeWithRetry(mobileNumber, verifyCode, retryCount + 1); // 递归重试
+            } else {
+                AppConfig.LOGGER.error("发送验证码到 {} 失败,已达最大重试次数 {}。", mobileNumber, MAX_RETRY_TIMES, e);
+                throw e; // 抛出异常,让调用者捕获并处理
+            }
+        }
+    }
+    
     //    @EmptyInterface(keyArray = {"mobile_number", "new_pwd_md5", "verify_code"})
     //    public void updatePwd() {
     //        // --- 核心修改部分:从 JSON 请求体中获取参数 ---

+ 3 - 3
src/main/java/modules/user/UserTeamShareTask.java

@@ -140,8 +140,8 @@ public class UserTeamShareTask implements Runnable {
 
     /**
      * 第三类、NFT持有者分润
-     *      1. 10%的部分
-     *      2. 4%的部分
+     *      1. 10%的部分,分母是20000
+     *      2. 4%的部分,分母是当前持有者数量
      */
     public void class3() {
         String queryUserIdSql = "SELECT user_id, COUNT(id) AS valid_order_count " +
@@ -282,7 +282,7 @@ public class UserTeamShareTask implements Runnable {
     }
 
     /**
-     * 第四类、持有者激励分润,这个最复杂最后做,可能需要为user加一个时间戳字段
+     * 第四类、持有者激励分润,这个是甲方手动分润
      */
 //    public void class4() {}