@@ -0,0 +1,48 @@
|
||||
package top.crushtj.xiaoyishu.auth.cache;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import top.crushtj.xiaoyishu.auth.domain.entity.UserEntity;
|
||||
import top.crushtj.xiaoyishu.auth.domain.mappers.UserMapper;
|
||||
|
||||
import static top.crushtj.xiaoyishu.auth.constant.RedisKeyConstants.XIAOYI_ID_GENERATOR_KEY;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title CacheLoader
|
||||
* @date 2026/01/20 18:25
|
||||
* @description 初始化缓存
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CacheLoader {
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
/**
|
||||
* 加载用户自增ID缓存
|
||||
*/
|
||||
@PostConstruct
|
||||
public void loadUserCache() {
|
||||
log.info("加载用户自增ID缓存开始...");
|
||||
LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.orderByDesc(UserEntity::getXiaoyishuId);
|
||||
queryWrapper.last("limit 1");
|
||||
UserEntity user = userMapper.selectOne(queryWrapper);
|
||||
if (user != null){
|
||||
redisTemplate.opsForValue().set(XIAOYI_ID_GENERATOR_KEY, user.getXiaoyishuId());
|
||||
}else {
|
||||
redisTemplate.opsForValue().set(XIAOYI_ID_GENERATOR_KEY, 1000000L);
|
||||
}
|
||||
log.info("加载用户自增ID缓存结束...");
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -25,6 +25,11 @@ public class RedisKeyConstants {
|
||||
*/
|
||||
private static final String USER_ROLES_KEY_PREFIX = "user:roles:";
|
||||
|
||||
/**
|
||||
* 小哈书全局 ID 生成器 KEY
|
||||
*/
|
||||
public static final String XIAOYI_ID_GENERATOR_KEY = "xiaoyishu_id_generator";
|
||||
|
||||
/**
|
||||
* 构建验证码 KEY
|
||||
*
|
||||
@@ -38,11 +43,11 @@ public class RedisKeyConstants {
|
||||
/**
|
||||
* 构建用户角色数据 KEY
|
||||
*
|
||||
* @param userId 用户 ID
|
||||
* @param phone 用户手机号
|
||||
* @return 用户角色数据 KEY
|
||||
*/
|
||||
public static String buildUserRolesKey(Long userId) {
|
||||
return USER_ROLES_KEY_PREFIX + userId;
|
||||
public static String buildUserRolesKey(String phone) {
|
||||
return USER_ROLES_KEY_PREFIX + phone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package top.crushtj.xiaoyishu.auth.constant;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title XiaoyiAuthConstants
|
||||
* @date 2026/01/19 19:40
|
||||
* @description 小一书常量
|
||||
*/
|
||||
|
||||
public class XiaoyiAuthConstants {
|
||||
public static final String NICK_NAME_PREFIX = "咿呀_";
|
||||
}
|
||||
+3
-3
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title PermissionEntity
|
||||
* @date 2026-01-18 21:20:36
|
||||
* @date 2026-01-19 19:47:27
|
||||
* @description 权限表(t_permission)表实体类
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.time.LocalDateTime;
|
||||
@TableName("t_permission")
|
||||
public class PermissionEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -18586083527537804L;
|
||||
private static final long serialVersionUID = -30618877661010662L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
@@ -99,6 +99,6 @@ public class PermissionEntity implements Serializable {
|
||||
* 逻辑删除(0:未删除 1:已删除)
|
||||
*/
|
||||
@TableField("IS_DELETED")
|
||||
private Integer isDeleted;
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RoleEntity
|
||||
* @date 2026-01-18 21:20:51
|
||||
* @date 2026-01-19 19:48:23
|
||||
* @description 角色表(t_role)表实体类
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.time.LocalDateTime;
|
||||
@TableName("t_role")
|
||||
public class RoleEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 294965117543247928L;
|
||||
private static final long serialVersionUID = -77681371692201000L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
@@ -81,6 +81,6 @@ public class RoleEntity implements Serializable {
|
||||
* 逻辑删除(0:未删除 1:已删除)
|
||||
*/
|
||||
@TableField("IS_DELETED")
|
||||
private Integer isDeleted;
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RolePermissionRelEntity
|
||||
* @date 2026-01-18 21:21:12
|
||||
* @date 2026-01-19 19:48:31
|
||||
* @description 用户权限表(t_role_permission_rel)表实体类
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.time.LocalDateTime;
|
||||
@TableName("t_role_permission_rel")
|
||||
public class RolePermissionRelEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 308157477991435934L;
|
||||
private static final long serialVersionUID = 345004944667469434L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
@@ -63,6 +63,6 @@ public class RolePermissionRelEntity implements Serializable {
|
||||
* 逻辑删除(0:未删除 1:已删除)
|
||||
*/
|
||||
@TableField("IS_DELETED")
|
||||
private Integer isDeleted;
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import java.time.LocalDateTime;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title UserEntity
|
||||
* @date 2026/01/18 19:33:00
|
||||
* @description 用户表
|
||||
* @date 2026-01-19 19:49:50
|
||||
* @description 用户表(t_user)表实体类
|
||||
*/
|
||||
|
||||
@Data
|
||||
@@ -28,7 +28,7 @@ import java.time.LocalDateTime;
|
||||
@TableName("t_user")
|
||||
public class UserEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -31680834394879938L;
|
||||
private static final long serialVersionUID = -47473970233354078L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
@@ -112,6 +112,6 @@ public class UserEntity implements Serializable {
|
||||
* 逻辑删除(0:未删除 1:已删除)
|
||||
*/
|
||||
@TableField("IS_DELETED")
|
||||
private Integer isDeleted;
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title UserRoleRelEntity
|
||||
* @date 2026-01-18 21:21:25
|
||||
* @date 2026-01-19 19:49:59
|
||||
* @description 用户角色表(t_user_role_rel)表实体类
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.time.LocalDateTime;
|
||||
@TableName("t_user_role_rel")
|
||||
public class UserRoleRelEntity implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 788758889499348222L;
|
||||
private static final long serialVersionUID = -77498437697772085L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
@@ -63,6 +63,6 @@ public class UserRoleRelEntity implements Serializable {
|
||||
* 逻辑删除(0:未删除 1:已删除)
|
||||
*/
|
||||
@TableField("IS_DELETED")
|
||||
private Integer isDeleted;
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title PermissionMapper
|
||||
* @date 2026-01-18 21:20:37
|
||||
* @date 2026-01-19 19:47:28
|
||||
* @description 权限表(t_permission)表数据库访问层
|
||||
*/
|
||||
public interface PermissionMapper extends BaseMapper<PermissionEntity> {
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RoleMapper
|
||||
* @date 2026-01-18 21:20:51
|
||||
* @date 2026-01-19 19:48:24
|
||||
* @description 角色表(t_role)表数据库访问层
|
||||
*/
|
||||
public interface RoleMapper extends BaseMapper<RoleEntity> {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title RolePermissionRelMapper
|
||||
* @date 2026-01-18 21:21:12
|
||||
* @date 2026-01-19 19:48:32
|
||||
* @description 用户权限表(t_role_permission_rel)表数据库访问层
|
||||
*/
|
||||
public interface RolePermissionRelMapper extends BaseMapper<RolePermissionRelEntity> {
|
||||
|
||||
@@ -7,12 +7,17 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
/**
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title User
|
||||
* @date 2026/01/18 19:33:00
|
||||
* @title UserMapper
|
||||
* @date 2026-01-19 19:49:51
|
||||
* @description 用户表(t_user)表数据库访问层
|
||||
*/
|
||||
public interface UserMapper extends BaseMapper<UserEntity> {
|
||||
|
||||
/**
|
||||
* 根据手机号查询用户
|
||||
* @param phone 手机号
|
||||
* @return 用户信息
|
||||
*/
|
||||
UserEntity selectByPhone(@Param("phone") String phone);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
* @title UserRoleRelMapper
|
||||
* @date 2026-01-18 21:21:25
|
||||
* @date 2026-01-19 19:50:00
|
||||
* @description 用户角色表(t_user_role_rel)表数据库访问层
|
||||
*/
|
||||
public interface UserRoleRelMapper extends BaseMapper<UserRoleRelEntity> {
|
||||
|
||||
+15
-15
@@ -1,20 +1,20 @@
|
||||
<?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 = "top.crushtj.xiaoyishu.auth.domain.mappers.PermissionMapper">
|
||||
<mapper namespace="top.crushtj.xiaoyishu.auth.domain.mappers.PermissionMapper">
|
||||
|
||||
<resultMap type = "top.crushtj.xiaoyishu.auth.domain.entity.PermissionEntity" id = "PermissionMap">
|
||||
<result property = "id" column = "id" jdbcType = "INTEGER"/>
|
||||
<result property = "parentId" column = "parent_id" jdbcType = "INTEGER"/>
|
||||
<result property = "name" column = "name" jdbcType = "VARCHAR"/>
|
||||
<result property = "type" column = "type" jdbcType = "INTEGER"/>
|
||||
<result property = "menuUrl" column = "menu_url" jdbcType = "VARCHAR"/>
|
||||
<result property = "menuIcon" column = "menu_icon" jdbcType = "VARCHAR"/>
|
||||
<result property = "sort" column = "sort" jdbcType = "INTEGER"/>
|
||||
<result property = "permissionKey" column = "permission_key" jdbcType = "VARCHAR"/>
|
||||
<result property = "status" column = "status" jdbcType = "INTEGER"/>
|
||||
<result property = "createTime" column = "create_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "updateTime" column = "update_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "isDeleted" column = "is_deleted" jdbcType = "INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap type="top.crushtj.xiaoyishu.auth.domain.entity.PermissionEntity" id="PermissionMap">
|
||||
<result property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="parentId" column="parent_id" jdbcType="INTEGER"/>
|
||||
<result property="name" column="name" jdbcType="VARCHAR"/>
|
||||
<result property="type" column="type" jdbcType="INTEGER"/>
|
||||
<result property="menuUrl" column="menu_url" jdbcType="VARCHAR"/>
|
||||
<result property="menuIcon" column="menu_icon" jdbcType="VARCHAR"/>
|
||||
<result property="sort" column="sort" jdbcType="INTEGER"/>
|
||||
<result property="permissionKey" column="permission_key" jdbcType="VARCHAR"/>
|
||||
<result property="status" column="status" jdbcType="INTEGER"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDeleted" column="is_deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
|
||||
+12
-12
@@ -1,17 +1,17 @@
|
||||
<?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 = "top.crushtj.xiaoyishu.auth.domain.mappers.RoleMapper">
|
||||
<mapper namespace="top.crushtj.xiaoyishu.auth.domain.mappers.RoleMapper">
|
||||
|
||||
<resultMap type = "top.crushtj.xiaoyishu.auth.domain.entity.RoleEntity" id = "RoleMap">
|
||||
<result property = "id" column = "id" jdbcType = "INTEGER"/>
|
||||
<result property = "roleName" column = "role_name" jdbcType = "VARCHAR"/>
|
||||
<result property = "roleKey" column = "role_key" jdbcType = "VARCHAR"/>
|
||||
<result property = "status" column = "status" jdbcType = "INTEGER"/>
|
||||
<result property = "sort" column = "sort" jdbcType = "INTEGER"/>
|
||||
<result property = "remark" column = "remark" jdbcType = "VARCHAR"/>
|
||||
<result property = "createTime" column = "create_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "updateTime" column = "update_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "isDeleted" column = "is_deleted" jdbcType = "INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap type="top.crushtj.xiaoyishu.auth.domain.entity.RoleEntity" id="RoleMap">
|
||||
<result property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="roleName" column="role_name" jdbcType="VARCHAR"/>
|
||||
<result property="roleKey" column="role_key" jdbcType="VARCHAR"/>
|
||||
<result property="status" column="status" jdbcType="INTEGER"/>
|
||||
<result property="sort" column="sort" jdbcType="INTEGER"/>
|
||||
<result property="remark" column="remark" jdbcType="VARCHAR"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDeleted" column="is_deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
|
||||
+9
-9
@@ -1,14 +1,14 @@
|
||||
<?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 = "top.crushtj.xiaoyishu.auth.domain.mappers.RolePermissionRelMapper">
|
||||
<mapper namespace="top.crushtj.xiaoyishu.auth.domain.mappers.RolePermissionRelMapper">
|
||||
|
||||
<resultMap type = "top.crushtj.xiaoyishu.auth.domain.entity.RolePermissionRelEntity" id = "RolePermissionRelMap">
|
||||
<result property = "id" column = "id" jdbcType = "INTEGER"/>
|
||||
<result property = "roleId" column = "role_id" jdbcType = "INTEGER"/>
|
||||
<result property = "permissionId" column = "permission_id" jdbcType = "INTEGER"/>
|
||||
<result property = "createTime" column = "create_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "updateTime" column = "update_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "isDeleted" column = "is_deleted" jdbcType = "INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap type="top.crushtj.xiaoyishu.auth.domain.entity.RolePermissionRelEntity" id="RolePermissionRelMap">
|
||||
<result property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="roleId" column="role_id" jdbcType="INTEGER"/>
|
||||
<result property="permissionId" column="permission_id" jdbcType="INTEGER"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDeleted" column="is_deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
|
||||
+18
-18
@@ -1,25 +1,25 @@
|
||||
<?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 = "top.crushtj.xiaoyishu.auth.domain.mappers.UserMapper">
|
||||
<mapper namespace="top.crushtj.xiaoyishu.auth.domain.mappers.UserMapper">
|
||||
|
||||
<resultMap type = "top.crushtj.xiaoyishu.auth.domain.entity.UserEntity" id = "UserMap">
|
||||
<result property = "id" column = "id" jdbcType = "INTEGER"/>
|
||||
<result property = "xiaoyishuId" column = "xiaoyishu_id" jdbcType = "VARCHAR"/>
|
||||
<result property = "password" column = "password" jdbcType = "VARCHAR"/>
|
||||
<result property = "nickname" column = "nickname" jdbcType = "VARCHAR"/>
|
||||
<result property = "avatar" column = "avatar" jdbcType = "VARCHAR"/>
|
||||
<result property = "birthday" column = "birthday" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "backgroundImg" column = "background_img" jdbcType = "VARCHAR"/>
|
||||
<result property = "phone" column = "phone" jdbcType = "VARCHAR"/>
|
||||
<result property = "sex" column = "sex" jdbcType = "INTEGER"/>
|
||||
<result property = "status" column = "status" jdbcType = "INTEGER"/>
|
||||
<result property = "introduction" column = "introduction" jdbcType = "VARCHAR"/>
|
||||
<result property = "createTime" column = "create_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "updateTime" column = "update_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "isDeleted" column = "is_deleted" jdbcType = "INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap type="top.crushtj.xiaoyishu.auth.domain.entity.UserEntity" id="UserMap">
|
||||
<result property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="xiaoyishuId" column="xiaoyishu_id" jdbcType="VARCHAR"/>
|
||||
<result property="password" column="password" jdbcType="VARCHAR"/>
|
||||
<result property="nickname" column="nickname" jdbcType="VARCHAR"/>
|
||||
<result property="avatar" column="avatar" jdbcType="VARCHAR"/>
|
||||
<result property="birthday" column="birthday" jdbcType="TIMESTAMP"/>
|
||||
<result property="backgroundImg" column="background_img" jdbcType="VARCHAR"/>
|
||||
<result property="phone" column="phone" jdbcType="VARCHAR"/>
|
||||
<result property="sex" column="sex" jdbcType="INTEGER"/>
|
||||
<result property="status" column="status" jdbcType="INTEGER"/>
|
||||
<result property="introduction" column="introduction" jdbcType="VARCHAR"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDeleted" column="is_deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
<select id = "selectByPhone" resultType = "top.crushtj.xiaoyishu.auth.domain.entity.UserEntity">
|
||||
SELECT id, password
|
||||
SELECT id, password, xiaoyishu_id
|
||||
FROM t_user
|
||||
WHERE phone = #{phone}
|
||||
</select>
|
||||
|
||||
+9
-9
@@ -1,14 +1,14 @@
|
||||
<?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 = "top.crushtj.xiaoyishu.auth.domain.mappers.UserRoleRelMapper">
|
||||
<mapper namespace="top.crushtj.xiaoyishu.auth.domain.mappers.UserRoleRelMapper">
|
||||
|
||||
<resultMap type = "top.crushtj.xiaoyishu.auth.domain.entity.UserRoleRelEntity" id = "UserRoleRelMap">
|
||||
<result property = "id" column = "id" jdbcType = "INTEGER"/>
|
||||
<result property = "userId" column = "user_id" jdbcType = "INTEGER"/>
|
||||
<result property = "roleId" column = "role_id" jdbcType = "INTEGER"/>
|
||||
<result property = "createTime" column = "create_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "updateTime" column = "update_time" jdbcType = "TIMESTAMP"/>
|
||||
<result property = "isDeleted" column = "is_deleted" jdbcType = "INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap type="top.crushtj.xiaoyishu.auth.domain.entity.UserRoleRelEntity" id="UserRoleRelMap">
|
||||
<result property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="userId" column="user_id" jdbcType="INTEGER"/>
|
||||
<result property="roleId" column="role_id" jdbcType="INTEGER"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDeleted" column="is_deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
|
||||
+66
-3
@@ -1,24 +1,40 @@
|
||||
package top.crushtj.xiaoyishu.auth.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.SaTokenInfo;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import top.crushtj.framework.common.enums.DeleteEnum;
|
||||
import top.crushtj.framework.common.enums.StatusEnum;
|
||||
import top.crushtj.framework.common.exception.BizException;
|
||||
import top.crushtj.framework.common.response.Response;
|
||||
import top.crushtj.framework.common.utils.IdGenerator;
|
||||
import top.crushtj.framework.common.utils.JsonUtils;
|
||||
import top.crushtj.framework.common.utils.MaskUtils;
|
||||
import top.crushtj.xiaoyishu.auth.constant.RedisKeyConstants;
|
||||
import top.crushtj.xiaoyishu.auth.domain.entity.UserEntity;
|
||||
import top.crushtj.xiaoyishu.auth.domain.entity.UserRoleRelEntity;
|
||||
import top.crushtj.xiaoyishu.auth.domain.mappers.UserMapper;
|
||||
import top.crushtj.xiaoyishu.auth.domain.mappers.UserRoleRelMapper;
|
||||
import top.crushtj.xiaoyishu.auth.enums.LoginTypeEnum;
|
||||
import top.crushtj.xiaoyishu.auth.enums.ResponseCodeEnum;
|
||||
import top.crushtj.xiaoyishu.auth.model.vo.user.UserLoginReqVO;
|
||||
import top.crushtj.xiaoyishu.auth.service.UserService;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static top.crushtj.xiaoyishu.auth.constant.RedisKeyConstants.XIAOYI_ID_GENERATOR_KEY;
|
||||
import static top.crushtj.xiaoyishu.auth.constant.RoleConstants.COMMON_USER_ROLE_ID;
|
||||
import static top.crushtj.xiaoyishu.auth.constant.XiaoyiAuthConstants.NICK_NAME_PREFIX;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
* @version V1.0
|
||||
@@ -34,6 +50,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
||||
private UserMapper userMapper;
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Resource
|
||||
private UserRoleRelMapper userRoleRelMapper;
|
||||
|
||||
@Override
|
||||
public Response<String> loginOrRegister(UserLoginReqVO userLoginReqVO) {
|
||||
@@ -58,7 +76,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
||||
// 构建验证码 Redis Key
|
||||
String key = RedisKeyConstants.buildVerificationCodeKey(phone);
|
||||
// 查询存储在 Redis 中该用户的登录验证码
|
||||
String sentCode = (String)redisTemplate.opsForValue().get(key);
|
||||
String sentCode = (String)redisTemplate.opsForValue()
|
||||
.get(key);
|
||||
|
||||
// 判断用户提交的验证码,与 Redis 中的验证码是否一致
|
||||
if (!StringUtils.equals(verificationCode, sentCode)) {
|
||||
@@ -68,12 +87,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
||||
// 通过手机号查询记录
|
||||
UserEntity userEntity = userMapper.selectByPhone(phone);
|
||||
|
||||
log.info("==> 用户是否注册, phone: {}, userId: {}", MaskUtils.maskMobile(phone), userEntity.getId());
|
||||
log.info("==> 用户是否注册, phone: {}, userId: {}", MaskUtils.maskMobile(phone),
|
||||
userEntity == null ? "未注册" : userEntity.getXiaoyishuId());
|
||||
|
||||
// 判断是否注册
|
||||
if (Objects.isNull(userEntity)) {
|
||||
// 若此用户还没有注册,系统自动注册该用户
|
||||
// todo 自动注册用户逻辑
|
||||
userId = registerUser(phone);
|
||||
|
||||
} else {
|
||||
// 已注册,则获取其用户 ID
|
||||
@@ -81,7 +102,49 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> impleme
|
||||
}
|
||||
}
|
||||
}
|
||||
return Response.success("");
|
||||
StpUtil.login(userId);
|
||||
|
||||
// 获取 Token 令牌
|
||||
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
|
||||
|
||||
// 返回 Token 令牌
|
||||
return Response.success(tokenInfo.tokenValue);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long registerUser(String phone) {
|
||||
long userId = IdGenerator.getInstance()
|
||||
.nextId();
|
||||
Long xiaoyishuId = redisTemplate.opsForValue()
|
||||
.increment(XIAOYI_ID_GENERATOR_KEY);
|
||||
UserEntity userEntity = UserEntity.builder()
|
||||
.id(userId)
|
||||
.phone(phone)
|
||||
.xiaoyishuId(String.valueOf(xiaoyishuId))
|
||||
.nickname(NICK_NAME_PREFIX + xiaoyishuId)
|
||||
.status(StatusEnum.ENABLED.getValue())
|
||||
.createTime(LocalDateTime.now())
|
||||
.updateTime(LocalDateTime.now())
|
||||
.isDeleted(DeleteEnum.NO.getValue())
|
||||
.build();
|
||||
save(userEntity);
|
||||
|
||||
UserRoleRelEntity userRoleRel = UserRoleRelEntity.builder()
|
||||
.id(IdGenerator.getInstance()
|
||||
.nextId())
|
||||
.userId(userId)
|
||||
.roleId(COMMON_USER_ROLE_ID)
|
||||
.createTime(LocalDateTime.now())
|
||||
.updateTime(LocalDateTime.now())
|
||||
.isDeleted(DeleteEnum.NO.getValue())
|
||||
.build();
|
||||
userRoleRelMapper.insert(userRoleRel);
|
||||
List<Long> roles = new ArrayList<>();
|
||||
roles.add(COMMON_USER_ROLE_ID);
|
||||
String userRolesKey = RedisKeyConstants.buildUserRolesKey(phone);
|
||||
redisTemplate.opsForValue()
|
||||
.set(userRolesKey, JsonUtils.toJsonString(roles));
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -36,7 +36,7 @@ public class VerificationCodeServiceImpl implements VerificationCodeService {
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Resource(name = "taskExecutor")
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
@Resource
|
||||
private AliyunSmsHelper aliyunSmsHelper;
|
||||
@@ -56,6 +56,7 @@ public class VerificationCodeServiceImpl implements VerificationCodeService {
|
||||
// 3. 生成6位随机验证码
|
||||
String verificationCode = RandomUtil.randomNumbers(6);
|
||||
|
||||
//=============== 开发环境不实际调用短信发送接口 ===============
|
||||
// 4. 异步发送短信(用CompletableFuture跟踪任务状态,捕获异常)
|
||||
CompletableFuture<Boolean> smsSendFuture = CompletableFuture.supplyAsync(() -> {
|
||||
// 设置线程名称,便于日志排查
|
||||
@@ -69,9 +70,9 @@ public class VerificationCodeServiceImpl implements VerificationCodeService {
|
||||
log.error("==> 手机号: {}, 短信发送接口调用异常", MaskUtils.maskMobile(phoneNumber), e);
|
||||
return false;
|
||||
}
|
||||
}, threadPoolTaskExecutor);
|
||||
}, taskExecutor);
|
||||
|
||||
// 5. 同步等待短信发送结果(超时控制,避免主线程阻塞过久)
|
||||
//5. 同步等待短信发送结果(超时控制,避免主线程阻塞过久)
|
||||
boolean smsSendSuccess;
|
||||
try {
|
||||
smsSendSuccess = smsSendFuture.get(SMS_SEND_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
@@ -92,11 +93,13 @@ public class VerificationCodeServiceImpl implements VerificationCodeService {
|
||||
log.error("==> 手机号: {}, 发送验证码失败(第三方接口返回失败)", MaskUtils.maskMobile(phoneNumber));
|
||||
throw new BizException(ResponseCodeEnum.SMS_SEND_FAILED);
|
||||
}
|
||||
//=============== 开发环境不实际调用短信发送接口 ===============
|
||||
|
||||
// 7. 短信发送成功后,记录日志(验证码脱敏,仅保留后2位)+ 存储Redis
|
||||
log.info("==> 手机号: {}, 已发送验证码:【****{}】", MaskUtils.maskMobile(phoneNumber), verificationCode.substring(4));
|
||||
redisTemplate.opsForValue().set(key, verificationCode, VERIFICATION_CODE_EXPIRE_TIME, TimeUnit.MINUTES);
|
||||
|
||||
return Response.success();
|
||||
return Response.success(verificationCode);
|
||||
//return Response.success();
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
/**
|
||||
* @author ayi
|
||||
@@ -16,9 +17,10 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
@TestPropertySource(properties = {"jasypt.encryptor.password=GhaU7VjZd2b3M4Hbx4SelEXZc"})
|
||||
public class ThreadPoolTaskExecutorTests {
|
||||
@Resource
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
@Resource(name = "taskExecutor")
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
/**
|
||||
* 测试线程池
|
||||
@@ -28,7 +30,7 @@ public class ThreadPoolTaskExecutorTests {
|
||||
int count = 300;
|
||||
while (count-- > 0) {
|
||||
int finalCount = count;
|
||||
threadPoolTaskExecutor.submit(() -> log.info("异步线程: 这是{}号线程", finalCount));
|
||||
taskExecutor.submit(() -> log.info("异步线程: 这是{}号线程", finalCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,5 +17,5 @@ public enum DeleteEnum {
|
||||
YES(true),
|
||||
NO(false);
|
||||
|
||||
private final Boolean value;
|
||||
public final Boolean value;
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,5 +17,5 @@ public enum StatusEnum {
|
||||
ENABLED(1),
|
||||
DISABLED(0);
|
||||
|
||||
private final Integer value;
|
||||
public final Integer value;
|
||||
}
|
||||
|
||||
+10
-10
@@ -4,7 +4,7 @@ import java.lang.management.ManagementFactory;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
public class SnowflakeIdGenerator {
|
||||
public class IdGenerator {
|
||||
// ====================== 配置参数 ======================
|
||||
/** 开始时间戳 (2024-01-01 00:00:00),可自定义,减少ID长度 */
|
||||
private static final long START_TIMESTAMP = 1767196800000L;
|
||||
@@ -36,7 +36,7 @@ public class SnowflakeIdGenerator {
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
// ====================== 单例实例 ======================
|
||||
private static volatile SnowflakeIdGenerator INSTANCE;
|
||||
private static volatile IdGenerator INSTANCE;
|
||||
|
||||
/**
|
||||
* 私有构造器,初始化机器ID(自动计算,也可手动指定)
|
||||
@@ -44,7 +44,7 @@ public class SnowflakeIdGenerator {
|
||||
* @param workerId 机器ID (0-1023)
|
||||
* @throws IllegalArgumentException 机器ID超出范围时抛出
|
||||
*/
|
||||
private SnowflakeIdGenerator(long workerId) {
|
||||
private IdGenerator(long workerId) {
|
||||
// 校验机器ID范围
|
||||
long maxWorkerId = ~(-1L << WORKER_ID_BITS);
|
||||
if (workerId < 0 || workerId > maxWorkerId) {
|
||||
@@ -58,11 +58,11 @@ public class SnowflakeIdGenerator {
|
||||
*
|
||||
* @return 雪花算法生成器实例
|
||||
*/
|
||||
public static SnowflakeIdGenerator getInstance() {
|
||||
public static IdGenerator getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (SnowflakeIdGenerator.class) {
|
||||
synchronized (IdGenerator.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new SnowflakeIdGenerator(calculateWorkerId());
|
||||
INSTANCE = new IdGenerator(calculateWorkerId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,11 +75,11 @@ public class SnowflakeIdGenerator {
|
||||
* @param workerId 机器ID (0-1023)
|
||||
* @return 雪花算法生成器实例
|
||||
*/
|
||||
public static SnowflakeIdGenerator getInstance(long workerId) {
|
||||
public static IdGenerator getInstance(long workerId) {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (SnowflakeIdGenerator.class) {
|
||||
synchronized (IdGenerator.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new SnowflakeIdGenerator(workerId);
|
||||
INSTANCE = new IdGenerator(workerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class SnowflakeIdGenerator {
|
||||
// ====================== 测试用例 ======================
|
||||
public static void main(String[] args) {
|
||||
// 测试生成10个ID,验证有序性和唯一性
|
||||
SnowflakeIdGenerator generator = SnowflakeIdGenerator.getInstance();
|
||||
IdGenerator generator = IdGenerator.getInstance();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
long id = generator.nextId();
|
||||
System.out.println("生成的ID:" + id);
|
||||
Reference in New Issue
Block a user