package com.example.caseData.controller; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import com.example.caseData.common.Response; import com.example.caseData.config.EnvConfig; import com.example.caseData.dto.T; import com.example.caseData.dto.publicDto.GetOssSignDto; import com.example.caseData.dto.publicDto.LoginDto; import com.example.caseData.dto.user.UserDto; import com.example.caseData.extend.aliyun.DySms; import com.example.caseData.extend.aliyun.Oss; import com.example.caseData.extend.weChat.WxMaServiceUtils; import com.example.caseData.request.publicRequest.*; import com.example.caseData.request.UserRequest.UserRequest; import com.example.caseData.service.UserService; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.time.Duration; import java.util.Map; import java.util.Objects; import java.util.Random; @RequiredArgsConstructor @RestController @RequestMapping("/api") public class PublicController { @Resource private UserService userService; @Resource private HttpServletRequest httpServletRequest; @Resource private EnvConfig envConfig; private final WxMaServiceUtils wxMaServiceUtils; @Resource private RedisTemplate redisTemplate; @Resource private DySms dySms; // 登陆 @PostMapping("/login/wechat/mobile") public Response loginWechatMobile(@Validated({LoginRequest.Login.class}) @ModelAttribute LoginRequest request) { // 微信手机号授权登录 try { // 获取手机号 WxMaPhoneNumberInfo phoneInfo = wxMaServiceUtils.getPhoneNumber(request.getPhone_code()); if (phoneInfo == null) { return Response.error("微信授权失败"); } if (phoneInfo.getPurePhoneNumber() == null) { return Response.error("微信授权失败"); } // 获取用户openid WxMaJscode2SessionResult wxInfoData = wxMaServiceUtils.getSessionInfo(request.getWx_code()); if (wxInfoData == null) { return Response.error("微信授权失败"); } if (wxInfoData.getOpenid() == null) { return Response.error("微信授权失败"); } if (wxInfoData.getSessionKey() == null) { return Response.error("微信授权失败"); } // 用户登陆 LoginDto g = userService.UserLoginWithMobile(phoneInfo.getPurePhoneNumber()); return Response.success(g); } catch (Exception e) { return Response.error(e.getMessage()); } } // 登陆 @PostMapping("/login/hcp") public Response loginHcp(@Validated() @ModelAttribute LoginHcpRequest request) { // 用户登陆 LoginDto g = userService.UserLoginWithApp(request.getToken()); return Response.success(g); } // 获取签名 @GetMapping("/sign/oss") public Response GetOssSign( @Validated() @ModelAttribute GetOssSignRequest request ) { String userId = (String) httpServletRequest.getAttribute("userId"); String ossPath = "dev/"; if (Objects.equals(envConfig.getActive(), "prod")){ ossPath = "prod/"; } if (request.getScene() == 1){ ossPath = ossPath + "static/images/exchange/"; }else if (request.getScene() == 2){ ossPath = ossPath + "static/video/exchange/"; }else{ return Response.error(); } // 生成签名 GetOssSignDto g = Oss.getOssSign(ossPath); return Response.success(g); } // 获取验证码 @PostMapping("/code/phone") public Response GetPhoneCode(@Validated() @ModelAttribute GetPhoneCodeRequest request) { String templateCode = ""; String scene = "注册验证码"; // 手机号登录 if (request.getScene() == 1){ templateCode = "SMS_215344868"; scene = "注册验证码"; } // 限流 key String limitKey = "sms:limit:" + request.getPhone(); // 验证码缓存 key String codeKey = "sms:code:" + request.getPhone(); // 获取当前请求次数 String countStr = redisTemplate.opsForValue().get(limitKey); int count = countStr != null ? Integer.parseInt(countStr) : 0; if (count > 3) { return Response.error("验证码请求过于频繁,请稍后再试"); } // 生成 4 位数字验证码 String code = String.format("%04d", new Random().nextInt(10000)); try { dySms.sendSms( request.getPhone(), templateCode, scene, Map.of("code", code) ); } catch (Exception e) { return Response.error(e.getMessage()); } // 缓存验证码(有效期 5 分钟) redisTemplate.opsForValue().set(codeKey, code, Duration.ofMinutes(5)); // 缓存请求次数 if (count == 0) { // 初次请求,设置有效期为 5 分钟 redisTemplate.opsForValue().set(limitKey, "1", Duration.ofMinutes(5)); } else { redisTemplate.opsForValue().increment(limitKey); } return Response.success(); } // 登陆 @PostMapping("/login/mobile") public Response loginPhone(@Validated() @ModelAttribute LoginPhoneRequest request) { // 验证码缓存 key if (!Objects.equals(envConfig.getActive(), "dev")){ String codeKey = "sms:code:" + request.getPhone(); String code = redisTemplate.opsForValue().get(codeKey); if (!Objects.equals(request.getCode(), code)){ return Response.error("验证码错误"); } } try { // 获取用户openid WxMaJscode2SessionResult wxInfoData = wxMaServiceUtils.getSessionInfo(request.getWx_code()); if (wxInfoData == null) { return Response.error("微信授权失败"); } if (wxInfoData.getOpenid() == null) { return Response.error("微信授权失败"); } if (wxInfoData.getSessionKey() == null) { return Response.error("微信授权失败"); } // 用户登陆 LoginDto g = userService.UserLoginWithMobile(request.getPhone()); return Response.success(g); } catch (Exception e) { return Response.error(e.getMessage()); } } }