- 后端:User 模块,接入统一的 OAuth2 服务
This commit is contained in:
parent
be94f29791
commit
68027b9f16
@ -14,11 +14,11 @@
|
|||||||
- [x] 发布商品
|
- [x] 发布商品
|
||||||
- [x] 商品列表
|
- [x] 商品列表
|
||||||
- [x] 展示类目
|
- [x] 展示类目
|
||||||
- [ ] 品牌管理【待认领】
|
- [ ] 品牌管理【开发中 @黑子】
|
||||||
- [ ] 订单管理
|
- [ ] 订单管理
|
||||||
- [ ] 销售单 开发中
|
- [ ] 销售单 开发中
|
||||||
- [ ] 售后单 开发中
|
- [ ] 售后单 开发中
|
||||||
- [ ] 订单评价【开发中】
|
- [ ] 订单评价【开发中 @wang171776704】
|
||||||
- [ ] 会员管理
|
- [ ] 会员管理
|
||||||
- [ ] 会员资料 20%【待认领】
|
- [ ] 会员资料 20%【待认领】
|
||||||
- TODO 需要补充
|
- TODO 需要补充
|
||||||
@ -33,8 +33,10 @@
|
|||||||
- [ ] 系统管理
|
- [ ] 系统管理
|
||||||
- [x] 员工管理
|
- [x] 员工管理
|
||||||
- [x] 角色管理 <!--【前端页面需要细化下】-->
|
- [x] 角色管理 <!--【前端页面需要细化下】-->
|
||||||
- [ ] 权限管理
|
- [x] 权限管理 <!--【前端页面需要细化下】-->
|
||||||
- [ ] 短信管理
|
- [ ] 部门管理【待认领】
|
||||||
|
- [x] 数据字典
|
||||||
|
- [ ] 短信管理【开发中 @小范】
|
||||||
- [ ] 短信模板
|
- [ ] 短信模板
|
||||||
- [ ] 发送日志
|
- [ ] 发送日志
|
||||||
- [ ] 员工操作日志
|
- [ ] 员工操作日志
|
||||||
|
@ -69,7 +69,7 @@ export default {
|
|||||||
let that = this;
|
let that = this;
|
||||||
let response = doPassportMobileRegister(this.mobile, this.code);
|
let response = doPassportMobileRegister(this.mobile, this.code);
|
||||||
response.then(data => {
|
response.then(data => {
|
||||||
setLoginToken(data.accessToken, data.refreshToken);
|
setLoginToken(data.token.accessToken, data.token.refreshToken);
|
||||||
Dialog.alert({
|
Dialog.alert({
|
||||||
title: '系统提示',
|
title: '系统提示',
|
||||||
message: '登陆成功',
|
message: '登陆成功',
|
||||||
|
@ -17,7 +17,7 @@ import java.util.Map;
|
|||||||
public interface AdminService {
|
public interface AdminService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户认证。认证成功后,返回认证信息
|
* 管理员认证。认证成功后,返回认证信息
|
||||||
*
|
*
|
||||||
* 实际上,就是用户名 + 密码登陆
|
* 实际上,就是用户名 + 密码登陆
|
||||||
*
|
*
|
||||||
|
@ -20,6 +20,8 @@ public interface OAuth2Service {
|
|||||||
|
|
||||||
// TODO @see 刷新 token
|
// TODO @see 刷新 token
|
||||||
|
|
||||||
|
void removeToken(Integer userId); // TODO 需要优化
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 accessToken 获得身份信息
|
* 通过 accessToken 获得身份信息
|
||||||
*
|
*
|
||||||
|
@ -5,10 +5,12 @@ import io.swagger.annotations.ApiModelProperty;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@ApiModel("OAUTH2 认证 BO")
|
@ApiModel("OAUTH2 认证 BO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class OAuth2AuthenticationBO {
|
public class OAuth2AuthenticationBO implements Serializable {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||||
private Integer userId;
|
private Integer userId;
|
||||||
|
@ -8,11 +8,12 @@ import lombok.Data;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@ApiModel("OAuth2 创建 Token DTO")
|
@ApiModel("OAuth2 创建 Token DTO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class OAuth2CreateTokenDTO {
|
public class OAuth2CreateTokenDTO implements Serializable {
|
||||||
|
|
||||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||||
@NotNull(message = "用户编号不能为空")
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
@ -9,11 +9,12 @@ import lombok.experimental.Accessors;
|
|||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@ApiModel("OAuth2 身份验证 DTO")
|
@ApiModel("OAuth2 身份验证 DTO")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class OAuth2GetTokenDTO {
|
public class OAuth2GetTokenDTO implements Serializable {
|
||||||
|
|
||||||
@ApiModelProperty(value = "accessToken", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
@ApiModelProperty(value = "accessToken", required = true, example = "001e8f49b20e47f7b3a2de774497cd50")
|
||||||
@NotEmpty(message = "accessToken 不能为空")
|
@NotEmpty(message = "accessToken 不能为空")
|
||||||
|
@ -64,6 +64,7 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
|||||||
*
|
*
|
||||||
* @param adminId 管理员编号
|
* @param adminId 管理员编号
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void removeToken(Integer adminId) {
|
public void removeToken(Integer adminId) {
|
||||||
// 设置 access token 失效
|
// 设置 access token 失效
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package cn.iocoder.mall.admin.service;
|
package cn.iocoder.mall.admin.service;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.exception.ServiceException;
|
||||||
import cn.iocoder.mall.admin.api.SmsPlatform;
|
import cn.iocoder.mall.admin.api.SmsPlatform;
|
||||||
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||||
import cn.iocoder.mall.admin.api.constant.SmsApplyStatusEnum;
|
import cn.iocoder.mall.admin.api.constant.SmsApplyStatusEnum;
|
||||||
import cn.iocoder.mall.admin.api.exception.SmsFailException;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
@ -104,7 +104,7 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
String result = post(URL_SIGN_ADD, params);
|
String result = post(URL_SIGN_ADD, params);
|
||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
||||||
throw new SmsFailException(AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getCode(),
|
throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getCode(),
|
||||||
AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getMessage());
|
AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +124,13 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
|
||||||
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
||||||
throw new SmsFailException(AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getCode(),
|
throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getCode(),
|
||||||
AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getMessage());
|
AdminErrorCodeEnum.SMS_SIGN_ADD_FAIL.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray jsonArray = jsonObject.getJSONArray("sign");
|
JSONArray jsonArray = jsonObject.getJSONArray("sign");
|
||||||
if (jsonArray.size() <= 0) {
|
if (jsonArray.size() <= 0) {
|
||||||
throw new SmsFailException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
|
throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getCode(),
|
||||||
AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
|
AdminErrorCodeEnum.SMS_SIGN_NOT_EXISTENT.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ public class SmsYunPianPlatform implements SmsPlatform {
|
|||||||
JSONObject jsonObject = JSON.parseObject(result);
|
JSONObject jsonObject = JSON.parseObject(result);
|
||||||
|
|
||||||
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
if (!(jsonObject.getInteger("code") == SUCCESS_CODE)) {
|
||||||
throw new SmsFailException(AdminErrorCodeEnum.SMS_SIGN_UPDATE_FAIL.getCode(),
|
throw new ServiceException(AdminErrorCodeEnum.SMS_SIGN_UPDATE_FAIL.getCode(),
|
||||||
AdminErrorCodeEnum.SMS_SIGN_UPDATE_FAIL.getMessage());
|
AdminErrorCodeEnum.SMS_SIGN_UPDATE_FAIL.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,13 +5,13 @@ import cn.iocoder.mall.user.api.MobileCodeService;
|
|||||||
import cn.iocoder.mall.user.api.OAuth2Service;
|
import cn.iocoder.mall.user.api.OAuth2Service;
|
||||||
import cn.iocoder.mall.user.api.UserService;
|
import cn.iocoder.mall.user.api.UserService;
|
||||||
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
||||||
|
import cn.iocoder.mall.user.api.bo.user.UserAuthenticationBO;
|
||||||
|
import cn.iocoder.mall.user.api.dto.user.UserAuthenticationByMobileCodeDTO;
|
||||||
import cn.iocoder.mall.user.application.convert.PassportConvert;
|
import cn.iocoder.mall.user.application.convert.PassportConvert;
|
||||||
import cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO;
|
import cn.iocoder.mall.user.application.vo.users.UsersAccessTokenVO;
|
||||||
import cn.iocoder.mall.user.application.vo.users.UsersMobileRegisterVO;
|
|
||||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.apache.dubbo.config.annotation.Reference;
|
import org.apache.dubbo.config.annotation.Reference;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@ -43,14 +43,8 @@ public class PassportController {
|
|||||||
@PermitAll
|
@PermitAll
|
||||||
@PostMapping("/mobile/register")
|
@PostMapping("/mobile/register")
|
||||||
@ApiOperation(value = "手机号 + 验证码登陆(注册)", notes = "如果手机对应的账号不存在,则会自动创建")
|
@ApiOperation(value = "手机号 + 验证码登陆(注册)", notes = "如果手机对应的账号不存在,则会自动创建")
|
||||||
@ApiImplicitParams({
|
public CommonResult<UserAuthenticationBO> mobileRegister(UserAuthenticationByMobileCodeDTO userAuthenticationByMobileCodeDTO) {
|
||||||
@ApiImplicitParam(name = "mobile", value = "手机号", required = true, example = "15601691300"),
|
return success(userService.authenticationByMobileCode(userAuthenticationByMobileCodeDTO));
|
||||||
@ApiImplicitParam(name = "code", value = "验证码", required = true, example = "9999")
|
|
||||||
})
|
|
||||||
public CommonResult<UsersMobileRegisterVO> mobileRegister(@RequestParam("mobile") String mobile,
|
|
||||||
@RequestParam("code") String code) {
|
|
||||||
OAuth2AccessTokenBO result = oauth2Service.getAccessToken(mobile, code);
|
|
||||||
return success(PassportConvert.INSTANCE.convert(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PermitAll
|
@PermitAll
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package cn.iocoder.mall.user.sdk.context;
|
package cn.iocoder.mall.user.sdk.context;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User Security 上下文
|
* User Security 上下文
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
public class UserSecurityContext {
|
public class UserSecurityContext {
|
||||||
|
|
||||||
private final Integer userId;
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
private Integer userId;
|
||||||
|
|
||||||
public UserSecurityContext(Integer userId) {
|
}
|
||||||
this.userId = userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getUserId() {
|
|
||||||
return userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,7 @@ public class UserSecurityContextHolder {
|
|||||||
UserSecurityContext ctx = SECURITY_CONTEXT.get();
|
UserSecurityContext ctx = SECURITY_CONTEXT.get();
|
||||||
// 为空时,设置一个空的进去
|
// 为空时,设置一个空的进去
|
||||||
if (ctx == null) {
|
if (ctx == null) {
|
||||||
ctx = new UserSecurityContext(null);
|
ctx = new UserSecurityContext();
|
||||||
SECURITY_CONTEXT.set(ctx);
|
SECURITY_CONTEXT.set(ctx);
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package cn.iocoder.mall.user.sdk.interceptor;
|
package cn.iocoder.mall.user.sdk.interceptor;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.constant.MallConstants;
|
import cn.iocoder.common.framework.constant.UserTypeEnum;
|
||||||
import cn.iocoder.common.framework.exception.ServiceException;
|
import cn.iocoder.common.framework.exception.ServiceException;
|
||||||
import cn.iocoder.common.framework.util.HttpUtil;
|
import cn.iocoder.common.framework.util.HttpUtil;
|
||||||
import cn.iocoder.common.framework.util.MallUtil;
|
import cn.iocoder.common.framework.util.MallUtil;
|
||||||
import cn.iocoder.mall.user.api.OAuth2Service;
|
import cn.iocoder.common.framework.util.StringUtil;
|
||||||
import cn.iocoder.mall.user.api.bo.OAuth2AuthenticationBO;
|
import cn.iocoder.mall.admin.api.OAuth2Service;
|
||||||
|
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AuthenticationBO;
|
||||||
|
import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
|
||||||
|
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2GetTokenDTO;
|
||||||
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
import cn.iocoder.mall.user.sdk.annotation.PermitAll;
|
||||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContext;
|
import cn.iocoder.mall.user.sdk.context.UserSecurityContext;
|
||||||
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
|
||||||
@ -18,40 +21,55 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全拦截器
|
* User 安全拦截器
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
|
public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
|
||||||
|
|
||||||
@Reference(validation = "true", version = "${dubbo.provider.OAuth2Service.version:1.0.0}")
|
@Reference(validation = "true", version = "${dubbo.consumer.OAuth2Service.version:1.0.0}")
|
||||||
private OAuth2Service oauth2Service;
|
private OAuth2Service oauth2Service;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
// 设置当前访问的用户类型。注意,即使未登陆,我们也认为是用户
|
// 设置当前访问的用户类型。注意,即使未登陆,我们也认为是用户
|
||||||
MallUtil.setUserType(request, MallConstants.USER_TYPE_USER);
|
MallUtil.setUserType(request, UserTypeEnum.USER.getValue());
|
||||||
// 校验访问令牌是否正确。若正确,返回授权信息
|
|
||||||
|
// 根据 accessToken 获得认证信息,判断是谁
|
||||||
String accessToken = HttpUtil.obtainAuthorization(request);
|
String accessToken = HttpUtil.obtainAuthorization(request);
|
||||||
OAuth2AuthenticationBO authentication = null;
|
OAuth2AuthenticationBO authentication = null;
|
||||||
if (accessToken != null) {
|
ServiceException serviceException = null;
|
||||||
authentication = oauth2Service.checkToken(accessToken); // TODO 芋艿,如果访问的地址无需登录,这里也不用抛异常
|
if (StringUtil.hasText(accessToken)) {
|
||||||
// 添加到 SecurityContext
|
try {
|
||||||
UserSecurityContext context = new UserSecurityContext(authentication.getUserId());
|
authentication = oauth2Service.getAuthentication(new OAuth2GetTokenDTO().setAccessToken(accessToken)
|
||||||
UserSecurityContextHolder.setContext(context);
|
.setUserType(UserTypeEnum.USER.getValue()));
|
||||||
// 同时也记录管理员编号到 AdminAccessLogInterceptor 中。因为:
|
} catch (ServiceException e) {
|
||||||
// AdminAccessLogInterceptor 需要在 AdminSecurityInterceptor 之前执行,这样记录的访问日志才健全
|
serviceException = e;
|
||||||
// AdminSecurityInterceptor 执行后,会移除 AdminSecurityContext 信息,这就导致 AdminAccessLogInterceptor 无法获得管理员编号
|
|
||||||
// 因此,这里需要进行记录
|
|
||||||
if (authentication.getUserId() != null) {
|
|
||||||
MallUtil.setUserId(request, authentication.getUserId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 校验是否需要已授权
|
|
||||||
|
// 进行鉴权
|
||||||
HandlerMethod method = (HandlerMethod) handler;
|
HandlerMethod method = (HandlerMethod) handler;
|
||||||
boolean isPermitAll = method.hasMethodAnnotation(PermitAll.class);
|
boolean isPermitAll = method.hasMethodAnnotation(PermitAll.class);
|
||||||
if (!isPermitAll && authentication == null) {
|
if (!isPermitAll) { // 如果需要鉴权
|
||||||
throw new ServiceException(-1, "未授权"); // TODO 这里要改下
|
if (serviceException != null) { // 认证失败,抛出上面认证失败的 ServiceException 异常
|
||||||
|
throw serviceException;
|
||||||
|
}
|
||||||
|
if (authentication == null) { // 无认证信息,抛出未登陆 ServiceException 异常
|
||||||
|
throw new ServiceException(AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getCode(), AdminErrorCodeEnum.OAUTH2_NOT_LOGIN.getMessage());
|
||||||
|
}
|
||||||
|
// TODO 芋艿,后续拓展读取用户信息
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 鉴权完成,初始化 AdminSecurityContext 上下文
|
||||||
|
UserSecurityContext context = new UserSecurityContext();
|
||||||
|
UserSecurityContextHolder.setContext(context);
|
||||||
|
if (authentication != null) {
|
||||||
|
context.setUserId(authentication.getUserId());
|
||||||
|
MallUtil.setUserId(request, authentication.getUserId()); // 记录到 request 中,避免 AdminSecurityContext 后续清理掉后,其它地方需要用到 userId
|
||||||
|
// TODO 芋艿,后续拓展读取用户信息
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回成功
|
||||||
return super.preHandle(request, response, handler);
|
return super.preHandle(request, response, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
<artifactId>common-framework</artifactId>
|
<artifactId>common-framework</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>system-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 工具类相关 -->
|
<!-- 工具类相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -4,10 +4,9 @@ package cn.iocoder.mall.user.api;
|
|||||||
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
import cn.iocoder.mall.user.api.bo.OAuth2AccessTokenBO;
|
||||||
import cn.iocoder.mall.user.api.bo.OAuth2AuthenticationBO;
|
import cn.iocoder.mall.user.api.bo.OAuth2AuthenticationBO;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface OAuth2Service {
|
public interface OAuth2Service {
|
||||||
|
|
||||||
OAuth2AccessTokenBO getAccessToken(String mobile, String code);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验访问令牌,获取身份信息( 不包括 accessToken 等等 )
|
* 校验访问令牌,获取身份信息( 不包括 accessToken 等等 )
|
||||||
*
|
*
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.mall.user.api;
|
|||||||
|
|
||||||
import cn.iocoder.mall.user.api.dto.UserAccessLogAddDTO;
|
import cn.iocoder.mall.user.api.dto.UserAccessLogAddDTO;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface UserAccessLogService {
|
public interface UserAccessLogService {
|
||||||
|
|
||||||
void addUserAccessLog(UserAccessLogAddDTO userAccessLogAddDTO);
|
void addUserAccessLog(UserAccessLogAddDTO userAccessLogAddDTO);
|
||||||
|
@ -2,13 +2,17 @@ package cn.iocoder.mall.user.api;
|
|||||||
|
|
||||||
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
||||||
import cn.iocoder.common.framework.validator.InEnum;
|
import cn.iocoder.common.framework.validator.InEnum;
|
||||||
|
import cn.iocoder.mall.user.api.bo.user.UserAuthenticationBO;
|
||||||
import cn.iocoder.mall.user.api.bo.UserBO;
|
import cn.iocoder.mall.user.api.bo.UserBO;
|
||||||
import cn.iocoder.mall.user.api.bo.UserPageBO;
|
import cn.iocoder.mall.user.api.bo.UserPageBO;
|
||||||
import cn.iocoder.mall.user.api.dto.UserPageDTO;
|
import cn.iocoder.mall.user.api.dto.UserPageDTO;
|
||||||
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
||||||
|
import cn.iocoder.mall.user.api.dto.user.UserAuthenticationByMobileCodeDTO;
|
||||||
|
|
||||||
public interface UserService {
|
public interface UserService {
|
||||||
|
|
||||||
|
UserAuthenticationBO authenticationByMobileCode(UserAuthenticationByMobileCodeDTO userAuthenticationByMobileCodeDTO);
|
||||||
|
|
||||||
UserPageBO getUserPage(UserPageDTO userPageDTO);
|
UserPageBO getUserPage(UserPageDTO userPageDTO);
|
||||||
|
|
||||||
UserBO getUser(Integer userId);
|
UserBO getUser(Integer userId);
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package cn.iocoder.mall.user.api.bo.user;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@ApiModel("用户认证 BO")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class UserAuthenticationBO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "昵称", required = true, example = "小王")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
private OAuth2AccessTokenBO token;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cn.iocoder.mall.user.api.dto.user;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
|
||||||
|
@ApiModel("用户认证 DTO")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class UserAuthenticationByMobileCodeDTO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "手机号", required = true, example = "15601691300")
|
||||||
|
@NotEmpty(message = "手机号不能为空")
|
||||||
|
@Length(min = 11, max = 11, message = "账号长度为 11 位")
|
||||||
|
@Pattern(regexp = "^[0-9]+$", message = "手机号必须都是数字")
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "手机验证码", required = true, example = "1024")
|
||||||
|
@NotEmpty(message = "手机验证码不能为空")
|
||||||
|
@Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
|
||||||
|
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
package cn.iocoder.mall.user.biz.convert;
|
package cn.iocoder.mall.user.biz.convert;
|
||||||
|
|
||||||
import cn.iocoder.mall.user.biz.dataobject.UserDO;
|
import cn.iocoder.mall.user.api.bo.user.UserAuthenticationBO;
|
||||||
import cn.iocoder.mall.user.api.bo.UserBO;
|
import cn.iocoder.mall.user.api.bo.UserBO;
|
||||||
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
||||||
|
import cn.iocoder.mall.user.biz.dataobject.UserDO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mappings;
|
import org.mapstruct.Mappings;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
@ -17,10 +18,13 @@ public interface UserConvert {
|
|||||||
@Mappings({})
|
@Mappings({})
|
||||||
UserBO convert(UserDO userDO);
|
UserBO convert(UserDO userDO);
|
||||||
|
|
||||||
|
@Mappings({})
|
||||||
|
UserAuthenticationBO convert2(UserDO userDO);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
UserDO convert(UserUpdateDTO userUpdateDTO);
|
UserDO convert(UserUpdateDTO userUpdateDTO);
|
||||||
|
|
||||||
@Mappings({})
|
@Mappings({})
|
||||||
List<UserBO> convert(List<UserDO> userDOs);
|
List<UserBO> convert(List<UserDO> userDOs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
package cn.iocoder.mall.user.biz.dao;
|
package cn.iocoder.mall.user.biz.dao;
|
||||||
|
|
||||||
import cn.iocoder.mall.user.biz.dataobject.MobileCodeDO;
|
import cn.iocoder.mall.user.biz.dataobject.MobileCodeDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository // 实际不加也没问entity,就是不想 IDEA 那看到有个报错
|
@Repository // 实际不加也没问entity,就是不想 IDEA 那看到有个报错
|
||||||
public interface MobileCodeMapper {
|
public interface MobileCodeMapper extends BaseMapper<MobileCodeDO> {
|
||||||
|
|
||||||
void insert(MobileCodeDO entity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新手机验证码
|
|
||||||
*
|
|
||||||
* @param entity 更新信息
|
|
||||||
*/
|
|
||||||
void update(MobileCodeDO entity);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得手机号的最后一个手机验证码
|
* 获得手机号的最后一个手机验证码
|
||||||
@ -21,6 +14,12 @@ public interface MobileCodeMapper {
|
|||||||
* @param mobile 手机号
|
* @param mobile 手机号
|
||||||
* @return 手机验证码
|
* @return 手机验证码
|
||||||
*/
|
*/
|
||||||
MobileCodeDO selectLast1ByMobile(String mobile);
|
default MobileCodeDO selectLast1ByMobile(String mobile) {
|
||||||
|
QueryWrapper<MobileCodeDO> query = new QueryWrapper<MobileCodeDO>()
|
||||||
|
.eq("mobile", mobile)
|
||||||
|
.orderByDesc("id")
|
||||||
|
.last("limit 1");
|
||||||
|
return selectOne(query);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package cn.iocoder.mall.user.biz.dataobject;
|
package cn.iocoder.mall.user.biz.dataobject;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
// TODO 优化,IP
|
// TODO 优化,IP
|
||||||
|
@TableName("mobile_code")
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class MobileCodeDO {
|
public class MobileCodeDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编号
|
* 编号
|
||||||
@ -34,10 +37,6 @@ public class MobileCodeDO {
|
|||||||
* 注册的用户编号
|
* 注册的用户编号
|
||||||
*/
|
*/
|
||||||
private Integer usedUserId;
|
private Integer usedUserId;
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
/**
|
||||||
* 使用时间
|
* 使用时间
|
||||||
*/
|
*/
|
||||||
|
@ -50,21 +50,21 @@ public class MobileCodeServiceImpl implements MobileCodeService {
|
|||||||
*/
|
*/
|
||||||
public MobileCodeDO validLastMobileCode(String mobile, String code) {
|
public MobileCodeDO validLastMobileCode(String mobile, String code) {
|
||||||
// TODO: 2019-04-09 Sin 暂时先忽略掉验证码校验
|
// TODO: 2019-04-09 Sin 暂时先忽略掉验证码校验
|
||||||
return new MobileCodeDO().setCode(code).setCreateTime(new Date()).setId(1);
|
// return new MobileCodeDO().setCode(code).setCreateTime(new Date()).setId(1);
|
||||||
// MobileCodeDO mobileCodePO = mobileCodeMapper.selectLast1ByMobile(mobile);
|
MobileCodeDO mobileCodePO = mobileCodeMapper.selectLast1ByMobile(mobile);
|
||||||
// if (mobileCodePO == null) { // 若验证码不存在,抛出异常
|
if (mobileCodePO == null) { // 若验证码不存在,抛出异常
|
||||||
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_NOT_FOUND.getCode());
|
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_NOT_FOUND.getCode());
|
||||||
// }
|
}
|
||||||
// if (System.currentTimeMillis() - mobileCodePO.getCreateTime().getTime() >= codeExpireTimes) { // 验证码已过期
|
if (System.currentTimeMillis() - mobileCodePO.getCreateTime().getTime() >= codeExpireTimes) { // 验证码已过期
|
||||||
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_EXPIRED.getCode());
|
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_EXPIRED.getCode());
|
||||||
// }
|
}
|
||||||
// if (mobileCodePO.getUsed()) { // 验证码已使用
|
if (mobileCodePO.getUsed()) { // 验证码已使用
|
||||||
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_USED.getCode());
|
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_USED.getCode());
|
||||||
// }
|
}
|
||||||
// if (!mobileCodePO.getCode().equals(code)) {
|
if (!mobileCodePO.getCode().equals(code)) {
|
||||||
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_NOT_CORRECT.getCode());
|
throw ServiceExceptionUtil.exception(UserErrorCodeEnum.MOBILE_CODE_NOT_CORRECT.getCode());
|
||||||
// }
|
}
|
||||||
// return mobileCodePO;
|
return mobileCodePO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,7 +75,7 @@ public class MobileCodeServiceImpl implements MobileCodeService {
|
|||||||
*/
|
*/
|
||||||
public void useMobileCode(Integer id, Integer userId) {
|
public void useMobileCode(Integer id, Integer userId) {
|
||||||
MobileCodeDO update = new MobileCodeDO().setId(id).setUsed(true).setUsedUserId(userId).setUsedTime(new Date());
|
MobileCodeDO update = new MobileCodeDO().setId(id).setUsed(true).setUsedUserId(userId).setUsedTime(new Date());
|
||||||
mobileCodeMapper.update(update);
|
mobileCodeMapper.updateById(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿,后面要返回有效时间
|
// TODO 芋艿,后面要返回有效时间
|
||||||
@ -99,7 +99,8 @@ public class MobileCodeServiceImpl implements MobileCodeService {
|
|||||||
MobileCodeDO newMobileCodePO = new MobileCodeDO().setMobile(mobile)
|
MobileCodeDO newMobileCodePO = new MobileCodeDO().setMobile(mobile)
|
||||||
.setCode("9999") // TODO 芋艿,随机 4 位验证码 or 6 位验证码
|
.setCode("9999") // TODO 芋艿,随机 4 位验证码 or 6 位验证码
|
||||||
.setTodayIndex(lastMobileCodePO != null ? lastMobileCodePO.getTodayIndex() : 1)
|
.setTodayIndex(lastMobileCodePO != null ? lastMobileCodePO.getTodayIndex() : 1)
|
||||||
.setUsed(false).setCreateTime(new Date());
|
.setUsed(false);
|
||||||
|
newMobileCodePO.setCreateTime(new Date());
|
||||||
mobileCodeMapper.insert(newMobileCodePO);
|
mobileCodeMapper.insert(newMobileCodePO);
|
||||||
// TODO 发送验证码短信
|
// TODO 发送验证码短信
|
||||||
}
|
}
|
||||||
|
@ -49,27 +49,6 @@ public class OAuth2ServiceImpl implements OAuth2Service {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
|
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public OAuth2AccessTokenBO getAccessToken(String mobile, String code) {
|
|
||||||
// 校验传入的 mobile 和 code 是否合法
|
|
||||||
MobileCodeDO mobileCodeDO = mobileCodeService.validLastMobileCode(mobile, code);
|
|
||||||
// 获取用户
|
|
||||||
UserDO userDO = userService.getUser(mobile);
|
|
||||||
if (userDO == null) { // 用户不存在,则进行创建用户
|
|
||||||
userDO = userService.createUser(mobile);
|
|
||||||
Assert.notNull(userDO, "创建用户必然成功");
|
|
||||||
}
|
|
||||||
// 创建刷新令牌
|
|
||||||
OAuth2RefreshTokenDO oauth2RefreshTokenDO = createOAuth2RefreshToken(userDO.getId());
|
|
||||||
// 创建访问令牌
|
|
||||||
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(userDO.getId(), oauth2RefreshTokenDO.getId());
|
|
||||||
// 标记已使用
|
|
||||||
mobileCodeService.useMobileCode(mobileCodeDO.getId(), userDO.getId());
|
|
||||||
// 转换返回
|
|
||||||
return OAuth2Convert.INSTANCE.convertToAccessTokenWithExpiresIn(oauth2AccessTokenDO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuth2AuthenticationBO checkToken(String accessToken) throws ServiceException {
|
public OAuth2AuthenticationBO checkToken(String accessToken) throws ServiceException {
|
||||||
OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByTokenId(accessToken);
|
OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByTokenId(accessToken);
|
||||||
|
@ -3,20 +3,28 @@ package cn.iocoder.mall.user.biz.service;
|
|||||||
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
import cn.iocoder.common.framework.constant.CommonStatusEnum;
|
||||||
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
|
||||||
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
|
||||||
|
import cn.iocoder.common.framework.constant.UserTypeEnum;
|
||||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.common.framework.util.ValidationUtil;
|
import cn.iocoder.common.framework.util.ValidationUtil;
|
||||||
|
import cn.iocoder.mall.admin.api.OAuth2Service;
|
||||||
|
import cn.iocoder.mall.admin.api.bo.oauth2.OAuth2AccessTokenBO;
|
||||||
|
import cn.iocoder.mall.admin.api.dto.oauth2.OAuth2CreateTokenDTO;
|
||||||
import cn.iocoder.mall.user.api.UserService;
|
import cn.iocoder.mall.user.api.UserService;
|
||||||
|
import cn.iocoder.mall.user.api.bo.user.UserAuthenticationBO;
|
||||||
import cn.iocoder.mall.user.api.bo.UserBO;
|
import cn.iocoder.mall.user.api.bo.UserBO;
|
||||||
import cn.iocoder.mall.user.api.bo.UserPageBO;
|
import cn.iocoder.mall.user.api.bo.UserPageBO;
|
||||||
import cn.iocoder.mall.user.api.constant.UserConstants;
|
import cn.iocoder.mall.user.api.constant.UserConstants;
|
||||||
import cn.iocoder.mall.user.api.constant.UserErrorCodeEnum;
|
import cn.iocoder.mall.user.api.constant.UserErrorCodeEnum;
|
||||||
import cn.iocoder.mall.user.api.dto.UserPageDTO;
|
import cn.iocoder.mall.user.api.dto.UserPageDTO;
|
||||||
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
import cn.iocoder.mall.user.api.dto.UserUpdateDTO;
|
||||||
|
import cn.iocoder.mall.user.api.dto.user.UserAuthenticationByMobileCodeDTO;
|
||||||
import cn.iocoder.mall.user.biz.convert.UserConvert;
|
import cn.iocoder.mall.user.biz.convert.UserConvert;
|
||||||
import cn.iocoder.mall.user.biz.dao.UserMapper;
|
import cn.iocoder.mall.user.biz.dao.UserMapper;
|
||||||
import cn.iocoder.mall.user.biz.dao.UserRegisterMapper;
|
import cn.iocoder.mall.user.biz.dao.UserRegisterMapper;
|
||||||
|
import cn.iocoder.mall.user.biz.dataobject.MobileCodeDO;
|
||||||
import cn.iocoder.mall.user.biz.dataobject.UserDO;
|
import cn.iocoder.mall.user.biz.dataobject.UserDO;
|
||||||
import cn.iocoder.mall.user.biz.dataobject.UserRegisterDO;
|
import cn.iocoder.mall.user.biz.dataobject.UserRegisterDO;
|
||||||
|
import org.apache.dubbo.config.annotation.Reference;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -35,7 +43,10 @@ public class UserServiceImpl implements UserService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserRegisterMapper userRegisterMapper;
|
private UserRegisterMapper userRegisterMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private OAuth2ServiceImpl oAuth2Service;
|
private MobileCodeServiceImpl mobileCodeService;
|
||||||
|
|
||||||
|
@Reference(validation = "true", version = "${dubbo.consumer.OAuth2Service.version}")
|
||||||
|
private OAuth2Service oAuth2Service;
|
||||||
|
|
||||||
public UserDO getUser(String mobile) {
|
public UserDO getUser(String mobile) {
|
||||||
return userMapper.selectByMobile(mobile);
|
return userMapper.selectByMobile(mobile);
|
||||||
@ -67,6 +78,36 @@ public class UserServiceImpl implements UserService {
|
|||||||
userRegisterMapper.insert(userRegisterDO);
|
userRegisterMapper.insert(userRegisterDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public UserAuthenticationBO authenticationByMobileCode(UserAuthenticationByMobileCodeDTO userAuthenticationByMobileCodeDTO) {
|
||||||
|
String mobile = userAuthenticationByMobileCodeDTO.getMobile();
|
||||||
|
String code = userAuthenticationByMobileCodeDTO.getCode();
|
||||||
|
// 校验手机格式
|
||||||
|
if (!ValidationUtil.isMobile(mobile)) {
|
||||||
|
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "手机格式不正确"); // TODO 有点搓
|
||||||
|
}
|
||||||
|
// 校验验证码是否正确
|
||||||
|
MobileCodeDO mobileCodeDO = mobileCodeService.validLastMobileCode(mobile, code);
|
||||||
|
// 获得用户
|
||||||
|
UserDO user = userMapper.selectByMobile(mobile);
|
||||||
|
if (user == null) { // 用户不存在,则进行创建
|
||||||
|
user = new UserDO().setMobile(mobile).setStatus(UserConstants.STATUS_ENABLE);
|
||||||
|
user.setCreateTime(new Date());
|
||||||
|
user.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
|
userMapper.insert(user);
|
||||||
|
// 插入注册信息 TODO 芋艿 后续完善,记录 ip、ua 等等
|
||||||
|
createUserRegister(user);
|
||||||
|
}
|
||||||
|
// 更新验证码已使用
|
||||||
|
mobileCodeService.useMobileCode(mobileCodeDO.getId(), user.getId());
|
||||||
|
// 创建 accessToken
|
||||||
|
OAuth2AccessTokenBO accessTokenBO = oAuth2Service.createToken(new OAuth2CreateTokenDTO().setUserId(user.getId())
|
||||||
|
.setUserType(UserTypeEnum.USER.getValue()));
|
||||||
|
// 转换返回
|
||||||
|
return UserConvert.INSTANCE.convert2(user).setToken(accessTokenBO);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserPageBO getUserPage(UserPageDTO userPageDTO) {
|
public UserPageBO getUserPage(UserPageDTO userPageDTO) {
|
||||||
UserPageBO userPageBO = new UserPageBO();
|
UserPageBO userPageBO = new UserPageBO();
|
||||||
|
@ -6,19 +6,17 @@ spring:
|
|||||||
username: root
|
username: root
|
||||||
password: ${MALL_MYSQL_PASSWORD}
|
password: ${MALL_MYSQL_PASSWORD}
|
||||||
|
|
||||||
# mybatis
|
|
||||||
#mybatis:
|
|
||||||
# config-location: classpath:mybatis-config.xml
|
|
||||||
# mapper-locations: classpath:mapper/*.xml
|
|
||||||
# type-aliases-package: cn.iocoder.mall.user.biz.dataobject
|
|
||||||
|
|
||||||
# mybatis-plus
|
# mybatis-plus
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
configuration:
|
configuration:
|
||||||
mapUnderscoreToCamelCase: true # 虽然默认为 true ,但是还是显示去指定下。
|
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||||
|
global-config:
|
||||||
|
db-config:
|
||||||
|
id-type: auto
|
||||||
|
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||||
|
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||||
mapperLocations: classpath*:mapper/*.xml
|
mapperLocations: classpath*:mapper/*.xml
|
||||||
typeAliasesPackage: cn.iocoder.mall.user.biz.dataobject
|
typeAliasesPackage: cn.iocoder.mall.user.biz.dataobject
|
||||||
config-location: classpath:mybatis-config.xml
|
|
||||||
|
|
||||||
# dubbo
|
# dubbo
|
||||||
dubbo:
|
dubbo:
|
||||||
@ -43,3 +41,6 @@ dubbo:
|
|||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
UserService:
|
UserService:
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
consumer:
|
||||||
|
OAuth2Service:
|
||||||
|
version: 1.0.0
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.iocoder.mall.user.biz.dao.MobileCodeMapper">
|
|
||||||
|
|
||||||
<insert id="insert" parameterType="MobileCodeDO">
|
|
||||||
INSERT INTO mobile_code (
|
|
||||||
id, mobile, code, today_index, used,
|
|
||||||
userd_user_id, used_time, create_time
|
|
||||||
) VALUES (
|
|
||||||
#{id}, #{mobile}, #{code}, #{todayIndex}, #{used},
|
|
||||||
#{usedUserId}, #{usedTime}, #{createTime}
|
|
||||||
)
|
|
||||||
</insert>
|
|
||||||
|
|
||||||
<update id="update" parameterType="MobileCodeDO">
|
|
||||||
UPDATE mobile_code
|
|
||||||
<set>
|
|
||||||
<if test="used != null"> used = #{used}, </if>
|
|
||||||
<if test="usedUserId != null"> userd_user_id = #{usedUserId}, </if>
|
|
||||||
<if test="usedTime != null"> used_time = #{usedTime}, </if>
|
|
||||||
</set>
|
|
||||||
WHERE id = #{id}
|
|
||||||
</update>
|
|
||||||
|
|
||||||
<select id="selectLast1ByMobile" parameterType="String" resultType="MobileCodeDO">
|
|
||||||
SELECT
|
|
||||||
id, mobile, code, today_index, used,
|
|
||||||
userd_user_id, used_time, create_time
|
|
||||||
FROM mobile_code
|
|
||||||
WHERE mobile = #{mobile}
|
|
||||||
ORDER BY id DESC
|
|
||||||
LIMIT 1
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</mapper>
|
|
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
|
|
||||||
<configuration>
|
|
||||||
|
|
||||||
<settings>
|
|
||||||
<!-- 使用驼峰命名法转换字段。 -->
|
|
||||||
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
|
||||||
</settings>
|
|
||||||
|
|
||||||
<typeAliases>
|
|
||||||
<typeAlias alias="Integer" type="java.lang.Integer"/>
|
|
||||||
<typeAlias alias="Long" type="java.lang.Long"/>
|
|
||||||
<typeAlias alias="HashMap" type="java.util.HashMap"/>
|
|
||||||
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
|
|
||||||
<typeAlias alias="ArrayList" type="java.util.ArrayList"/>
|
|
||||||
<typeAlias alias="LinkedList" type="java.util.LinkedList"/>
|
|
||||||
</typeAliases>
|
|
||||||
|
|
||||||
</configuration>
|
|
Loading…
Reference in New Issue
Block a user