2025-06-18 10:56:40 +08:00

214 lines
6.9 KiB
Java

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<String, String> redisTemplate;
@Resource
private DySms dySms;
// 登陆
@PostMapping("/login/wechat/mobile")
public Response<LoginDto> 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<LoginDto> loginHcp(@Validated() @ModelAttribute LoginHcpRequest request) {
// 用户登陆
LoginDto g = userService.UserLoginWithApp(request.getToken());
return Response.success(g);
}
// 获取签名
@GetMapping("/sign/oss")
public Response<GetOssSignDto> 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<T> 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<LoginDto> 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());
}
}
}