feat: 完善知识库批量导入与公共 API
- 新增批量异步导入、状态查询、失败重试与中断恢复链路 - 拆分知识库读取、导入、维护权限并完善 Public API 契约 - 补充数据库迁移、管理端交互、接口说明与相关测试
This commit is contained in:
@@ -47,7 +47,7 @@ easyflow:
|
||||
max-retry: 16
|
||||
consumer-executor:
|
||||
core-size: 4
|
||||
max-size: 12
|
||||
max-size: 32
|
||||
queue-capacity: 64
|
||||
keep-alive-seconds: 60
|
||||
pool:
|
||||
|
||||
@@ -10,6 +10,9 @@ server:
|
||||
enabled: true
|
||||
charset: UTF-8 # 必须设置 UTF-8,避免 WebFlux 流式返回(AI 场景)会乱码问题
|
||||
force: true
|
||||
tomcat:
|
||||
# Public API 单次最多 200 个文件,额外为 metadata 与表单边界预留 Part。
|
||||
max-part-count: 205
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
@@ -44,8 +47,8 @@ spring:
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 100MB
|
||||
# 为 multipart 边界和请求头预留空间,文件本身仍由 M18 的 100 MiB 硬上限约束。
|
||||
max-request-size: 105MB
|
||||
# Public API 业务上限为 200 MiB,为 metadata 与 multipart 边界预留空间。
|
||||
max-request-size: 220MB
|
||||
web:
|
||||
resources:
|
||||
# 示例:windows【file: C:\easyflow\attachment】 linux【file: /www/easyflow/attachment】
|
||||
@@ -127,7 +130,7 @@ easyflow:
|
||||
max-retry: 16
|
||||
consumer-executor:
|
||||
core-size: 16
|
||||
max-size: 24
|
||||
max-size: 32
|
||||
queue-capacity: 64
|
||||
keep-alive-seconds: 60
|
||||
pool:
|
||||
@@ -198,6 +201,22 @@ easyflow:
|
||||
health:
|
||||
cache-ttl: 5s
|
||||
document-import:
|
||||
bulk:
|
||||
max-file-count: 2000
|
||||
max-total-size: 1GB
|
||||
max-file-size: 100MB
|
||||
upload-concurrency: 3
|
||||
parse-max-running: 2
|
||||
split-max-running: 2
|
||||
index-max-running: 2
|
||||
per-batch-parse-max-running: 2
|
||||
pending-dispatch-batch-size: 100
|
||||
pending-dispatch-interval: 2s
|
||||
pending-redispatch-delay: 5s
|
||||
pending-timeout: 24h
|
||||
parse-submit-timeout: 120s
|
||||
interruption-timeout: 10m
|
||||
max-task-attempts: 3
|
||||
status-broadcast-channel: easyflow:document-import:status
|
||||
parse-monitor:
|
||||
fixed-delay: 10000
|
||||
@@ -249,7 +268,8 @@ easy-agents:
|
||||
provider: mineru
|
||||
mineru:
|
||||
# 统一文档解析桥接层直接复用 easy-agents 的 provider 配置,不在 easyflow 再复制一套配置体系
|
||||
base-url: https://hub.wust.edu.cn/modelServer/mineru-api
|
||||
base-url: https://ontoweb.wust.edu.cn/mineru-api
|
||||
submit-timeout-ms: 120000
|
||||
default-lang-list:
|
||||
- ch
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
CREATE TABLE `tb_document_import_batch`
|
||||
(
|
||||
`id` bigint UNSIGNED NOT NULL COMMENT '主键',
|
||||
`knowledge_id` bigint UNSIGNED NOT NULL COMMENT '知识库ID',
|
||||
`import_mode` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '导入模式',
|
||||
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '批次状态',
|
||||
`total_count` int NOT NULL DEFAULT 0 COMMENT '文件总数',
|
||||
`total_bytes` bigint NOT NULL DEFAULT 0 COMMENT '文件总字节数',
|
||||
`completed_count` int NOT NULL DEFAULT 0 COMMENT '完成数',
|
||||
`processing_count` int NOT NULL DEFAULT 0 COMMENT '处理中数量',
|
||||
`failed_count` int NOT NULL DEFAULT 0 COMMENT '失败数',
|
||||
`pending_count` int NOT NULL DEFAULT 0 COMMENT '等待数',
|
||||
`started_at` datetime NULL DEFAULT NULL COMMENT '开始时间',
|
||||
`finished_at` datetime NULL DEFAULT NULL COMMENT '结束时间',
|
||||
`created` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`created_by` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人',
|
||||
`modified` datetime NULL DEFAULT NULL COMMENT '修改时间',
|
||||
`modified_by` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `idx_document_import_batch_knowledge_status` (`knowledge_id`, `status`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库文档批量导入批次' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
CREATE TABLE `tb_document_import_batch_item`
|
||||
(
|
||||
`id` bigint UNSIGNED NOT NULL COMMENT '主键',
|
||||
`batch_id` bigint UNSIGNED NOT NULL COMMENT '批次ID',
|
||||
`knowledge_id` bigint UNSIGNED NOT NULL COMMENT '知识库ID',
|
||||
`document_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '文档ID',
|
||||
`client_file_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '客户端文件键',
|
||||
`file_name` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件名',
|
||||
`relative_path` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件夹相对路径',
|
||||
`file_size` bigint NOT NULL DEFAULT 0 COMMENT '文件大小',
|
||||
`file_path` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '存储路径',
|
||||
`stage` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '当前阶段',
|
||||
`status` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '当前状态',
|
||||
`error_summary` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '错误摘要',
|
||||
`created` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`created_by` bigint UNSIGNED NULL DEFAULT NULL COMMENT '创建人',
|
||||
`modified` datetime NULL DEFAULT NULL COMMENT '修改时间',
|
||||
`modified_by` bigint UNSIGNED NULL DEFAULT NULL COMMENT '修改人',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_document_import_batch_item_key` (`batch_id`, `client_file_key`) USING BTREE,
|
||||
INDEX `idx_document_import_batch_item_batch_status` (`batch_id`, `status`) USING BTREE,
|
||||
INDEX `idx_document_import_batch_item_knowledge_key` (`knowledge_id`, `client_file_key`) USING BTREE,
|
||||
INDEX `idx_document_import_batch_item_document` (`document_id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '知识库文档批量导入文件项' ROW_FORMAT = DYNAMIC;
|
||||
|
||||
ALTER TABLE `tb_document_import_task`
|
||||
ADD COLUMN `batch_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '批次ID' AFTER `knowledge_id`,
|
||||
ADD COLUMN `batch_item_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '批次文件项ID' AFTER `batch_id`,
|
||||
ADD INDEX `idx_document_import_task_batch_phase_status` (`batch_id`, `phase`, `status`) USING BTREE,
|
||||
ADD INDEX `idx_document_import_task_batch_item` (`batch_item_id`) USING BTREE;
|
||||
@@ -0,0 +1,42 @@
|
||||
ALTER TABLE `tb_document_import_batch`
|
||||
ADD COLUMN `uploaded_count` int NOT NULL DEFAULT 0 COMMENT '已上传数' AFTER `pending_count`,
|
||||
ADD COLUMN `skipped_count` int NOT NULL DEFAULT 0 COMMENT '跳过数' AFTER `uploaded_count`,
|
||||
ADD COLUMN `cancelled_count` int NOT NULL DEFAULT 0 COMMENT '取消数' AFTER `skipped_count`,
|
||||
ADD COLUMN `retryable_failed_count` int NOT NULL DEFAULT 0 COMMENT '可重试失败数' AFTER `cancelled_count`;
|
||||
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
ADD COLUMN `retryable` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否允许批量重试' AFTER `error_summary`,
|
||||
ADD COLUMN `attempt_count` int NOT NULL DEFAULT 0 COMMENT '重试次数' AFTER `retryable`,
|
||||
DROP INDEX `idx_document_import_batch_item_batch_status`,
|
||||
ADD INDEX `idx_document_import_batch_item_batch_status` (`batch_id`, `status`, `modified`) USING BTREE;
|
||||
|
||||
ALTER TABLE `tb_document_import_task`
|
||||
ADD INDEX `idx_document_import_task_phase_status_modified`
|
||||
(`phase`, `status`, `modified`, `batch_id`, `created`) USING BTREE;
|
||||
|
||||
UPDATE `tb_document_import_batch` batch
|
||||
SET batch.`uploaded_count` = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_document_import_batch_item` item
|
||||
WHERE item.`batch_id` = batch.`id`
|
||||
AND item.`status` = 'UPLOADED'
|
||||
),
|
||||
batch.`skipped_count` = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_document_import_batch_item` item
|
||||
WHERE item.`batch_id` = batch.`id`
|
||||
AND item.`status` = 'SKIPPED'
|
||||
),
|
||||
batch.`cancelled_count` = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_document_import_batch_item` item
|
||||
WHERE item.`batch_id` = batch.`id`
|
||||
AND item.`status` = 'CANCELLED'
|
||||
),
|
||||
batch.`retryable_failed_count` = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_document_import_batch_item` item
|
||||
WHERE item.`batch_id` = batch.`id`
|
||||
AND item.`status` = 'FAILED'
|
||||
AND item.`retryable` = 1
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
ADD COLUMN `replaced_document_id` bigint UNSIGNED NULL DEFAULT NULL
|
||||
COMMENT '待覆盖的历史文档ID' AFTER `document_id`,
|
||||
ADD INDEX `idx_document_import_batch_item_replacement`
|
||||
(`replaced_document_id`, `status`, `modified`) USING BTREE;
|
||||
@@ -0,0 +1,15 @@
|
||||
UPDATE `tb_document_import_batch_item`
|
||||
SET `retryable` = 1
|
||||
WHERE `status` = 'FAILED'
|
||||
AND `stage` IN ('PARSE', 'SPLIT', 'INDEX')
|
||||
AND `document_id` IS NOT NULL
|
||||
AND `retryable` = 0;
|
||||
|
||||
UPDATE `tb_document_import_batch` batch
|
||||
SET batch.`retryable_failed_count` = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_document_import_batch_item` item
|
||||
WHERE item.`batch_id` = batch.`id`
|
||||
AND item.`status` = 'FAILED'
|
||||
AND item.`retryable` = 1
|
||||
);
|
||||
@@ -0,0 +1,191 @@
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
INSERT INTO `tb_sys_api_key_resource` (`id`, `request_interface`, `title`)
|
||||
VALUES
|
||||
(366700000000000101, '/public-api/knowledge-share/detail', '知识库读取'),
|
||||
(366700000000000102, '/public-api/knowledge-share/search', '知识库读取'),
|
||||
(366700000000000103, '/public-api/knowledge-share/document/page', '知识库读取'),
|
||||
(366700000000000104, '/public-api/knowledge-share/document/download', '知识库读取'),
|
||||
(366700000000000105, '/public-api/knowledge-share/documentChunk/page', '知识库读取'),
|
||||
(366700000000000106, '/public-api/knowledge-share/faq/page', '知识库读取'),
|
||||
(366700000000000107, '/public-api/knowledge-share/faq/detail', '知识库读取'),
|
||||
(366700000000000108, '/public-api/knowledge-share/faq/exportExcel', '知识库读取'),
|
||||
(366700000000000109, '/public-api/knowledge-share/document/import/batch', '知识导入'),
|
||||
(366700000000000110, '/public-api/knowledge-share/document/import/batch/status', '知识导入'),
|
||||
(366700000000000111, '/public-api/knowledge-share/document/import/batch/retry', '知识导入'),
|
||||
(366700000000000112, '/public-api/knowledge-share/document/import/analyze', '知识导入'),
|
||||
(366700000000000113, '/public-api/knowledge-share/document/import/preview', '知识导入'),
|
||||
(366700000000000114, '/public-api/knowledge-share/document/import/commit', '知识导入'),
|
||||
(366700000000000115, '/public-api/knowledge-share/document/import/task/create', '知识导入'),
|
||||
(366700000000000116, '/public-api/knowledge-share/document/import/task/detail', '知识导入'),
|
||||
(366700000000000117, '/public-api/knowledge-share/document/import/task/preview', '知识导入'),
|
||||
(366700000000000118, '/public-api/knowledge-share/document/import/task/startIndex', '知识导入'),
|
||||
(366700000000000119, '/public-api/knowledge-share/document/import/task/retryParse', '知识导入'),
|
||||
(366700000000000120, '/public-api/knowledge-share/document/import/task/retryIndex', '知识导入'),
|
||||
(366700000000000121, '/public-api/knowledge-share/faq/importExcel', '知识导入'),
|
||||
(366700000000000122, '/public-api/knowledge-share/faq/downloadImportTemplate', '知识导入'),
|
||||
(366700000000000123, '/public-api/knowledge-share/document/remove', '知识库维护'),
|
||||
(366700000000000124, '/public-api/knowledge-share/documentChunk/update', '知识库维护'),
|
||||
(366700000000000125, '/public-api/knowledge-share/documentChunk/remove', '知识库维护'),
|
||||
(366700000000000126, '/public-api/knowledge-share/faq/save', '知识库维护'),
|
||||
(366700000000000127, '/public-api/knowledge-share/faq/update', '知识库维护'),
|
||||
(366700000000000128, '/public-api/knowledge-share/faq/remove', '知识库维护')
|
||||
ON DUPLICATE KEY UPDATE `title` = VALUES(`title`);
|
||||
|
||||
SET @migrated_knowledge_api_key_count = (
|
||||
SELECT COUNT(DISTINCT mapping.`api_key_id`)
|
||||
FROM `tb_sys_api_key_resource_mapping` mapping
|
||||
WHERE mapping.`resource_type` = 'KNOWLEDGE'
|
||||
AND mapping.`resource_target_id` IS NULL
|
||||
);
|
||||
|
||||
UPDATE `tb_sys_api_key_resource_mapping` mapping
|
||||
JOIN `tb_sys_api_key_resource` resource
|
||||
ON resource.`id` = mapping.`api_key_resource_id`
|
||||
SET mapping.`action_scope` = CASE
|
||||
WHEN resource.`request_interface` IN (
|
||||
'/public-api/knowledge-share/detail',
|
||||
'/public-api/knowledge-share/search',
|
||||
'/public-api/knowledge-share/document/page',
|
||||
'/public-api/knowledge-share/document/download',
|
||||
'/public-api/knowledge-share/documentChunk/page',
|
||||
'/public-api/knowledge-share/faq/page',
|
||||
'/public-api/knowledge-share/faq/detail',
|
||||
'/public-api/knowledge-share/faq/exportExcel'
|
||||
) THEN 'KNOWLEDGE_READ'
|
||||
WHEN resource.`request_interface` IN (
|
||||
'/public-api/knowledge-share/document/import/analyze',
|
||||
'/public-api/knowledge-share/document/import/preview',
|
||||
'/public-api/knowledge-share/document/import/commit',
|
||||
'/public-api/knowledge-share/document/import/task/create',
|
||||
'/public-api/knowledge-share/document/import/task/detail',
|
||||
'/public-api/knowledge-share/document/import/task/preview',
|
||||
'/public-api/knowledge-share/document/import/task/startIndex',
|
||||
'/public-api/knowledge-share/document/import/task/retryParse',
|
||||
'/public-api/knowledge-share/document/import/task/retryIndex',
|
||||
'/public-api/knowledge-share/faq/importExcel',
|
||||
'/public-api/knowledge-share/faq/downloadImportTemplate'
|
||||
) THEN 'KNOWLEDGE_IMPORT'
|
||||
WHEN resource.`request_interface` IN (
|
||||
'/public-api/knowledge-share/document/remove',
|
||||
'/public-api/knowledge-share/documentChunk/update',
|
||||
'/public-api/knowledge-share/documentChunk/remove',
|
||||
'/public-api/knowledge-share/faq/save',
|
||||
'/public-api/knowledge-share/faq/update',
|
||||
'/public-api/knowledge-share/faq/remove'
|
||||
) THEN 'KNOWLEDGE_MAINTENANCE'
|
||||
ELSE mapping.`action_scope`
|
||||
END
|
||||
WHERE mapping.`resource_type` = 'KNOWLEDGE';
|
||||
|
||||
SET @revoked_maintenance_mapping_count = (
|
||||
SELECT COUNT(*)
|
||||
FROM `tb_sys_api_key_resource_mapping`
|
||||
WHERE `resource_type` = 'KNOWLEDGE'
|
||||
AND `resource_target_id` IS NULL
|
||||
AND `action_scope` = 'KNOWLEDGE_MAINTENANCE'
|
||||
);
|
||||
|
||||
DELETE FROM `tb_sys_api_key_resource_mapping`
|
||||
WHERE `resource_type` = 'KNOWLEDGE'
|
||||
AND `resource_target_id` IS NULL
|
||||
AND `action_scope` = 'KNOWLEDGE_MAINTENANCE';
|
||||
|
||||
INSERT INTO `tb_sys_api_key_resource_mapping`
|
||||
(`id`, `api_key_id`, `api_key_resource_id`, `resource_type`,
|
||||
`resource_target_id`, `action_scope`)
|
||||
SELECT
|
||||
CAST(
|
||||
366900000000000000
|
||||
+ ROW_NUMBER() OVER (
|
||||
ORDER BY token.`api_key_id`,
|
||||
COALESCE(token.`resource_target_id`, 0),
|
||||
resource.`id`
|
||||
)
|
||||
AS UNSIGNED
|
||||
),
|
||||
token.`api_key_id`,
|
||||
resource.`id`,
|
||||
'KNOWLEDGE',
|
||||
token.`resource_target_id`,
|
||||
'KNOWLEDGE_IMPORT'
|
||||
FROM (
|
||||
SELECT DISTINCT mapping.`api_key_id`, mapping.`resource_target_id`
|
||||
FROM `tb_sys_api_key_resource_mapping` mapping
|
||||
WHERE mapping.`resource_type` = 'KNOWLEDGE'
|
||||
AND mapping.`action_scope` = 'KNOWLEDGE_IMPORT'
|
||||
) token
|
||||
JOIN `tb_sys_api_key_resource` resource
|
||||
ON resource.`request_interface` IN (
|
||||
'/public-api/knowledge-share/document/import/batch',
|
||||
'/public-api/knowledge-share/document/import/batch/status',
|
||||
'/public-api/knowledge-share/document/import/batch/retry'
|
||||
)
|
||||
LEFT JOIN `tb_sys_api_key_resource_mapping` existing
|
||||
ON existing.`api_key_id` = token.`api_key_id`
|
||||
AND existing.`api_key_resource_id` = resource.`id`
|
||||
AND existing.`resource_type` = 'KNOWLEDGE'
|
||||
AND existing.`resource_target_id` <=> token.`resource_target_id`
|
||||
AND existing.`action_scope` = 'KNOWLEDGE_IMPORT'
|
||||
WHERE existing.`id` IS NULL;
|
||||
|
||||
SELECT
|
||||
@migrated_knowledge_api_key_count AS `migrated_knowledge_api_key_count`,
|
||||
@revoked_maintenance_mapping_count AS `revoked_maintenance_mapping_count`;
|
||||
|
||||
ALTER TABLE `tb_document_import_batch`
|
||||
ADD COLUMN `caller_type` varchar(16) NULL DEFAULT NULL
|
||||
COMMENT '调用者类型' AFTER `knowledge_id`,
|
||||
ADD COLUMN `caller_id` bigint UNSIGNED NULL DEFAULT NULL
|
||||
COMMENT '调用者ID' AFTER `caller_type`,
|
||||
ADD COLUMN `idempotency_key_hash` char(64) NULL DEFAULT NULL
|
||||
COMMENT '提交幂等键SHA-256' AFTER `caller_id`,
|
||||
ADD COLUMN `request_digest` char(64) NULL DEFAULT NULL
|
||||
COMMENT '请求摘要SHA-256' AFTER `idempotency_key_hash`,
|
||||
ADD COLUMN `duplicate_policy` varchar(16) NULL DEFAULT NULL
|
||||
COMMENT '重复文件策略' AFTER `request_digest`,
|
||||
ADD COLUMN `requested_strategy_json` text NULL
|
||||
COMMENT '请求分块策略' AFTER `duplicate_policy`,
|
||||
ADD COLUMN `retry_generation` int NOT NULL DEFAULT 0
|
||||
COMMENT '重试代次' AFTER `requested_strategy_json`,
|
||||
ADD COLUMN `last_retry_key_hash` char(64) NULL DEFAULT NULL
|
||||
COMMENT '最近重试幂等键SHA-256' AFTER `retry_generation`,
|
||||
ADD COLUMN `last_retry_generation` int NOT NULL DEFAULT 0
|
||||
COMMENT '最近重试响应代次' AFTER `last_retry_key_hash`,
|
||||
ADD COLUMN `version` int NOT NULL DEFAULT 0
|
||||
COMMENT '乐观锁版本' AFTER `last_retry_generation`,
|
||||
ADD UNIQUE INDEX `uk_document_import_batch_caller_idempotency`
|
||||
(`caller_type`, `caller_id`, `idempotency_key_hash`) USING BTREE;
|
||||
|
||||
UPDATE `tb_document_import_batch`
|
||||
SET `caller_type` = 'ADMIN',
|
||||
`caller_id` = COALESCE(`created_by`, 0),
|
||||
`duplicate_policy` = COALESCE(`duplicate_policy`, 'SKIP')
|
||||
WHERE `caller_type` IS NULL;
|
||||
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
ADD COLUMN `content_sha256` char(64) NULL DEFAULT NULL
|
||||
COMMENT '文件内容SHA-256' AFTER `file_path`,
|
||||
ADD COLUMN `failure_code` varchar(64) NULL DEFAULT NULL
|
||||
COMMENT '稳定失败码' AFTER `error_summary`,
|
||||
ADD COLUMN `applied_strategy_code` varchar(64) NULL DEFAULT NULL
|
||||
COMMENT '实际分块策略编码' AFTER `failure_code`,
|
||||
ADD COLUMN `strategy_snapshot_json` text NULL
|
||||
COMMENT '分块策略快照' AFTER `applied_strategy_code`,
|
||||
DROP INDEX `idx_document_import_batch_item_batch_status`,
|
||||
ADD INDEX `idx_document_import_batch_item_batch_status`
|
||||
(`batch_id`, `status`, `modified`, `id`) USING BTREE;
|
||||
|
||||
ALTER TABLE `tb_document_import_task`
|
||||
ADD COLUMN `failure_code` varchar(64) NULL DEFAULT NULL
|
||||
COMMENT '稳定失败码' AFTER `error_summary`,
|
||||
ADD COLUMN `attempt_no` int NOT NULL DEFAULT 0
|
||||
COMMENT '执行尝试次数' AFTER `failure_code`,
|
||||
ADD COLUMN `execution_token` varchar(64) NULL DEFAULT NULL
|
||||
COMMENT '执行令牌' AFTER `attempt_no`,
|
||||
ADD COLUMN `lease_until` datetime NULL DEFAULT NULL
|
||||
COMMENT '租约到期时间' AFTER `execution_token`,
|
||||
ADD COLUMN `version` int NOT NULL DEFAULT 0
|
||||
COMMENT '乐观锁版本' AFTER `lease_until`,
|
||||
ADD INDEX `idx_document_import_task_phase_status_lease`
|
||||
(`phase`, `status`, `lease_until`, `created`, `id`) USING BTREE;
|
||||
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `tb_document_import_batch_retry_request`
|
||||
(
|
||||
`id` bigint UNSIGNED NOT NULL COMMENT '主键',
|
||||
`batch_id` bigint UNSIGNED NOT NULL COMMENT '批次ID',
|
||||
`retry_key_hash` char(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT '重试幂等键SHA-256',
|
||||
`request_digest` char(64) CHARACTER SET ascii COLLATE ascii_bin NOT NULL COMMENT '重试请求摘要SHA-256',
|
||||
`response_status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '首次领取后的响应状态',
|
||||
`retry_generation` int NOT NULL COMMENT '首次领取后的重试代次',
|
||||
`created` datetime NULL DEFAULT NULL COMMENT '创建时间',
|
||||
`modified` datetime NULL DEFAULT NULL COMMENT '修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_document_import_retry_batch_key` (`batch_id`, `retry_key_hash`) USING BTREE,
|
||||
INDEX `idx_document_import_retry_batch_created` (`batch_id`, `created`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
|
||||
COMMENT = '知识库文档批量导入重试幂等请求' ROW_FORMAT = DYNAMIC;
|
||||
@@ -0,0 +1,7 @@
|
||||
DROP TABLE IF EXISTS `tb_document_import_batch_retry_request`;
|
||||
|
||||
ALTER TABLE `tb_document_import_batch`
|
||||
DROP COLUMN `last_retry_key_hash`,
|
||||
DROP COLUMN `last_retry_generation`,
|
||||
ADD INDEX `idx_document_import_batch_status_modified`
|
||||
(`status`, `modified`, `id`) USING BTREE;
|
||||
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
ADD INDEX `idx_document_import_batch_item_cleanup`
|
||||
(`stage`, `status`, `modified`, `id`) USING BTREE;
|
||||
@@ -0,0 +1,16 @@
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
ADD COLUMN `storage_locator` varchar(2048) NULL DEFAULT NULL
|
||||
COMMENT '可恢复存储定位符' AFTER `file_path`,
|
||||
ADD COLUMN `cleanup_pending` tinyint(1) NOT NULL DEFAULT 0
|
||||
COMMENT '是否等待清理存储对象' AFTER `storage_locator`;
|
||||
|
||||
UPDATE `tb_document_import_batch_item`
|
||||
SET `cleanup_pending` = 1
|
||||
WHERE `stage` = 'UPLOAD'
|
||||
AND `status` IN ('UPLOADING', 'CANCELLED')
|
||||
AND `file_path` IS NOT NULL;
|
||||
|
||||
ALTER TABLE `tb_document_import_batch_item`
|
||||
DROP INDEX `idx_document_import_batch_item_cleanup`,
|
||||
ADD INDEX `idx_document_import_batch_item_cleanup_pending`
|
||||
(`cleanup_pending`, `modified`, `id`) USING BTREE;
|
||||
Reference in New Issue
Block a user