feat: 完善后端架构和service层实现
- 创建完整的entity实体类体系,包括所有业务实体 - 实现BaseEntity基类,统一管理公共字段 - 创建雪花算法ID生成器和自动填充处理器 - 简化所有mapper接口,只继承BaseMapper - 重构service层,使用LambdaQueryWrapper进行数据库操作 - 创建BasePageRequest分页查询基类 - 完善用户上下文管理和JWT认证 - 新增WebSocket聊天功能和相关控制器 - 更新前端配置和组件,完善用户认证流程 - 同步数据库建表脚本
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package com.emotion.config;
|
||||
|
||||
import com.emotion.util.SnowflakeIdGenerator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* ID生成器配置类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class IdGeneratorConfig {
|
||||
|
||||
/**
|
||||
* 机器ID配置(可通过配置文件指定)
|
||||
*/
|
||||
@Value("${emotion.snowflake.machine-id:#{null}}")
|
||||
private Long machineId;
|
||||
|
||||
/**
|
||||
* 配置雪花算法ID生成器
|
||||
*
|
||||
* @return SnowflakeIdGenerator实例
|
||||
*/
|
||||
@Bean
|
||||
public SnowflakeIdGenerator snowflakeIdGenerator() {
|
||||
long finalMachineId;
|
||||
|
||||
if (machineId != null) {
|
||||
// 使用配置文件中指定的机器ID
|
||||
finalMachineId = machineId;
|
||||
log.info("使用配置文件指定的机器ID: {}", finalMachineId);
|
||||
} else {
|
||||
// 自动生成机器ID
|
||||
finalMachineId = generateMachineId();
|
||||
log.info("自动生成机器ID: {}", finalMachineId);
|
||||
}
|
||||
|
||||
return new SnowflakeIdGenerator(finalMachineId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动生成机器ID
|
||||
* 基于MAC地址和IP地址生成唯一的机器ID
|
||||
*
|
||||
* @return 机器ID (0-1023)
|
||||
*/
|
||||
private long generateMachineId() {
|
||||
try {
|
||||
// 获取本机IP地址
|
||||
InetAddress localHost = InetAddress.getLocalHost();
|
||||
|
||||
// 获取网络接口
|
||||
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
|
||||
|
||||
if (networkInterface != null) {
|
||||
// 获取MAC地址
|
||||
byte[] hardwareAddress = networkInterface.getHardwareAddress();
|
||||
|
||||
if (hardwareAddress != null && hardwareAddress.length >= 6) {
|
||||
// 使用MAC地址的后两个字节生成机器ID
|
||||
long machineId = ((hardwareAddress[4] & 0xFF) << 8) | (hardwareAddress[5] & 0xFF);
|
||||
// 确保机器ID在有效范围内 (0-1023)
|
||||
return machineId & 0x3FF;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果无法获取MAC地址,使用IP地址生成
|
||||
byte[] address = localHost.getAddress();
|
||||
if (address.length >= 4) {
|
||||
// 使用IP地址的后两个字节生成机器ID
|
||||
long machineId = ((address[2] & 0xFF) << 8) | (address[3] & 0xFF);
|
||||
return machineId & 0x3FF;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("自动生成机器ID失败,使用默认策略: {}", e.getMessage());
|
||||
}
|
||||
|
||||
// 如果所有方法都失败,使用当前时间戳生成
|
||||
return System.currentTimeMillis() % 1024;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.emotion.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* MyBatis-Plus配置类
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
/**
|
||||
* 分页插件配置
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// 添加分页插件
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.emotion.config;
|
||||
|
||||
import com.emotion.interceptor.UserContextInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* Web配置类
|
||||
* 配置拦截器、跨域等
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private UserContextInterceptor userContextInterceptor;
|
||||
|
||||
/**
|
||||
* 添加拦截器
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(userContextInterceptor)
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns(
|
||||
"/error",
|
||||
"/favicon.ico",
|
||||
"/actuator/**",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-resources/**",
|
||||
"/v2/api-docs",
|
||||
"/v3/api-docs",
|
||||
"/webjars/**",
|
||||
"/doc.html",
|
||||
"/static/**",
|
||||
"/public/**"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨域配置
|
||||
*/
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOriginPatterns("*")
|
||||
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||
.allowedHeaders("*")
|
||||
.allowCredentials(true)
|
||||
.maxAge(3600);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.emotion.config;
|
||||
|
||||
import com.emotion.interceptor.JwtAuthInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* Web MVC配置
|
||||
*
|
||||
* @author emotion-museum
|
||||
* @date 2025-07-23
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private JwtAuthInterceptor jwtAuthInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(jwtAuthInterceptor)
|
||||
.addPathPatterns("/api/**") // 拦截所有API请求
|
||||
.excludePathPatterns(
|
||||
"/api/auth/login", // 登录接口
|
||||
"/api/auth/register", // 注册接口
|
||||
"/api/auth/captcha", // 验证码接口
|
||||
"/api/auth/refresh-token", // 刷新token接口
|
||||
"/api/health", // 健康检查接口
|
||||
"/api/ws/**", // WebSocket接口
|
||||
"/swagger-ui/**", // Swagger UI
|
||||
"/v3/api-docs/**", // API文档
|
||||
"/actuator/**" // 监控端点
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user