liujie
2026-08-26 d7fd9123c3e100e5fc8079fea8d9cacf8afd4a32
cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java
@@ -54,6 +54,7 @@
import com.dsh.account.vo.entity.YearData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
@@ -84,6 +85,10 @@
@Service
public class TAppUserServiceImpl extends ServiceImpl<TAppUserMapper, TAppUser> implements TAppUserService {
    private static final String SMS_COOLDOWN_KEY_PREFIX = "security:sms:cooldown:";
    private static final String SMS_PHONE_QUOTA_KEY_PREFIX = "security:sms:phone-quota:";
    private static final String SMS_IP_QUOTA_KEY_PREFIX = "security:sms:ip-quota:";
    @Resource
    private TStudentMapper tsmapper;
@@ -96,6 +101,15 @@
    @Autowired
    private RedisUtil redisUtil;
    @Value("${security.sms.cooldown-seconds:60}")
    private int smsCooldownSeconds;
    @Value("${security.sms.phone-max-per-day:5}")
    private int smsPhoneMaxPerDay;
    @Value("${security.sms.ip-max-per-day:10}")
    private int smsIpMaxPerDay;
    @Autowired
    private GDMapGeocodingUtil gdMapGeocodingUtil;
@@ -415,13 +429,31 @@
     * @throws Exception
     */
    @Override
    public ResultUtil getSMSCode(Integer type, String phone) throws Exception {
    public ResultUtil getSMSCode(Integer type, String phone, String clientIp) throws Exception {
        if (type == 2) {
            TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", phone).ne("state", 3));
            if (null != tAppUser) {
                return ResultUtil.error("账号已存在");
            }
        }
        String cooldownKey = SMS_COOLDOWN_KEY_PREFIX + phone;
        if (!redisUtil.setIfAbsent(cooldownKey, "1", smsCooldownSeconds)) {
            return ResultUtil.error("短信发送过于频繁,请稍后重试");
        }
        String phoneQuotaKey = SMS_PHONE_QUOTA_KEY_PREFIX + phone;
        if (!redisUtil.tryAcquireFixedWindow(phoneQuotaKey, smsPhoneMaxPerDay, 24 * 60 * 60)) {
            redisUtil.remove(cooldownKey);
            return ResultUtil.error("该手机号24小时内短信发送次数已达上限");
        }
        String ipQuotaKey = SMS_IP_QUOTA_KEY_PREFIX + clientIp;
        if (!redisUtil.tryAcquireFixedWindow(ipQuotaKey, smsIpMaxPerDay, 24 * 60 * 60)) {
            redisUtil.remove(cooldownKey);
            redisUtil.releaseFixedWindow(phoneQuotaKey);
            return ResultUtil.error("当前网络24小时内短信发送次数已达上限");
        }
        String numberRandom = UUIDUtil.getNumberRandom(6);
        String templateCode = "";
        if (type == 1 || type == 2) {
@@ -430,9 +462,29 @@
        if (type == 3 || type == 4) {
            templateCode = "SMS_160960014";
        }
        aLiSendSms.sendSms(phone, templateCode, "{\"code\":\"" + numberRandom + "\"}");
        boolean providerAccepted = false;
        try {
            String sendResult = aLiSendSms.sendSms(phone, templateCode, "{\"code\":\"" + numberRandom + "\"}");
            com.alibaba.fastjson.JSONObject response = com.alibaba.fastjson.JSONObject.parseObject(sendResult);
            if (response == null || !"OK".equalsIgnoreCase(response.getString("Code"))) {
                releaseSmsLimit(cooldownKey, phoneQuotaKey, ipQuotaKey);
                return ResultUtil.error("短信发送失败,请稍后重试");
            }
            providerAccepted = true;
        redisUtil.setStrValue(phone, numberRandom, 300);
        return ResultUtil.success();
        } catch (Exception e) {
            if (!providerAccepted) {
                releaseSmsLimit(cooldownKey, phoneQuotaKey, ipQuotaKey);
            }
            throw e;
        }
    }
    private void releaseSmsLimit(String cooldownKey, String phoneQuotaKey, String ipQuotaKey) {
        redisUtil.remove(cooldownKey);
        redisUtil.releaseFixedWindow(phoneQuotaKey);
        redisUtil.releaseFixedWindow(ipQuotaKey);
    }
    /**