From 4bb8b55919bf9a1c8ea8764db8fb8d23b3b568cd Mon Sep 17 00:00:00 2001 From: zhangli <123879394@qq.com> Date: Wed, 9 Jul 2025 20:57:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=92=8C=E6=B3=A8=E5=86=8C=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sczx/user/common/IApiCode.java | 12 ++ .../java/com/sczx/user/common/Result.java | 114 ++++++++++++++++++ .../sczx/user/common/enums/ApiErrorCode.java | 54 +++++++++ .../sczx/user/controller/AuthController.java | 43 +++++-- .../com/sczx/user/exception/BizException.java | 85 +++++++++++++ .../exception/GlobalExceptionHandler.java | 50 ++++++++ .../sczx/user/exception/InnerException.java | 86 +++++++++++++ .../com/sczx/user/service/IUserService.java | 33 +++++ .../user/service/impl/UserServiceImpl.java | 54 +++++++++ 9 files changed, 518 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/sczx/user/common/IApiCode.java create mode 100644 src/main/java/com/sczx/user/common/Result.java create mode 100644 src/main/java/com/sczx/user/common/enums/ApiErrorCode.java create mode 100644 src/main/java/com/sczx/user/exception/BizException.java create mode 100644 src/main/java/com/sczx/user/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/sczx/user/exception/InnerException.java diff --git a/src/main/java/com/sczx/user/common/IApiCode.java b/src/main/java/com/sczx/user/common/IApiCode.java new file mode 100644 index 0000000..68ecb60 --- /dev/null +++ b/src/main/java/com/sczx/user/common/IApiCode.java @@ -0,0 +1,12 @@ +package com.sczx.user.common; + +/** + * @Author: 张黎 + * @Date: 2025/07/09/20:20 + * @Description: + */ +public interface IApiCode { + String getCode(); + + String getMsg(); +} diff --git a/src/main/java/com/sczx/user/common/Result.java b/src/main/java/com/sczx/user/common/Result.java new file mode 100644 index 0000000..9697498 --- /dev/null +++ b/src/main/java/com/sczx/user/common/Result.java @@ -0,0 +1,114 @@ +package com.sczx.user.common; + + +import com.sczx.user.common.enums.ApiErrorCode; +import lombok.Builder; +import lombok.Data; +import org.apache.commons.lang.StringUtils; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: 张黎 + * @Date: 2025/07/09/20:25 + * @Description: + */ +@Builder +@Data +public class Result implements Serializable { + private static final long serialVersionUID = 1331134667810352183L; + private boolean success; + private String code; + private String msg; + private String issue; + private T data; + + public Result(boolean success, String code, String msg, String issue, T data) { + this.success = success; + this.code = code; + this.msg = msg; + this.issue = issue; + this.data = data; + } + + public static Result result(IApiCode apiCode) { + return result(apiCode, (Object)null); + } + + public static Result result(IApiCode apiCode, Object data) { + return result(apiCode, apiCode.getMsg(), data); + } + + public static Result result(IApiCode apiCode, String issue, Object data) { + return result((IApiCode)apiCode, (String)null, issue, data); + } + + public static Result result(IApiCode apiCode, String msg, String issue, Object data) { + String message = apiCode.getMsg(); + if (StringUtils.isNotBlank(msg)) { + message = msg; + } + + return result(apiCode.getCode(), message, issue, data); + } + + public static Result result(String code, String msg, String issue, Object data) { + return builder().code(code).success("0".equals(code)).msg(msg).issue(issue).data(data).build(); + } + + public static Result ok() { + return ok((Object)null); + } + + public static Result ok(Object data) { + return result(ApiErrorCode.SUCCESS, data); + } + + public static Result ok(String key, Object value) { + Map map = new HashMap(1); + map.put(key, value); + return ok(map); + } + + public static Result fail(String msg) { + return result((IApiCode)ApiErrorCode.FAIL, msg, msg, (Object)null); + } + + public static Result fail(IApiCode apiCode) { + return result(apiCode, (Object)null); + } + + public static Result fail(IApiCode apiCode, String issue) { + return result(apiCode, issue, (Object)null); + } + + public static Result fail(String code, String msg) { + return result((String)code, msg, msg, (Object)null); + } + + public static Result fail(String code, String msg, String issue) { + return result((String)code, msg, issue, (Object)null); + } + + public static Result fail(String code, String msg, String issue, Object data) { + return result(code, msg, issue, data); + } + + public static Result fail(IApiCode apiCode, String issue, Object data) { + if (ApiErrorCode.SUCCESS == apiCode) { + throw new RuntimeException("失败结果状态码不能为" + ApiErrorCode.SUCCESS.getCode()); + } else { + return result(apiCode, issue, data); + } + } + + public static Result fail(String key, Object value) { + Map map = new HashMap(); + map.put(key, value); + return result(ApiErrorCode.FAIL, map); + } + public Result() { + } +} diff --git a/src/main/java/com/sczx/user/common/enums/ApiErrorCode.java b/src/main/java/com/sczx/user/common/enums/ApiErrorCode.java new file mode 100644 index 0000000..860e705 --- /dev/null +++ b/src/main/java/com/sczx/user/common/enums/ApiErrorCode.java @@ -0,0 +1,54 @@ +package com.sczx.user.common.enums; + +import com.sczx.user.common.IApiCode; + +/** + * @Author: 张黎 + * @Date: 2025/07/09/20:22 + * @Description: + */ +public enum ApiErrorCode implements IApiCode { + SUCCESS("0", "操作成功"), + ARG_ERROR("401000", "参数错误"), + NOT_PERMISSION("401001", "没有权限"), + HTTP_MEDIA_TYPE_NOT_SUPPORTED_ERROR("401002", "media类型出错"), + HTTP_METHOD_NOT_ALLOW_ERROR("401003", "http请求method错误"), + BODY_NOT_MATCH("401004", "请求的数据格式不符!"), + NOT_FOUND("404000", "你请求的路径不存在"), + UNAUTHORIZED("404001", "非法访问"), + FAIL("500000", "操作失败"), + INNER_ERROR("500001", "服务器内部异常"); + + private final String code; + private final String msg; + + private ApiErrorCode(String code, String msg) { + this.code = code; + this.msg = msg; + } + + public static ApiErrorCode getApiCode(String code) { + ApiErrorCode[] ecs = values(); + ApiErrorCode[] var2 = ecs; + int var3 = ecs.length; + + for(int var4 = 0; var4 < var3; ++var4) { + ApiErrorCode ec = var2[var4]; + if (ec.getCode().equals(code)) { + return ec; + } + } + + return SUCCESS; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getMsg() { + return this.msg; + } +} diff --git a/src/main/java/com/sczx/user/controller/AuthController.java b/src/main/java/com/sczx/user/controller/AuthController.java index ade6cab..d8c3816 100644 --- a/src/main/java/com/sczx/user/controller/AuthController.java +++ b/src/main/java/com/sczx/user/controller/AuthController.java @@ -1,5 +1,6 @@ package com.sczx.user.controller; +import com.sczx.user.common.Result; import com.sczx.user.model.LoginRequest; import com.sczx.user.service.IUserService; import com.sczx.user.util.JwtUtil; @@ -9,10 +10,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -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; +import org.springframework.web.bind.annotation.*; @Api(value = "登录控制器", produces = "注册、登录") @RequestMapping("/auth") @@ -24,16 +22,35 @@ public class AuthController { @Autowired private JwtUtil jwtUtil; - @ApiOperation(value = "注册", notes = "用户注册",produces = "application/json") - @PostMapping("/register") - public ResponseEntity register(@RequestBody LoginRequest request) { - return ResponseEntity.ok(userService.register(request)); + @ApiOperation(value = "微信小程序登录", notes = "通过微信code登录") + @PostMapping("/mini-program/wechat/login") + public Result wechatLogin(@RequestParam("code") String code) { + String token = userService.miniProgramLogin(code); + return Result.ok(token); } - @ApiOperation(value = "登录", notes = "用户登录返回token",produces = "application/json") - @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginRequest request) { - String token = userService.login(request); - return ResponseEntity.ok(token); + @ApiOperation(value = "微信小程序注册", notes = "通过微信code注册") + @PostMapping("/mini-program/wechat/register") + public Result wechatRegister( + @RequestParam("code") String code, + @RequestBody LoginRequest request) { + String token = userService.miniProgramRegister(code, request.getUsername(), request.getPassword()); + return Result.ok(token); + } + + @ApiOperation(value = "支付宝小程序登录", notes = "通过支付宝userId登录") + @PostMapping("/mini-program/alipay/login") + public Result alipayLogin(@RequestParam("userId") String userId) { + String token = userService.alipayMiniProgramLogin(userId); + return Result.ok(token); + } + + @ApiOperation(value = "支付宝小程序注册", notes = "通过支付宝userId注册") + @PostMapping("/mini-program/alipay/register") + public Result alipayRegister( + @RequestParam("userId") String userId, + @RequestBody LoginRequest request) { + String token = userService.alipayMiniProgramRegister(userId, request.getUsername(), request.getPassword()); + return Result.ok(token); } } diff --git a/src/main/java/com/sczx/user/exception/BizException.java b/src/main/java/com/sczx/user/exception/BizException.java new file mode 100644 index 0000000..2a7e98b --- /dev/null +++ b/src/main/java/com/sczx/user/exception/BizException.java @@ -0,0 +1,85 @@ +package com.sczx.user.exception; + + +import com.sczx.user.common.IApiCode; +import com.sczx.user.common.enums.ApiErrorCode; + +/** + * + * @author zhangli + */ +public class BizException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + protected String errorCode; + /** + * 错误信息 + */ + protected String errorMsg; + + public BizException() { + super(); + } + + public BizException(IApiCode apiCode) { + super(apiCode.getCode()); + this.errorCode = apiCode.getCode(); + this.errorMsg = apiCode.getMsg(); + } + + public BizException(IApiCode apiCode, Throwable cause) { + super(apiCode.getCode(), cause); + this.errorCode = apiCode.getCode(); + this.errorMsg = apiCode.getMsg(); + } + + public BizException(String errorMsg) { + super(errorMsg); + this.errorCode = ApiErrorCode.FAIL.getCode(); + this.errorMsg = errorMsg; + } + + public BizException(String errorCode, String errorMsg) { + super(errorCode); + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + public BizException(String errorCode, String errorMsg, Throwable cause) { + super(errorCode, cause); + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + @Override + public String getMessage() { + return errorMsg; + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + +} diff --git a/src/main/java/com/sczx/user/exception/GlobalExceptionHandler.java b/src/main/java/com/sczx/user/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..6532735 --- /dev/null +++ b/src/main/java/com/sczx/user/exception/GlobalExceptionHandler.java @@ -0,0 +1,50 @@ +package com.sczx.user.exception; + + +import com.sczx.user.common.Result; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; + + +/** + * @author zhangli + */ +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + + + /** + * 处理自定义的业务异常 + * + * @param req + * @param e + * @return + */ + @ExceptionHandler(value = BizException.class) + @ResponseBody + public Result bizExceptionHandler(HttpServletRequest req, BizException e) { + log.warn("发生业务异常!原因是:{}", e.getErrorMsg(), e); + return Result.fail(e.getErrorCode(), e.getErrorMsg()); + } + + @ExceptionHandler(value = InnerException.class) + @ResponseBody + public Result innerExceptionHandler(HttpServletRequest req, InnerException e) { + log.error("发生服务内部异常!原因是:{}", e.getErrorMsg(), e); + return Result.fail(e.getErrorCode(), e.getErrorMsg()); + } + + @ExceptionHandler(value = Exception.class) + @ResponseBody + public Result exceptionHandler(HttpServletRequest req, Exception e) { + log.error("意料外异常!原因是:{}", e.getMessage(), e); + return Result.fail("99999", "系统内部异常"); + } + +} diff --git a/src/main/java/com/sczx/user/exception/InnerException.java b/src/main/java/com/sczx/user/exception/InnerException.java new file mode 100644 index 0000000..2825fef --- /dev/null +++ b/src/main/java/com/sczx/user/exception/InnerException.java @@ -0,0 +1,86 @@ +package com.sczx.user.exception; + + +import com.sczx.user.common.IApiCode; +import com.sczx.user.common.enums.ApiErrorCode; + +/** + * + * @author zhangli + + */ +public class InnerException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + protected String errorCode; + /** + * 错误信息 + */ + protected String errorMsg; + + public InnerException() { + super(); + } + + public InnerException(IApiCode apiCode) { + super(apiCode.getCode()); + this.errorCode = apiCode.getCode(); + this.errorMsg = apiCode.getMsg(); + } + + public InnerException(IApiCode apiCode, Throwable cause) { + super(apiCode.getCode(), cause); + this.errorCode = apiCode.getCode(); + this.errorMsg = apiCode.getMsg(); + } + + public InnerException(String errorMsg) { + super(errorMsg); + this.errorCode = ApiErrorCode.INNER_ERROR.getCode(); + this.errorMsg = errorMsg; + } + + public InnerException(String errorCode, String errorMsg) { + super(errorCode); + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + public InnerException(String errorCode, String errorMsg, Throwable cause) { + super(errorCode, cause); + this.errorCode = errorCode; + this.errorMsg = errorMsg; + } + + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMsg() { + return errorMsg; + } + + public void setErrorMsg(String errorMsg) { + this.errorMsg = errorMsg; + } + + @Override + public String getMessage() { + return errorMsg; + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + +} diff --git a/src/main/java/com/sczx/user/service/IUserService.java b/src/main/java/com/sczx/user/service/IUserService.java index bbe0f77..e4e9e43 100644 --- a/src/main/java/com/sczx/user/service/IUserService.java +++ b/src/main/java/com/sczx/user/service/IUserService.java @@ -22,4 +22,37 @@ public interface IUserService { * @return */ String login(LoginRequest request); + + + /** + * 微信小程序登录 + * @param code 微信登录code + * @return token + */ + String miniProgramLogin(String code); + + /** + * 微信小程序注册 + * @param code 微信登录code + * @param username 用户名 + * @param password 密码 + * @return token + */ + String miniProgramRegister(String code, String username, String password); + + /** + * 支付宝小程序登录 + * @param userId 支付宝用户ID + * @return token + */ + String alipayMiniProgramLogin(String userId); + + /** + * 支付宝小程序注册 + * @param userId 支付宝用户ID + * @param username 用户名 + * @param password 密码 + * @return token + */ + String alipayMiniProgramRegister(String userId, String username, String password); } diff --git a/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java b/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java index 051fd1d..b8d6ef7 100644 --- a/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java +++ b/src/main/java/com/sczx/user/service/impl/UserServiceImpl.java @@ -8,6 +8,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; /** @@ -19,6 +21,16 @@ import java.util.concurrent.TimeUnit; @Service public class UserServiceImpl implements IUserService { + // 模拟微信登录获取 openid + private static final Map WECHAT_CODE_TO_OPENID = new HashMap<>(); + private static final Map ALIPAY_ID_TO_USERID = new HashMap<>(); + + static { + // 测试数据模拟 + WECHAT_CODE_TO_OPENID.put("test_wx_code", "user_openid_1"); + ALIPAY_ID_TO_USERID.put("test_alipay_id", "user_id_1"); + } + @Autowired private JwtUtil jwtUtil; @@ -58,4 +70,46 @@ public class UserServiceImpl implements IUserService { return token; } + + + @Override + public String miniProgramLogin(String code) { + String openid = WECHAT_CODE_TO_OPENID.get(code); + if (openid == null) { + throw new RuntimeException("无效的微信登录code"); + } + // 存入 Redis + return jwtUtil.generateToken(openid, "USER"); + } + + @Override + public String miniProgramRegister(String code, String username, String password) { + String openid = WECHAT_CODE_TO_OPENID.get(code); + if (openid == null) { + throw new RuntimeException("无效的微信登录code"); + } + // 模拟注册逻辑 +// userRepository.save(new User(openid, username, password)); + return jwtUtil.generateToken(openid, "USER"); + } + + @Override + public String alipayMiniProgramLogin(String userId) { + String realUserId = ALIPAY_ID_TO_USERID.get(userId); + if (realUserId == null) { + throw new RuntimeException("无效的支付宝用户ID"); + } + return jwtUtil.generateToken(realUserId, "USER"); + } + + @Override + public String alipayMiniProgramRegister(String userId, String username, String password) { + String realUserId = ALIPAY_ID_TO_USERID.get(userId); + if (realUserId == null) { + throw new RuntimeException("无效的支付宝用户ID"); + } + // 模拟注册逻辑 +// userRepository.save(new User(realUserId, username, password)); + return jwtUtil.generateToken(realUserId, "USER"); + } }