mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-14 11:05:06 +08:00
多模块重构 4:system 模块的调整,实现 social API~~
This commit is contained in:
@ -21,6 +21,20 @@
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- 用户信息 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -0,0 +1,56 @@
|
||||
package cn.iocoder.yudao.module.system.api.auth;
|
||||
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 在线用户 Session API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface UserSessionApi {
|
||||
|
||||
/**
|
||||
* 创建在线用户 Session
|
||||
*
|
||||
* @param loginUser 登录用户
|
||||
* @param userIp 用户 IP
|
||||
* @param userAgent 用户 UA
|
||||
* @return Session 编号
|
||||
*/
|
||||
String createUserSession(@NotNull(message = "登录用户不能为空") LoginUser loginUser, String userIp, String userAgent);
|
||||
|
||||
/**
|
||||
* 刷新在线用户 Session 的更新时间
|
||||
*
|
||||
* @param sessionId Session 编号
|
||||
* @param loginUser 登录用户
|
||||
*/
|
||||
void refreshUserSession(@NotEmpty(message = "Session编号不能为空") String sessionId,
|
||||
@NotNull(message = "登录用户不能为空") LoginUser loginUser);
|
||||
|
||||
/**
|
||||
* 删除在线用户 Session
|
||||
*
|
||||
* @param sessionId Session 编号
|
||||
*/
|
||||
void deleteUserSession(String sessionId);
|
||||
|
||||
/**
|
||||
* 获得 Session 编号对应的在线用户
|
||||
*
|
||||
* @param sessionId Session 编号
|
||||
* @return 在线用户
|
||||
*/
|
||||
LoginUser getLoginUser(String sessionId);
|
||||
|
||||
/**
|
||||
* 获得 Session 超时时间,单位:毫秒
|
||||
*
|
||||
* @return 超时时间
|
||||
*/
|
||||
Long getSessionTimeoutMillis();
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.system.api.logger;
|
||||
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 登录日志的 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface LoginLogApi {
|
||||
|
||||
/**
|
||||
* 创建登录日志
|
||||
*
|
||||
* @param reqDTO 日志信息
|
||||
*/
|
||||
void createLoginLog(@Valid LoginLogCreateReqDTO reqDTO);
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package cn.iocoder.yudao.module.system.api.logger.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* 登录日志创建 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class LoginLogCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
@NotNull(message = "日志类型不能为空")
|
||||
private Integer logType;
|
||||
/**
|
||||
* 链路追踪编号
|
||||
*/
|
||||
@NotEmpty(message = "链路追踪编号不能为空")
|
||||
private String traceId;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
private Integer userType;
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
@NotBlank(message = "用户账号不能为空")
|
||||
@Size(max = 30, message = "用户账号长度不能超过30个字符")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 登录结果
|
||||
*/
|
||||
@NotNull(message = "登录结果不能为空")
|
||||
private Integer result;
|
||||
|
||||
/**
|
||||
* 用户 IP
|
||||
*/
|
||||
@NotEmpty(message = "用户 IP 不能为空")
|
||||
private String userIp;
|
||||
/**
|
||||
* 浏览器 UserAgent
|
||||
*/
|
||||
@NotEmpty(message = "浏览器 UserAgent 不能为空")
|
||||
private String userAgent;
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* System API 包,定义暴露给其它模块的 API
|
||||
*/
|
||||
package cn.iocoder.yudao.module.system.api;
|
@ -0,0 +1,64 @@
|
||||
package cn.iocoder.yudao.module.system.api.social;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 社交用户的 API 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface SocialUserApi {
|
||||
|
||||
/**
|
||||
* 获得社交平台的授权 URL
|
||||
*
|
||||
* @param type 社交平台的类型 {@link SocialTypeEnum}
|
||||
* @param redirectUri 重定向 URL
|
||||
* @return 社交平台的授权 URL
|
||||
*/
|
||||
String getAuthorizeUrl(Integer type, String redirectUri);
|
||||
|
||||
/**
|
||||
* 绑定社交用户
|
||||
*
|
||||
* @param reqDTO 绑定信息
|
||||
*/
|
||||
void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 取消绑定社交用户
|
||||
*
|
||||
* @param reqDTO 解绑
|
||||
*/
|
||||
void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO);
|
||||
|
||||
/**
|
||||
* 校验社交用户的认证信息是否正确
|
||||
* 如果校验不通过,则抛出 {@link ServiceException} 业务异常
|
||||
*
|
||||
* @param type 社交平台的类型
|
||||
* @param code 授权码
|
||||
* @param state state
|
||||
*/
|
||||
void checkSocialUser(Integer type, String code, String state);
|
||||
|
||||
/**
|
||||
* 获得社交用户的绑定用户编号
|
||||
* 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号!
|
||||
* 该方法会执行和 {@link #checkSocialUser(Integer, String, String)} 一样的逻辑。
|
||||
* 所以在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
|
||||
*
|
||||
* @param userType 用户类型
|
||||
* @param type 社交平台的类型
|
||||
* @param code 授权码
|
||||
* @param state state
|
||||
* @return 绑定用户编号
|
||||
*/
|
||||
Long getBindUserId(Integer userType, Integer type, String code, String state);
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package cn.iocoder.yudao.module.system.api.social.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 取消绑定社交用户 Request DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SocialUserBindReqDTO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
@InEnum(UserTypeEnum.class)
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 社交平台的类型
|
||||
*/
|
||||
@InEnum(SocialTypeEnum.class)
|
||||
@NotNull(message = "社交平台的类型不能为空")
|
||||
private Integer type;
|
||||
/**
|
||||
* 授权码
|
||||
*/
|
||||
@NotEmpty(message = "授权码不能为空")
|
||||
private String code;
|
||||
/**
|
||||
* state
|
||||
*/
|
||||
@NotEmpty(message = "state 不能为空")
|
||||
private String state;
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package cn.iocoder.yudao.module.system.api.social.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 社交绑定 Request DTO,使用 code 授权码
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class SocialUserUnbindReqDTO {
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
@InEnum(UserTypeEnum.class)
|
||||
@NotNull(message = "用户类型不能为空")
|
||||
private Integer userType;
|
||||
|
||||
/**
|
||||
* 社交平台的类型
|
||||
*/
|
||||
@InEnum(SocialTypeEnum.class)
|
||||
@NotNull(message = "社交平台的类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 社交平台的 unionId
|
||||
*/
|
||||
@NotEmpty(message = "社交平台的 unionId 不能为空")
|
||||
private String unionId;
|
||||
|
||||
}
|
@ -87,12 +87,31 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(1002011000, "短信模板不存在");
|
||||
ErrorCode SMS_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1002011001, "已经存在编码为【{}】的短信模板");
|
||||
|
||||
// ========== 租户模块 1002012000 ==========
|
||||
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1002012000, "租户不存在");
|
||||
// ========== 短信发送 1002012000 ==========
|
||||
ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002012000, "手机号不存在");
|
||||
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1002012001, "模板参数({})缺失");
|
||||
ErrorCode SMS_SEND_TEMPLATE_NOT_EXISTS = new ErrorCode(1002012002, "短信模板不存在");
|
||||
|
||||
// ========== 错误码模块 1002013000 ==========
|
||||
ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002013000, "错误码不存在");
|
||||
ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002013001, "已经存在编码为【{}】的错误码");
|
||||
// ========== 短信验证码 1002013000 ==========
|
||||
ErrorCode SMS_CODE_NOT_FOUND = new ErrorCode(1002013000, "验证码不存在");
|
||||
ErrorCode SMS_CODE_EXPIRED = new ErrorCode(1002013001, "验证码已过期");
|
||||
ErrorCode SMS_CODE_USED = new ErrorCode(1002013002, "验证码已使用");
|
||||
ErrorCode SMS_CODE_NOT_CORRECT = new ErrorCode(1002013004, "验证码不正确");
|
||||
ErrorCode SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY = new ErrorCode(1002013005, "超过每日短信发送数量");
|
||||
ErrorCode SMS_CODE_SEND_TOO_FAST = new ErrorCode(1002013006, "短信发送过于频率");
|
||||
ErrorCode SMS_CODE_IS_EXISTS = new ErrorCode(1002013007, "手机号已被使用");
|
||||
ErrorCode SMS_CODE_IS_UNUSED = new ErrorCode(1002013008, "验证码未被使用");
|
||||
|
||||
// ========== 租户模块 1002014000 ==========
|
||||
ErrorCode TENANT_NOT_EXISTS = new ErrorCode(1002014000, "租户不存在");
|
||||
|
||||
// ========== 错误码模块 1002015000 ==========
|
||||
ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1002015000, "错误码不存在");
|
||||
ErrorCode ERROR_CODE_DUPLICATE = new ErrorCode(1002015001, "已经存在编码为【{}】的错误码");
|
||||
|
||||
// ========== 社交用户 1002015000 ==========
|
||||
ErrorCode SOCIAL_USER_AUTH_FAILURE = new ErrorCode(1002015000, "社交授权失败,原因是:{}");
|
||||
ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1002015001, "社交解绑失败,非当前用户绑定");
|
||||
ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1002015001, "社交授权失败,找不到对应的用户");
|
||||
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.enums;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* System 错误码枚举类
|
||||
*
|
||||
* system 系统,使用 1-006-000-000 段
|
||||
*/
|
||||
public interface SysErrorCodeConstants {
|
||||
|
||||
// ========== 短信发送 1006000000 ==========
|
||||
ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1006000000, "手机号不存在");
|
||||
ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1006000001, "模板参数({})缺失");
|
||||
ErrorCode SMS_SEND_TEMPLATE_NOT_EXISTS = new ErrorCode(1006000000, "短信模板不存在");
|
||||
|
||||
// ========== 社交模块 1006002000 ==========
|
||||
ErrorCode SOCIAL_AUTH_FAILURE = new ErrorCode(1006002000, "社交授权失败,原因是:{}");
|
||||
ErrorCode SOCIAL_UNBIND_NOT_SELF = new ErrorCode(1006002001, "社交解绑失败,非当前用户绑定");
|
||||
|
||||
// ========== 用户模块 1006003000 ==========
|
||||
ErrorCode USER_NOT_EXISTS = new ErrorCode(1006003000, "用户不存在");
|
||||
ErrorCode USER_IS_DISABLE = new ErrorCode(1006003001, "名字为【{}】的用户已被禁用");
|
||||
|
||||
// ========== 部门模块 1006004000 ==========
|
||||
ErrorCode DEPT_NOT_FOUND = new ErrorCode(1006004000, "当前部门不存在");
|
||||
ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1006004001, "部门不处于开启状态,不允许选择");
|
||||
|
||||
// ========== 角色模块 1006005000 ==========
|
||||
ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1006005000, "角色不存在");
|
||||
ErrorCode ROLE_IS_DISABLE = new ErrorCode(1006005001, "名字为【{}】的角色已被禁用");
|
||||
|
||||
// ========== 岗位模块 1006007000 ==========
|
||||
ErrorCode POST_NOT_FOUND = new ErrorCode(1006007000, "当前岗位不存在");
|
||||
ErrorCode POST_NOT_ENABLE = new ErrorCode(1006007001, "岗位({}) 不处于开启状态,不允许选择");
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.system.enums.logger;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录日志的类型枚举
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum LoginLogTypeEnum {
|
||||
|
||||
LOGIN_USERNAME(100), // 使用账号登录
|
||||
LOGIN_SOCIAL(101), // 使用社交登录
|
||||
LOGIN_MOCK(102), // 使用 Mock 登录
|
||||
LOGIN_MOBILE(103), // 使用手机登陆
|
||||
LOGIN_SMS(104), // 使用短信登陆
|
||||
|
||||
LOGOUT_SELF(200), // 自己主动登出
|
||||
LOGOUT_TIMEOUT(201), // 超时登出
|
||||
LOGOUT_DELETE(202), // 强制退出
|
||||
;
|
||||
|
||||
/**
|
||||
* 日志类型
|
||||
*/
|
||||
private final Integer type;
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.system.enums.logger;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录结果的枚举类
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum LoginResultEnum {
|
||||
|
||||
SUCCESS(0), // 成功
|
||||
BAD_CREDENTIALS(10), // 账号或密码不正确
|
||||
USER_DISABLED(20), // 用户被禁用
|
||||
CAPTCHA_NOT_FOUND(30), // 图片验证码不存在
|
||||
CAPTCHA_CODE_ERROR(31), // 图片验证码不正确
|
||||
|
||||
UNKNOWN_ERROR(100), // 未知异常
|
||||
;
|
||||
|
||||
/**
|
||||
* 结果
|
||||
*/
|
||||
private final Integer result;
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package cn.iocoder.yudao.module.system.enums.sms;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户短信验证码发送场景的枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum SmsSceneEnum implements IntArrayValuable {
|
||||
|
||||
MEMBER_LOGIN(1, "user-sms-login", "会员用户 - 手机号登陆"),
|
||||
MEMBER_UPDATE_MOBILE(2, "user-sms-reset-password", "会员用户 - 修改手机"),
|
||||
MEMBER_FORGET_PASSWORD(3, "user-sms-update-mobile", "会员用户 - 忘记密码");
|
||||
|
||||
// 如果未来希望管理后台支持手机验证码登陆,可以通过添加 ADMIN_MEMBER_LOGIN 枚举
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SmsSceneEnum::getScene).toArray();
|
||||
|
||||
/**
|
||||
* 验证场景的编号
|
||||
*/
|
||||
private final Integer scene;
|
||||
/**
|
||||
* 模版编码
|
||||
*/
|
||||
private final String templateCode;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
public static SmsSceneEnum getCodeByScene(Integer scene) {
|
||||
return ArrayUtil.firstMatch(sceneEnum -> sceneEnum.getScene().equals(scene));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user