本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

136 lines
5.9 KiB

package com.wok.supportbot.config;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
/**
* 数据库初始化配置
* 应用启动时检查并创建必要的表
*/
@Component
@Slf4j
public class DatabaseInitConfig {
@Autowired
private JdbcTemplate jdbcTemplate;
@PostConstruct
public void init() {
try {
// 检查 knowledge_category 表是否存在
boolean categoryTableExists = checkTableExists("knowledge_category");
if (!categoryTableExists) {
log.info("创建知识库分类表 knowledge_category");
createCategoryTable();
}
// 检查 knowledge_document 表是否存在
boolean documentTableExists = checkTableExists("knowledge_document");
if (!documentTableExists) {
log.info("创建知识文档表 knowledge_document");
createDocumentTable();
} else {
// 修复已存在表的 tags 默认值(从数组改为对象)
fixTagsDefaultValue();
// 自动添加 content_hash 列(二期新增)
addContentHashColumn();
}
log.info("数据库初始化完成");
} catch (Exception e) {
log.error("数据库初始化失败", e);
}
}
private boolean checkTableExists(String tableName) {
try {
String sql = "SELECT 1 FROM " + tableName + " LIMIT 1";
jdbcTemplate.queryForObject(sql, Integer.class);
return true;
} catch (Exception e) {
return false;
}
}
private void createCategoryTable() {
String sql = """
CREATE TABLE IF NOT EXISTS knowledge_category (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
parent_id BIGINT DEFAULT 0 NOT NULL,
sort_order INTEGER DEFAULT 0 NOT NULL,
document_count INTEGER DEFAULT 0 NOT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_delete BOOLEAN DEFAULT FALSE NOT NULL
)
""";
jdbcTemplate.execute(sql);
// 创建索引
jdbcTemplate.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_category_parent ON knowledge_category (parent_id)");
}
private void createDocumentTable() {
String sql = """
CREATE TABLE IF NOT EXISTS knowledge_document (
id BIGSERIAL PRIMARY KEY,
title VARCHAR(500) NOT NULL,
source_name VARCHAR(500),
file_type VARCHAR(20) NOT NULL,
file_size BIGINT DEFAULT 0 NOT NULL,
content TEXT,
category_id BIGINT DEFAULT 0 NOT NULL,
tags JSONB DEFAULT '{}' NOT NULL,
chunk_count INTEGER DEFAULT 0 NOT NULL,
status VARCHAR(20) DEFAULT 'PROCESSING' NOT NULL,
error_message TEXT,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_delete BOOLEAN DEFAULT FALSE NOT NULL
)
""";
jdbcTemplate.execute(sql);
// 创建索引
jdbcTemplate.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_document_category ON knowledge_document (category_id)");
jdbcTemplate.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_document_status ON knowledge_document (status)");
jdbcTemplate.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_document_create_time ON knowledge_document (create_time DESC)");
}
private void fixTagsDefaultValue() {
try {
// 检查当前默认值是否为数组
String checkSql = "SELECT column_default FROM information_schema.columns WHERE table_name = 'knowledge_document' AND column_name = 'tags'";
String currentDefault = jdbcTemplate.queryForObject(checkSql, String.class);
if (currentDefault != null && currentDefault.contains("[]")) {
log.info("修复 knowledge_document.tags 默认值");
jdbcTemplate.execute("ALTER TABLE knowledge_document ALTER COLUMN tags SET DEFAULT '{}'");
// 将已有的 '[]' 更新为 '{}'
jdbcTemplate.execute("UPDATE knowledge_document SET tags = '{}' WHERE tags = '[]' OR tags IS NULL");
}
} catch (Exception e) {
log.warn("修复 tags 默认值时出错(可能已修复)", e);
}
}
/**
* 自动添加 content_hash 列(二期去重功能新增字段)
*/
private void addContentHashColumn() {
try {
String checkSql = "SELECT COUNT(*) FROM information_schema.columns WHERE table_name = 'knowledge_document' AND column_name = 'content_hash'";
Integer count = jdbcTemplate.queryForObject(checkSql, Integer.class);
if (count != null && count == 0) {
log.info("添加 knowledge_document.content_hash 列");
jdbcTemplate.execute("ALTER TABLE knowledge_document ADD COLUMN content_hash VARCHAR(64)");
jdbcTemplate.execute("CREATE INDEX IF NOT EXISTS idx_knowledge_document_content_hash ON knowledge_document (content_hash)");
}
} catch (Exception e) {
log.warn("添加 content_hash 列时出错", e);
}
}
}