-- 文件中心独占数据库,其他服务只保存文件逻辑ID。 CREATE DATABASE IF NOT EXISTS baiyue_file DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; USE baiyue_file; CREATE TABLE IF NOT EXISTS file_object ( id BIGINT UNSIGNED NOT NULL COMMENT '文件ID(雪花ID)', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID', business_type VARCHAR(32) NULL COMMENT '关联业务类型', business_id VARCHAR(64) NULL COMMENT '关联业务逻辑ID', original_name VARCHAR(255) NOT NULL COMMENT '原始文件名', object_key VARCHAR(512) NOT NULL COMMENT '对象存储键', storage_provider VARCHAR(32) NOT NULL COMMENT '存储提供方', bucket_name VARCHAR(128) NOT NULL COMMENT '存储桶名称', content_type VARCHAR(128) NOT NULL COMMENT '文件内容类型', size_bytes BIGINT UNSIGNED NOT NULL COMMENT '文件字节数', sha256 CHAR(64) NULL COMMENT '文件SHA-256摘要', status VARCHAR(24) NOT NULL DEFAULT 'ACTIVE' COMMENT '文件状态', created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT UNSIGNED NOT NULL COMMENT '最后修改人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_file_tenant_object (tenant_id, object_key), KEY idx_file_tenant_business (tenant_id, business_type, business_id), KEY idx_file_tenant_created (tenant_id, created_at) ) ENGINE=InnoDB COMMENT='文件元数据表'; CREATE TABLE IF NOT EXISTS file_download_token ( id BIGINT UNSIGNED NOT NULL COMMENT '下载令牌ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID', file_id BIGINT UNSIGNED NOT NULL COMMENT '文件逻辑ID', token_hash CHAR(64) NOT NULL COMMENT '下载令牌SHA-256摘要', expires_at DATETIME(3) NOT NULL COMMENT '过期时间', max_downloads INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '最大下载次数', download_count INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已下载次数', revoked_at DATETIME(3) NULL COMMENT '撤销时间', created_by BIGINT UNSIGNED NOT NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY (id), UNIQUE KEY uk_download_token_hash (token_hash), KEY idx_download_file (tenant_id, file_id), KEY idx_download_expiry (expires_at) ) ENGINE=InnoDB COMMENT='临时下载授权令牌表'; CREATE TABLE IF NOT EXISTS file_download_log ( id BIGINT UNSIGNED NOT NULL COMMENT '下载日志ID', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID', file_id BIGINT UNSIGNED NOT NULL COMMENT '文件逻辑ID', user_id BIGINT UNSIGNED NULL COMMENT '下载用户ID', request_id VARCHAR(64) NULL COMMENT '请求ID', client_ip VARCHAR(64) NULL COMMENT '客户端IP', result VARCHAR(16) NOT NULL COMMENT '下载结果', failure_reason VARCHAR(500) NULL COMMENT '失败原因', downloaded_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '下载时间', PRIMARY KEY (id), KEY idx_download_log_file (tenant_id, file_id, downloaded_at), KEY idx_download_log_user (tenant_id, user_id, downloaded_at) ) ENGINE=InnoDB COMMENT='文件下载审计日志表'; CREATE TABLE IF NOT EXISTS file_export_task ( id BIGINT UNSIGNED NOT NULL COMMENT '导出任务ID(雪花ID)', tenant_id BIGINT UNSIGNED NOT NULL COMMENT '申请人所属租户ID,平台任务为0', app_code VARCHAR(24) NOT NULL COMMENT '申请端:PLATFORM或MERCHANT', task_no VARCHAR(40) NOT NULL COMMENT '导出任务编号', export_type VARCHAR(64) NOT NULL COMMENT '导出类型', format VARCHAR(16) NOT NULL DEFAULT 'XLSX' COMMENT '导出格式', task_name VARCHAR(128) NOT NULL COMMENT '任务名称', parameters_json JSON NOT NULL COMMENT '筛选条件快照', status VARCHAR(24) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/RUNNING/SUCCEEDED/FAILED/EXPIRED', total_rows BIGINT UNSIGNED NULL COMMENT '预计总行数', processed_rows BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已处理行数', file_name VARCHAR(255) NULL COMMENT '下载文件名', object_key VARCHAR(512) NULL COMMENT '存储对象键', content_type VARCHAR(128) NULL COMMENT '文件类型', size_bytes BIGINT UNSIGNED NULL COMMENT '文件字节数', failure_message VARCHAR(1000) NULL COMMENT '失败原因', dispatch_version INT NOT NULL DEFAULT 1 COMMENT '派发版本,仅执行重试时递增', attempt_count INT NOT NULL DEFAULT 0 COMMENT '已执行尝试次数', max_attempts INT NOT NULL DEFAULT 3 COMMENT '自动重试上限', next_retry_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '允许执行的最早时间', lease_owner VARCHAR(128) NULL COMMENT '当前执行实例标识', lease_until DATETIME(3) NULL COMMENT '执行租约截止时间', last_heartbeat_at DATETIME(3) NULL COMMENT '最后心跳时间', execution_deadline_at DATETIME(3) NULL COMMENT '本次执行截止时间', requested_by BIGINT UNSIGNED NOT NULL COMMENT '申请用户ID', requested_username VARCHAR(128) NULL COMMENT '申请账号快照', requested_at DATETIME(3) NOT NULL COMMENT '申请时间', started_at DATETIME(3) NULL COMMENT '开始时间', completed_at DATETIME(3) NULL COMMENT '完成时间', expires_at DATETIME(3) NULL COMMENT '文件过期时间', created_by BIGINT UNSIGNED NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', updated_by BIGINT UNSIGNED NULL COMMENT '最后修改人ID', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间', deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除标记', version INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id), UNIQUE KEY uk_file_export_task_no (task_no), KEY idx_file_export_owner (tenant_id, app_code, requested_by, requested_at), KEY idx_file_export_status (status, requested_at), KEY idx_file_export_dispatch (status, next_retry_at, id), KEY idx_file_export_lease (status, lease_until), KEY idx_file_export_expiry (status, expires_at) ) ENGINE=InnoDB COMMENT='公共异步导出任务表'; CREATE TABLE IF NOT EXISTS file_export_task_guard ( guard_key VARCHAR(64) NOT NULL COMMENT '任务创建串行化锁键', updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), PRIMARY KEY (guard_key) ) ENGINE=InnoDB COMMENT='导出任务创建并发保护表:低频创建入口使用单行锁保证重复提交及活动上限'; INSERT IGNORE INTO file_export_task_guard (guard_key) VALUES ('GLOBAL_CREATE'); CREATE TABLE IF NOT EXISTS file_export_outbox ( id BIGINT UNSIGNED NOT NULL COMMENT 'Outbox记录ID', event_id VARCHAR(64) NOT NULL COMMENT '投递意图唯一标识', task_id BIGINT UNSIGNED NOT NULL COMMENT '关联导出任务ID', dispatch_version INT NOT NULL COMMENT '任务派发版本', topic VARCHAR(128) NOT NULL COMMENT '目标Topic', tag VARCHAR(64) NOT NULL COMMENT '消息Tag', message_key VARCHAR(64) NOT NULL COMMENT '消息Key', payload_json JSON NOT NULL COMMENT '命令消息体', status VARCHAR(24) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/CLAIMED/SENT/QUARANTINED', attempt_count INT NOT NULL DEFAULT 0 COMMENT '累计发送尝试次数', next_retry_at DATETIME(3) NOT NULL COMMENT '允许发送的最早时间', lease_owner VARCHAR(128) NULL COMMENT '领取实例标识', lease_until DATETIME(3) NULL COMMENT '领取租约截止时间', sent_at DATETIME(3) NULL COMMENT '发送成功时间', last_error VARCHAR(1000) NULL COMMENT '最后发送错误', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), PRIMARY KEY (id), UNIQUE KEY uk_file_export_outbox_event (event_id), UNIQUE KEY uk_file_export_outbox_task_version (task_id, dispatch_version), KEY idx_file_export_outbox_publish (status, next_retry_at, id), KEY idx_file_export_outbox_task (task_id, dispatch_version, status, sent_at) ) ENGINE=InnoDB COMMENT='导出命令事务Outbox表';