diff --git a/service-ai/database/20250702.sql b/service-ai/database/20250702.sql new file mode 100644 index 0000000..82c0f0c --- /dev/null +++ b/service-ai/database/20250702.sql @@ -0,0 +1,83 @@ +create table hudi_collect_build_b12.service_ai_feedback +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + analysis longtext comment 'AI的分析结果', + conclusion longtext comment 'AI的解决方案', + source longtext not null comment '原始报障说明', + status enum ('ANALYSIS_PROCESSING','ANALYSIS_SUCCESS','FINISHED') not null comment '报障处理状态', + primary key (id) +) comment ='报障信息记录' charset = utf8mb4; + +create table hudi_collect_build_b12.service_ai_feedback_pictures +( + feedback_id bigint not null, + pictures_id bigint not null, + primary key (feedback_id, pictures_id) +) comment ='报障相关截图' charset = utf8mb4; + +alter table hudi_collect_build_b12.service_ai_feedback_pictures + add constraint UK3npjcyjyqfbdlf2v5tj64j2g3 unique (pictures_id); + +create table hudi_collect_build_b12.service_ai_file +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + filename varchar(255) comment '文件名称', + md5 varchar(255) comment '文件的md5编码,用于校验文件的完整性', + path varchar(255) comment '文件在主机上存储的实际路径', + size bigint comment '文件大小,单位是byte', + type varchar(255) comment '文件类型,通常记录的是文件的后缀名', + primary key (id) +) comment ='记录上传的文件存储信息' charset = utf8mb4; + +create table hudi_collect_build_b12.service_ai_flow_task +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + error longtext comment '任务运行产生的报错', + input longtext comment '任务输入', + result longtext comment '任务运行结果', + status enum ('ERROR','FINISHED','RUNNING') not null comment '任务运行状态', + template_id bigint not null comment '流程任务对应的模板', + primary key (id) +) comment ='流程任务记录' charset = utf8mb4; + +create table hudi_collect_build_b12.service_ai_flow_task_template +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + description varchar(255) comment '模板功能、内容说明', + flow text not null comment 'LiteFlow流程表达式', + flow_graph longtext comment '前端流程图数据', + input_schema longtext not null comment '模板入参Schema', + name varchar(255) not null comment '模板名称', + primary key (id) +) comment ='流程任务模板' charset = utf8mb4; + +create table hudi_collect_build_b12.service_ai_group +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + name varchar(255) not null comment '分组名称', + status enum ('FINISHED','RUNNING') not null comment '分组处理状态', + knowledge_id bigint not null, + primary key (id) +) comment ='知识库下包含的分组' charset = utf8mb4; + +create table hudi_collect_build_b12.service_ai_knowledge +( + id bigint not null comment '记录唯一标记', + created_time datetime(6) comment '记录创建时间', + modified_time datetime(6) comment '记录更新时间', + description longtext not null comment '知识库说明', + name varchar(255) not null comment '知识库名称', + strategy enum ('Cosine','Euclid') not null comment '知识库策略', + vector_source_id bigint not null comment '知识库对应的向量库名', + primary key (id) +) comment ='知识库' charset = utf8mb4; diff --git a/service-ai/database/service_ai_feedback.sql b/service-ai/database/service_ai_feedback.sql deleted file mode 100644 index 8baf92a..0000000 --- a/service-ai/database/service_ai_feedback.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE TABLE `service_ai_feedback` -( - `id` bigint NOT NULL, - `created_time` datetime(6) DEFAULT NULL, - `modified_time` datetime(6) DEFAULT NULL, - `analysis` longtext, - `conclusion` longtext, - `source` longtext NOT NULL, - `status` tinyint NOT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET = utf8mb4; - -CREATE TABLE `service_ai_feedback_pictures` -( - `feedback_id` bigint NOT NULL, - `pictures_id` bigint NOT NULL, - PRIMARY KEY (`feedback_id`, `pictures_id`) -) DEFAULT CHARSET = utf8mb4; diff --git a/service-ai/database/service_ai_file.sql b/service-ai/database/service_ai_file.sql deleted file mode 100644 index d0bb88f..0000000 --- a/service-ai/database/service_ai_file.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE `service_ai_file` -( - `id` bigint NOT NULL, - `created_time` datetime(6) DEFAULT NULL, - `modified_time` datetime(6) DEFAULT NULL, - `filename` varchar(255) DEFAULT NULL, - `md5` varchar(255) DEFAULT NULL, - `path` varchar(255) DEFAULT NULL, - `size` bigint DEFAULT NULL, - `type` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET = utf8mb4; diff --git a/service-ai/database/service_ai_group.sql b/service-ai/database/service_ai_group.sql deleted file mode 100644 index eafead9..0000000 --- a/service-ai/database/service_ai_group.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `service_ai_group` -( - `id` bigint NOT NULL, - `created_time` datetime(6) DEFAULT NULL, - `modified_time` datetime(6) DEFAULT NULL, - `name` varchar(255) NOT NULL, - `status` tinyint NOT NULL, - `knowledge_id` bigint NOT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET=utf8mb4; diff --git a/service-ai/database/service_ai_knowledge.sql b/service-ai/database/service_ai_knowledge.sql deleted file mode 100644 index 90f30f5..0000000 --- a/service-ai/database/service_ai_knowledge.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE `service_ai_knowledge` -( - `id` bigint NOT NULL, - `created_time` datetime(6) DEFAULT NULL, - `modified_time` datetime(6) DEFAULT NULL, - `description` longtext NOT NULL, - `name` varchar(255) NOT NULL, - `strategy` tinyint NOT NULL, - `vector_source_id` bigint NOT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET = utf8mb4; diff --git a/service-ai/service-ai-web/pom.xml b/service-ai/service-ai-web/pom.xml index a1b67ce..450a070 100644 --- a/service-ai/service-ai-web/pom.xml +++ b/service-ai/service-ai-web/pom.xml @@ -82,6 +82,13 @@ org.noear solon-ai-dialect-openai + + + org.hibernate.orm + hibernate-ant + 6.6.8.Final + test + diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/IdOnlyEntity.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/IdOnlyEntity.java index 1ce7264..8eeef62 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/IdOnlyEntity.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/IdOnlyEntity.java @@ -7,6 +7,7 @@ import jakarta.persistence.MappedSuperclass; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.GenericGenerator; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -22,6 +23,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class IdOnlyEntity { + @Comment("记录唯一标记") @Id @GeneratedValue(generator = "snowflake") @GenericGenerator(name = "snowflake", strategy = "com.lanyuanxiaoyao.service.ai.web.configuration.SnowflakeIdGenerator") diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/SimpleEntity.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/SimpleEntity.java index 5329664..383fed0 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/SimpleEntity.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/base/entity/SimpleEntity.java @@ -6,6 +6,7 @@ import java.time.LocalDateTime; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -22,8 +23,10 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class SimpleEntity extends IdOnlyEntity { + @Comment("记录创建时间") @CreatedDate private LocalDateTime createdTime; + @Comment("记录更新时间") @LastModifiedDate private LocalDateTime modifiedTime; } diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/DataFile.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/DataFile.java index 0b9f4ad..f3b8194 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/DataFile.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/DataFile.java @@ -8,6 +8,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; /** @@ -23,11 +24,17 @@ import org.hibernate.annotations.DynamicUpdate; @DynamicUpdate @Table(catalog = Constants.DATABASE_NAME, name = "service_ai_file") @NoArgsConstructor +@Comment("记录上传的文件存储信息") public class DataFile extends SimpleEntity { + @Comment("文件名称") private String filename; + @Comment("文件大小,单位是byte") private Long size; + @Comment("文件的md5编码,用于校验文件的完整性") private String md5; + @Comment("文件在主机上存储的实际路径") private String path; + @Comment("文件类型,通常记录的是文件的后缀名") private String type; public DataFile(String filename) { diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Feedback.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Feedback.java index bc50bcb..a4b6cdd 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Feedback.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Feedback.java @@ -6,6 +6,8 @@ import jakarta.persistence.Column; import jakarta.persistence.ConstraintMode; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.ForeignKey; import jakarta.persistence.JoinTable; @@ -17,6 +19,7 @@ import java.util.Set; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -30,18 +33,25 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @NamedEntityGraph(name = "feedback.detail", attributeNodes = { @NamedAttributeNode("pictures") }) +@Comment("报障信息记录") public class Feedback extends SimpleEntity { + @Comment("原始报障说明") @Column(nullable = false, columnDefinition = "longtext") private String source; + @Comment("报障相关截图") @OneToMany(fetch = FetchType.EAGER) @JoinTable(catalog = Constants.DATABASE_NAME, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @ToString.Exclude private Set pictures; + @Comment("AI的分析结果") @Column(columnDefinition = "longtext") private String analysis; + @Comment("AI的解决方案") @Column(columnDefinition = "longtext") private String conclusion; + @Comment("报障处理状态") @Column(nullable = false) + @Enumerated(EnumType.STRING) private Status status = Status.ANALYSIS_PROCESSING; public enum Status { diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTask.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTask.java index c740e59..af1ec7b 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTask.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTask.java @@ -6,6 +6,8 @@ import jakarta.persistence.Column; import jakarta.persistence.ConstraintMode; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.ForeignKey; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; @@ -13,6 +15,7 @@ import jakarta.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -23,16 +26,23 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @DynamicUpdate @EntityListeners(AuditingEntityListener.class) @Table(catalog = Constants.DATABASE_NAME, name = "service_ai_flow_task") +@Comment("流程任务记录") public class FlowTask extends SimpleEntity { + @Comment("流程任务对应的模板") @ManyToOne @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) private FlowTaskTemplate template; + @Comment("任务输入") @Column(columnDefinition = "longtext") private String input; + @Comment("任务运行状态") @Column(nullable = false) + @Enumerated(EnumType.STRING) private Status status = Status.RUNNING; + @Comment("任务运行产生的报错") @Column(columnDefinition = "longtext") private String error; + @Comment("任务运行结果") @Column(columnDefinition = "longtext") private String result; diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTaskTemplate.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTaskTemplate.java index d024447..ad294a5 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTaskTemplate.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/FlowTaskTemplate.java @@ -9,6 +9,7 @@ import jakarta.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -19,14 +20,20 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @DynamicUpdate @EntityListeners(AuditingEntityListener.class) @Table(catalog = Constants.DATABASE_NAME, name = "service_ai_flow_task_template") +@Comment("流程任务模板") public class FlowTaskTemplate extends SimpleEntity { + @Comment("模板名称") @Column(nullable = false) private String name; + @Comment("模板功能、内容说明") private String description; + @Comment("模板入参Schema") @Column(nullable = false, columnDefinition = "longtext") private String inputSchema; + @Comment("LiteFlow流程表达式") @Column(nullable = false, columnDefinition = "text") private String flow; + @Comment("前端流程图数据") @Column(columnDefinition = "longtext") private String flowGraph; } diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Group.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Group.java index 828bcd5..c61f286 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Group.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Group.java @@ -6,6 +6,8 @@ import jakarta.persistence.Column; import jakarta.persistence.ConstraintMode; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.ForeignKey; import jakarta.persistence.JoinColumn; @@ -14,6 +16,7 @@ import jakarta.persistence.Table; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -28,10 +31,14 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @DynamicUpdate @EntityListeners(AuditingEntityListener.class) @Table(catalog = Constants.DATABASE_NAME, name = "service_ai_group") +@Comment("知识库内的逻辑分组,比如一个文件是一个分组或一次上传的所有文本是一个分组,可以自由使用而不是限于文件范畴") public class Group extends SimpleEntity { + @Comment("分组名称") @Column(nullable = false) private String name; + @Comment("分组处理状态") @Column(nullable = false) + @Enumerated(EnumType.STRING) private Status status = Status.RUNNING; @ManyToOne(fetch = FetchType.LAZY) diff --git a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Knowledge.java b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Knowledge.java index 6dd04fc..2d71101 100644 --- a/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Knowledge.java +++ b/service-ai/service-ai-web/src/main/java/com/lanyuanxiaoyao/service/ai/web/entity/Knowledge.java @@ -6,6 +6,8 @@ import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; @@ -13,6 +15,7 @@ import java.util.Set; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.hibernate.annotations.Comment; import org.hibernate.annotations.DynamicUpdate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -27,16 +30,23 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @DynamicUpdate @EntityListeners(AuditingEntityListener.class) @Table(catalog = Constants.DATABASE_NAME, name = "service_ai_knowledge") +@Comment("知识库") public class Knowledge extends SimpleEntity { + @Comment("知识库对应的向量库名") @Column(nullable = false) private Long vectorSourceId; + @Comment("知识库名称") @Column(nullable = false) private String name; + @Comment("知识库说明") @Column(nullable = false, columnDefinition = "longtext") private String description; + @Comment("知识库策略") @Column(nullable = false) + @Enumerated(EnumType.STRING) private Strategy strategy = Strategy.Cosine; + @Comment("知识库下包含的分组") @OneToMany(fetch = FetchType.LAZY, mappedBy = "knowledge", cascade = CascadeType.ALL) @ToString.Exclude private Set groups; diff --git a/service-ai/service-ai-web/src/test/java/com/lanyuanxiaoyao/service/ai/web/GenerateDDL.java b/service-ai/service-ai-web/src/test/java/com/lanyuanxiaoyao/service/ai/web/GenerateDDL.java new file mode 100644 index 0000000..e9a9c08 --- /dev/null +++ b/service-ai/service-ai-web/src/test/java/com/lanyuanxiaoyao/service/ai/web/GenerateDDL.java @@ -0,0 +1,51 @@ +package com.lanyuanxiaoyao.service.ai.web; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.ClassUtil; +import jakarta.persistence.Entity; +import java.util.EnumSet; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.dialect.MySQLDialect; +import org.hibernate.tool.hbm2ddl.SchemaExport; +import org.hibernate.tool.schema.TargetType; +import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; + +/** + * JPA直接生成建表语句 + * + * @author lanyuanxiaoyao + * @version 20250702 + */ +public class GenerateDDL { + public static void main(String[] args) { + String root = "/Users/lanyuanxiaoyao/Project/IdeaProjects/hudi-service/service-ai/target/sql"; + FileUtil.mkdir(root); + /* ClassUtil.scanPackageBySuper("org.hibernate.dialect", Dialect.class) + .stream() + .filter(clazz -> StrUtil.startWith(clazz.getSimpleName(), "MySQL")) + .filter(clazz -> !StrUtil.startWith(clazz.getSimpleName(), "Abstract")) + .filter(clazz -> !StrUtil.startWith(clazz.getSimpleName(), "Dialect")) + .forEach(dialectClazz -> generateDDL(root, dialectClazz)); */ + generateDDL(root, MySQLDialect.class); + } + + private static void generateDDL(String path, Class dialect) { + var metadataSources = new MetadataSources( + new StandardServiceRegistryBuilder() + .applySetting("hibernate.dialect", dialect.getName()) + .applySetting("hibernate.physical_naming_strategy", CamelCaseToUnderscoresNamingStrategy.class.getName()) + .applySetting("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName()) + .build() + ); + var classes = ClassUtil.scanPackageByAnnotation("com.lanyuanxiaoyao.service.ai.web.entity", Entity.class); + classes.forEach(metadataSources::addAnnotatedClass); + var export = new SchemaExport(); + export.setFormat(true); + export.setDelimiter(";"); + export.setOutputFile(path + "/" + dialect.getSimpleName() + ".sql"); + export.setOverrideOutputFileContent(); + export.execute(EnumSet.of(TargetType.SCRIPT), SchemaExport.Action.CREATE, metadataSources.buildMetadata()); + } +}