refactor(ai): 重构AI
This commit is contained in:
@@ -13,6 +13,7 @@ import java.time.LocalDateTime;
|
||||
* 基础实体类
|
||||
*
|
||||
* <p>实体类的基类,包含了实体类的公共属性,如创建时间、更新时间、逻辑删除标识等</p>
|
||||
* <p>多租户模式下,会自动添加 tenant_id 字段(通过 MyMetaObjectHandler 自动填充)</p>
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2024/6/23
|
||||
@@ -29,6 +30,26 @@ public class BaseEntity implements Serializable {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户ID(多租户模式)
|
||||
* <p>
|
||||
* 注意:此字段仅在启用多租户时生效
|
||||
* 通过 MyMetaObjectHandler 自动填充,无需手动设置
|
||||
* 如果不需要多租户,可以通过配置 youlai.tenant.enabled=false 禁用
|
||||
* </p>
|
||||
* <p>
|
||||
* 重要说明:
|
||||
* 1. 默认使用 exist = false 标记字段不存在于数据库,避免单租户模式下报错
|
||||
* 2. 在启用多租户时,需要确保数据库表中有 tenant_id 字段
|
||||
* 3. 多租户的数据隔离主要通过 TenantLineHandler 自动添加 WHERE 条件实现
|
||||
* 4. 如果需要在 INSERT 时写入 tenant_id,请将 exist 改为 true 或移除 exist 属性
|
||||
* 5. 或者执行 add_tenant_column.sql 脚本为表添加 tenant_id 字段
|
||||
* </p>
|
||||
*/
|
||||
@TableField(value = "tenant_id", exist = false)
|
||||
@JsonInclude(value = JsonInclude.Include.NON_NULL)
|
||||
private Long tenantId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
||||
@@ -5,11 +5,16 @@ import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||
import com.youlai.boot.config.property.TenantProperties;
|
||||
import com.youlai.boot.plugin.mybatis.MyDataPermissionHandler;
|
||||
import com.youlai.boot.plugin.mybatis.MyMetaObjectHandler;
|
||||
import com.youlai.boot.plugin.mybatis.TenantLineHandler;
|
||||
import org.apache.ibatis.mapping.DatabaseIdProvider;
|
||||
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
@@ -29,14 +34,30 @@ public class MybatisConfig {
|
||||
@Value("${app.db-type:mysql}")
|
||||
private String dbType;
|
||||
|
||||
@Autowired(required = false)
|
||||
private TenantLineHandler tenantLineHandler;
|
||||
|
||||
@Autowired(required = false)
|
||||
private TenantProperties tenantProperties;
|
||||
|
||||
/**
|
||||
* 分页插件和数据权限插件
|
||||
* <p>
|
||||
* 如果启用了多租户,则添加多租户插件(必须在最前面)
|
||||
* </p>
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
|
||||
// 多租户插件(如果启用,必须在最前面)
|
||||
if (tenantProperties != null && Boolean.TRUE.equals(tenantProperties.getEnabled()) && tenantLineHandler != null) {
|
||||
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(tenantLineHandler));
|
||||
}
|
||||
|
||||
// 数据权限
|
||||
interceptor.addInnerInterceptor(new DataPermissionInterceptor(new MyDataPermissionHandler()));
|
||||
|
||||
// 分页插件,根据配置动态选择数据库类型
|
||||
DbType mpDbType = DbType.MYSQL;
|
||||
String type = dbType == null ? "mysql" : dbType.toLowerCase();
|
||||
|
||||
@@ -23,3 +23,4 @@ public interface AiCommandLogMapper extends BaseMapper<AiCommandLog> {
|
||||
IPage<AiCommandLogVO> getLogPage(Page<AiCommandLogVO> page, AiCommandPageQuery queryParams);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -79,3 +79,4 @@ public class AiCommandLog extends BaseEntity {
|
||||
private String ipAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,3 +90,4 @@ public class AiCommandLogVO implements Serializable {
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,3 +30,4 @@ public interface AiCommandLogService extends IService<AiCommandLog> {
|
||||
void rollbackCommand(String logId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,3 +47,4 @@ public class AiCommandLogServiceImpl extends ServiceImpl<AiCommandLogMapper, AiC
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,33 @@
|
||||
package com.youlai.boot.plugin.mybatis;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.youlai.boot.common.tenant.TenantContextHolder;
|
||||
import com.youlai.boot.config.property.TenantProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* mybatis-plus 字段自动填充
|
||||
* <p>
|
||||
* 支持自动填充创建时间、更新时间和租户ID
|
||||
* </p>
|
||||
*
|
||||
* @author haoxr
|
||||
* @since 2022/10/14
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
@Autowired(required = false)
|
||||
private TenantProperties tenantProperties;
|
||||
|
||||
/**
|
||||
* 新增填充创建时间
|
||||
* 新增填充创建时间、更新时间和租户ID
|
||||
*
|
||||
* @param metaObject 元数据
|
||||
*/
|
||||
@@ -24,6 +35,27 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
|
||||
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
|
||||
|
||||
// 如果启用了多租户,自动填充租户ID
|
||||
// 注意:由于 BaseEntity 中 tenantId 字段使用了 exist = false(避免单租户模式报错)
|
||||
// 在启用多租户时,需要通过反射动态修改字段的 exist 属性,或者直接设置值
|
||||
// 但 MyBatis-Plus 的字段映射是静态的,无法动态修改
|
||||
// 因此,我们使用 strictInsertFill,它会自动处理字段映射
|
||||
// 如果字段不存在(exist = false),strictInsertFill 会跳过,不会报错
|
||||
if (tenantProperties != null && Boolean.TRUE.equals(tenantProperties.getEnabled())) {
|
||||
Long tenantId = TenantContextHolder.getTenantId();
|
||||
if (tenantId != null) {
|
||||
// 使用数据库字段名(tenant_id)进行填充
|
||||
// 注意:由于 exist = false,这个填充不会写入数据库
|
||||
// 但多租户的数据隔离是通过 TenantLineHandler 自动添加 WHERE 条件实现的
|
||||
// 所以这里只需要设置实体对象的属性值即可(用于业务逻辑)
|
||||
String propertyName = "tenantId";
|
||||
if (metaObject.hasGetter(propertyName)) {
|
||||
// 直接设置值到实体对象,不依赖字段映射
|
||||
metaObject.setValue(propertyName, tenantId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user