feat(biji-houdaun): 实现用户注册、登录、 Markdown 文件和图片上传功能
- 新增用户注册、登录接口及服务实现 - 添加 Markdown 文件创建、更新接口及服务实现 - 实现图片上传、获取接口及服务实现 - 集成 Snowflake ID 生成器 - 添加全局异常处理和统一返回结果封装 - 配置跨域访问和静态资源处理 - 实现基础的 XSS 防护
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package com.test.bijihoudaun.util;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 实体复制工具类
|
||||
*/
|
||||
public class EntityCopier {
|
||||
|
||||
/**
|
||||
* 复制实体属性到另一个实体
|
||||
* @param source 源实体
|
||||
* @param target 目标实体
|
||||
* @param <S> 源类型
|
||||
* @param <T> 目标类型
|
||||
*/
|
||||
public static <S, T> void copyEntityToEntity(S source, T target) {
|
||||
BeanUtil.copyProperties(source, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制实体属性到目标类的新实例
|
||||
* @param source 源实体
|
||||
* @param targetClass 目标类
|
||||
* @param <S> 源类型
|
||||
* @param <T> 目标类型
|
||||
* @return 目标类的新实例
|
||||
*/
|
||||
public static <S, T> T copyEntityToClass(S source, Class<T> targetClass) {
|
||||
return BeanUtil.copyProperties(source, targetClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制实体列表到目标类列表
|
||||
* @param sourceList 源列表
|
||||
* @param targetClass 目标类
|
||||
* @param <S> 源类型
|
||||
* @param <T> 目标类型
|
||||
* @return 目标类的新列表
|
||||
*/
|
||||
public static <S, T> List<T> copyList(List<S> sourceList, Class<T> targetClass) {
|
||||
return sourceList.stream()
|
||||
.map(source -> copyEntityToClass(source, targetClass))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.test.bijihoudaun.util;
|
||||
|
||||
public class RandomString {
|
||||
|
||||
// 生成指定长度的随机字符串
|
||||
public static String generateRandomString(int length) {
|
||||
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int randomIndex = (int) (Math.random() * chars.length());
|
||||
result.append(chars.charAt(randomIndex));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.test.bijihoudaun.util;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SnowflakeIdGenerator {
|
||||
|
||||
// 起始时间戳(2023-01-01 00:00:00)
|
||||
private static final long EPOCH = 1672531200000L;
|
||||
|
||||
// 机器ID位数
|
||||
private static final long WORKER_ID_BITS = 5L;
|
||||
// 数据中心ID位数
|
||||
private static final long DATACENTER_ID_BITS = 5L;
|
||||
// 最大机器ID (0-31)
|
||||
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
|
||||
// 最大数据中心ID (0-31)
|
||||
private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);
|
||||
// 序列号位数
|
||||
private static final long SEQUENCE_BITS = 12L;
|
||||
|
||||
// 机器ID左移位数
|
||||
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
|
||||
// 数据中心ID左移位数
|
||||
private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
|
||||
// 时间戳左移位数
|
||||
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
|
||||
// 序列号掩码(4095)
|
||||
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
|
||||
|
||||
private final long workerId;
|
||||
private final long datacenterId;
|
||||
|
||||
private long sequence = 0L;
|
||||
private long lastTimestamp = -1L;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param workerId 机器ID
|
||||
* @param datacenterId 数据中心ID
|
||||
*/
|
||||
public SnowflakeIdGenerator(
|
||||
@Value("${worker.id:0}") long workerId,
|
||||
@Value("${datacenter.id:0}") long datacenterId) {
|
||||
|
||||
// 校验机器ID范围
|
||||
if (workerId > MAX_WORKER_ID || workerId < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Worker ID 必须在 0 到 %d 之间", MAX_WORKER_ID));
|
||||
}
|
||||
|
||||
// 校验数据中心ID范围
|
||||
if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Datacenter ID 必须在 0 到 %d 之间", MAX_DATACENTER_ID));
|
||||
}
|
||||
|
||||
this.workerId = workerId;
|
||||
this.datacenterId = datacenterId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成雪花ID
|
||||
*
|
||||
* @return 雪花ID
|
||||
*/
|
||||
public synchronized long nextId() {
|
||||
long timestamp = currentTime();
|
||||
|
||||
// 处理时钟回拨
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(
|
||||
String.format("时钟回拨拒绝生成ID。当前时间: %d, 最后时间: %d",
|
||||
timestamp, lastTimestamp));
|
||||
}
|
||||
|
||||
// 同一毫秒内生成ID
|
||||
if (lastTimestamp == timestamp) {
|
||||
sequence = (sequence + 1) & SEQUENCE_MASK;
|
||||
// 当前毫秒序列号用完
|
||||
if (sequence == 0) {
|
||||
timestamp = nextMillis(lastTimestamp);
|
||||
}
|
||||
}
|
||||
// 新毫秒重置序列号
|
||||
else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
// 组合ID各部分
|
||||
return ((timestamp - EPOCH) << TIMESTAMP_SHIFT)
|
||||
| (datacenterId << DATACENTER_ID_SHIFT)
|
||||
| (workerId << WORKER_ID_SHIFT)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成雪花ID,转化成字符串类型
|
||||
*
|
||||
* @return 雪花ID-字符串类型
|
||||
*/
|
||||
public synchronized String nextIdStr() {
|
||||
return Long.toString(nextId());
|
||||
}
|
||||
|
||||
// 等待下一毫秒
|
||||
private long nextMillis(long lastTimestamp) {
|
||||
long timestamp = currentTime();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = currentTime();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
// 获取当前毫秒时间戳
|
||||
private long currentTime() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.test.bijihoudaun.util;
|
||||
|
||||
import com.fasterxml.uuid.Generators;
|
||||
import com.fasterxml.uuid.impl.TimeBasedGenerator;
|
||||
|
||||
/**
|
||||
* uuidV7
|
||||
*/
|
||||
public class UuidV7 {
|
||||
/**
|
||||
* 生成uuidV7,生成的uuid有-
|
||||
*/
|
||||
public static String uuid() {
|
||||
TimeBasedGenerator generator = Generators.timeBasedGenerator();
|
||||
return generator.generate().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取uuidV7,生成的uuid无-
|
||||
*/
|
||||
public static String uuidNoHyphen() {
|
||||
return uuid().replace("-", "");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user