增加小程序登录和注册接口

This commit is contained in:
2025-07-09 20:57:58 +08:00
parent 60891d8c70
commit 4bb8b55919
9 changed files with 518 additions and 13 deletions

View File

@ -0,0 +1,12 @@
package com.sczx.user.common;
/**
* @Author: 张黎
* @Date: 2025/07/09/20:20
* @Description:
*/
public interface IApiCode {
String getCode();
String getMsg();
}

View File

@ -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<T> 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<String, Object> 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<String, Object> map = new HashMap();
map.put(key, value);
return result(ApiErrorCode.FAIL, map);
}
public Result() {
}
}

View File

@ -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;
}
}

View File

@ -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<String> register(@RequestBody LoginRequest request) {
return ResponseEntity.ok(userService.register(request));
@ApiOperation(value = "微信小程序登录", notes = "通过微信code登录")
@PostMapping("/mini-program/wechat/login")
public Result<String> 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<String> login(@RequestBody LoginRequest request) {
String token = userService.login(request);
return ResponseEntity.ok(token);
@ApiOperation(value = "微信小程序注册", notes = "通过微信code注册")
@PostMapping("/mini-program/wechat/register")
public Result<String> 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<String> 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<String> alipayRegister(
@RequestParam("userId") String userId,
@RequestBody LoginRequest request) {
String token = userService.alipayMiniProgramRegister(userId, request.getUsername(), request.getPassword());
return Result.ok(token);
}
}

View File

@ -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;
}
}

View File

@ -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", "系统内部异常");
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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<String, String> WECHAT_CODE_TO_OPENID = new HashMap<>();
private static final Map<String, String> 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");
}
}