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