package com.ruoyi.promo.controller; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.ruoyi.admin.mapper.PromoAdminMapper; import com.ruoyi.admin.service.TtUserService; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.domain.common.constant.UserType; import com.ruoyi.domain.entity.sys.TtUser; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.thirdparty.common.model.ApiSmsBody; import com.ruoyi.thirdparty.common.service.ApiSmsService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 推广后台短信验证码控制器 * POST /promo/sms/getVerifyCode - 获取短信验证码(需要滑块验证) */ @Api(tags = "推广后台短信") @Slf4j @RestController @RequestMapping("/promo/sms") public class PromoSmsController extends BaseController { private final ISysConfigService sysConfigService; private final ApiSmsService apiSmsService; private final PromoAdminMapper promoAdminMapper; @Autowired private RedisCache redisCache; @Autowired private TtUserService userService; public PromoSmsController(ISysConfigService sysConfigService, ApiSmsService apiSmsService, PromoAdminMapper promoAdminMapper) { this.sysConfigService = sysConfigService; this.apiSmsService = apiSmsService; this.promoAdminMapper = promoAdminMapper; } /** * 获取短信验证码(推广后台版本) * 需要先完成/promo/captcha/check 滑块验证 */ @ApiOperation("获取短信验证码") @Anonymous @PostMapping("/getVerifyCode") public R getVerifyCode(@RequestBody ApiSmsBody smsBody) { String websiteMaintenance = sysConfigService.selectConfigByKey("websiteMaintenance"); if ("1".equals(websiteMaintenance)) { return R.fail("网站维护中......"); } String phoneNumber = smsBody.getPhoneNumber(); String captchaId = smsBody.getCaptchaId(); if (!"1".equals(smsBody.getType()) && !"2".equals(smsBody.getType())) { return R.fail("验证码类型错误"); } if ("2".equals(smsBody.getType())) { TtUser user = new LambdaQueryChainWrapper<>(userService.getBaseMapper()) .eq(TtUser::getPhoneNumber, phoneNumber) .eq(TtUser::getDelFlag, "0") .eq(TtUser::getStatus, "0") .one(); boolean hasPromoRole = user != null && (UserType.ANCHOR.getCode().equals(user.getUserType()) || UserType.BUSINESS_USER.getCode().equals(user.getUserType()) || UserType.CARD_MERCHANT.getCode().equals(user.getUserType())); // 超级管理员账号(promo_admin.username / phone_number)也可以是手机号,同样允许短信登录 boolean isSuperAdmin = !hasPromoRole && promoAdminMapper.findByAccount(phoneNumber) != null; // 手机号没注册过:带有效招商邀请码时允许发码(登录即自动注册为主播) boolean canAutoRegister = !hasPromoRole && !isSuperAdmin && StringUtils.isNotEmpty(smsBody.getParentInvitationCode()) && findBusinessByInvitationCode(smsBody.getParentInvitationCode()) != null; if (!hasPromoRole && !isSuperAdmin && !canAutoRegister) { return R.fail("该手机号无推广后台登录权限"); } } // 校验推广后台滑块验证码 if (StringUtils.isEmpty(captchaId)) { return R.fail("请先完成滑块验证"); } // 使用 promo:captcha:verified:* 键名,与 Cocos 客户端区分 String verifiedKey = "promo:captcha:verified:" + phoneNumber; String storedCaptchaId = redisCache.getCacheObject(verifiedKey); if (StringUtils.isEmpty(storedCaptchaId) || !storedCaptchaId.equals(captchaId)) { return R.fail("滑块验证已过期或无效,请重新验证"); } String msg = apiSmsService.getVerifyCode(smsBody); if (StringUtils.isNotEmpty(msg)) { // 短信发送失败(次数/余额不足),返回特定错误码 if (msg.contains("次数") || msg.contains("余额") || msg.contains("不足")) { return R.fail(999, "短信发送次数不足"); } return R.fail(msg); } log.info("[推广后台短信发送成功] phone={}", phoneNumber); return R.ok("获取验证码成功,请注意短信通知!"); } /** * 按邀请码找招商账号(必须是 04 招商) */ private TtUser findBusinessByInvitationCode(String invitationCode) { TtUser parent = new LambdaQueryChainWrapper<>(userService.getBaseMapper()) .eq(TtUser::getInvitationCode, invitationCode.trim().toUpperCase()) .eq(TtUser::getDelFlag, "0") .eq(TtUser::getStatus, "0") .one(); if (parent == null || !UserType.BUSINESS_USER.getCode().equals(parent.getUserType())) { return null; } return parent; } }