|
|
@@ -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 请求体中获取参数 ---
|