无尘阁日记

无尘阁日记

跟AI沟通完成一个跟三方OA的对接工作之四
2026-03-12

我问:

-- =========================================================

-- 1. 报备主表

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_record`;

CREATE TABLE `bridge_filing_record`

(

`id`                    BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`             BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`            BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`enterprise_code`       VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用编码',


`trace_id`              VARCHAR(64) NOT NULL COMMENT '整笔报备链路号',

`last_request_id`     VARCHAR(64) DEFAULT NULL COMMENT '最新请求流水号',


`oa_project_id`         BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',

`oa_project_code`       VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

`project_group_id`      BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',

`submission_id`         BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',


`filing_no`             VARCHAR(64) DEFAULT NULL COMMENT '我方报备编号',

`external_filing_no`    VARCHAR(128) DEFAULT NULL COMMENT '外部系统返回的报备号/备案号',


`filing_initiator`      VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',

`filing_mode`           VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',


`account_source`        VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',

`account_config_id`     BIGINT UNSIGNED DEFAULT NULL COMMENT '使用的本地账号配置ID',


`source_data_json`      JSON DEFAULT NULL COMMENT 'OA来源业务数据JSON快照,不含文件二进制',

`submit_data_json`      JSON DEFAULT NULL COMMENT '最终提交给CAS业务数据JSON快照,不含文件二进制',

`account_snapshot_json` JSON DEFAULT NULL COMMENT '本次使用账号快照,建议脱敏存储',


`has_field_override`    TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否存在字段覆盖修改:0否1是',


`filing_status`         VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '报备状态:PENDING/EDITING/READY/SUBMITTING/SUBMITTED/SUCCESS/FAILED',

`association_status`    VARCHAR(32) DEFAULT NULL COMMENT '评协状态:NOT_SUBMITTED/SUBMITTING/SUBMITTED/SUCCESS/FAILED/TIMEOUT',


`filing_result_code`    VARCHAR(64) DEFAULT NULL COMMENT '结果码',

`filing_result_msg`     VARCHAR(1000) DEFAULT NULL COMMENT '结果说明',


`request_body`          JSON DEFAULT NULL COMMENT 'OA向我方报备时原始请求体,不含文件二进制',

`response_body`         JSON DEFAULT NULL COMMENT 'OA向我方报备时原始响应体',

`remark`                VARCHAR(1000) DEFAULT NULL COMMENT '备注',


`is_deleted`            TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`            DATETIME DEFAULT NULL COMMENT '删除时间',


`created_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',

`updated_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',

`created_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`updated_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',


PRIMARY KEY (`id`),

UNIQUE KEY `uk_trace_id` (`trace_id`),

KEY `idx_partner_id` (`partner_id`),

KEY `idx_enterprise_code` (`enterprise_code`),

KEY `idx_submission_id` (`submission_id`),

KEY `idx_oa_project_id` (`oa_project_id`),

KEY `idx_project_group_id` (`project_group_id`),

KEY `idx_filing_status` (`filing_status`),

KEY `idx_association_status` (`association_status`),

KEY `idx_filing_initiator` (`filing_initiator`),

KEY `idx_filing_mode` (`filing_mode`),

KEY `idx_is_deleted` (`is_deleted`),

KEY `idx_created_at` (`created_at`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';



-- =========================================================

-- 2. 报备详情表,1=》2,1对多关系,可编辑后再提交报备

-- 报告主体按项目组维度体现

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_detail`;

CREATE TABLE `bridge_filing_detail`

(

`id`                        BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`filing_record_id`          BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',

`detail_no`                 INT NOT NULL DEFAULT 1 COMMENT '明细序号',


`oa_project_id`         BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',

`oa_project_code`       VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',


`report_project_group_id`   BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',

`report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

`report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',


`contract_id`               BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',

`contract_no`               VARCHAR(128) DEFAULT NULL COMMENT '合同编号',

`contract_name`             VARCHAR(255) DEFAULT NULL COMMENT '合同名称',


`report_id`                 BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',

`report_no`                 VARCHAR(128) DEFAULT NULL COMMENT '报告号',

`report_name`               VARCHAR(255) DEFAULT NULL COMMENT '报告名称',


`client_name`               VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',

`sign_appraiser_names`      VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',


`request_id`                VARCHAR(64) DEFAULT NULL COMMENT '相关请求流水号',

`source_detail_json`        JSON DEFAULT NULL COMMENT '来源明细JSON快照,不含文件二进制',

`final_detail_json`         JSON DEFAULT NULL COMMENT '最终提交明细JSON快照,不含文件二进制',

`detail_json`               JSON DEFAULT NULL COMMENT '扩展数据',


`is_deleted`                TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`                DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`updated_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',


PRIMARY KEY (`id`),

KEY `idx_filing_record_id` (`filing_record_id`),

KEY `idx_oa_project_id` (`oa_project_id`),

KEY `idx_report_project_group_id` (`report_project_group_id`),

KEY `idx_contract_no` (`contract_no`),

KEY `idx_report_no` (`report_no`),

KEY `idx_request_id` (`request_id`),

KEY `idx_is_deleted` (`is_deleted`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备详情表';


这俩表我感觉有问题。首先OA推送给我们报备,我得记录整个链路状态,我再提交给评协也得记录,相当于我这里转发。另外我一次报备之后,可能成功也可能失败,要允许用户对此次报备记录修改后再次在智评云系统继续提交报备,还得记录这个报备的所有详情。请你在不额外增加表的情况下合理设计这两张表。

AI答:

你这两个表现在最大的症结,不是字段多不多,而是一张表里混了“当前态”和“历史态”,结果会导致三个问题:

一、当前设计的核心问题

1. 主表没有把“两段链路”拆开

你这里实际上有两段链路:

1. OA → 智评云

这是“接收报备”的链路。

2. 智评云 → 评协

这是“正式提交报备”的链路。

这两段链路不是一回事,但你现在只用 filing_statusassociation_status 去兜,语义还是不够清楚。
后面一旦出现:

  • OA推送成功,但我方落库失败

  • 我方落库成功,但还没提交评协

  • 提交评协失败,用户改完后再次提交

  • 同一版本重复提交

  • 修改后形成新版本再次提交

状态就会越来越乱。

2. 主表没有明确“当前编辑版本”和“提交尝试次数”

你现在说“允许用户修改后再次提交”,那其实至少要区分两层:

1)数据版本

用户改过一次,内容就变了,这叫新版本

2)提交尝试

同一个版本,第一次提交失败,第二次再点提交,这叫同版本下的再次尝试

如果没有这两个概念,后面你根本分不清:

  • 这次失败是“老数据重试”

  • 还是“修改后新数据再次提交”

3. 详情表没有承载“历史快照”的能力

你现在的 bridge_filing_detail 更像“当前明细表”,不是“版本化明细表”。

但既然你又要求:

  • 可以编辑

  • 可以再次提交

  • 还要保留每次报备的所有详情

那详情表就不能只存“当前那一份”,而必须支持按版本保留快照

也就是说,详情表不能只是“报备主表1对多明细”,而应该是:

报备单 1 对 多个版本明细快照

二、合理的设计思路

在“不增加新表”的前提下,最稳妥的方案是:

方案总原则

1. 主表只负责“当前主状态 + 整体链路汇总 + 最近一次提交信息”

也就是主表保留“当前态”。

2. 详情表负责“每个版本的明细快照”

用户每次修改并保存,都生成一批新的 detail 记录,挂在新的 data_version 下。

3. 主表再补一个 JSON 字段,记录所有提交尝试历史

因为不能加日志表,那就只能让主表存:

  • OA接收事件

  • 每次提交评协的请求/响应摘要

  • 每次失败原因

  • 重试记录

也就是一个 lifecycle_log_json

这样就能满足:

  • 不加新表

  • 能看当前状态

  • 能看历史版本

  • 能看每次提交尝试

三、建议的字段设计逻辑

1. 主表应该表达什么

主表表达的是“这张报备单”的整体情况:

基础身份

租户、对接方、项目组、报备单号、trace_id

OA接收状态

OA是否推送成功、解析是否成功、落库是否成功

当前编辑状态

当前版本号、是否已编辑、当前是否可提交

评协提交状态

最近一次提交结果、提交次数、成功失败原因

历史轨迹

所有事件日志 JSON

2. 明细表应该表达什么

详情表表达的是:

某一张报备单,在某一个版本下,有哪些明细内容

因此必须加:

data_version

第几版数据

is_current

是否当前有效版本

detail_status

该明细是否有效、是否已删除

这样用户修改后,不是直接改原记录,而是:

  • 老版本明细保留

  • 新版本复制一份再改

  • 主表 current_version 指向新版本

这就是最稳的“版本快照模式”。

四、我建议你直接改成下面这个 SQL

下面这套就是按你现在的业务重新收敛后的版本。
重点是:

  • 主表表示当前态

  • 详情表表示版本快照

  • 不增加第三张表

  • 通过 JSON 保存链路历史

-- =========================================================
-- 1. 报备主表
-- 说明:
-- 1)一条记录代表“一张报备单”的完整生命周期
-- 2)支持 OA 推送进入、智评云编辑、提交评协、失败后修改再提交
-- 3)主表保存当前状态 + 最近一次提交信息 + 整体历史轨迹
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record`
(
    `id`                        BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
    `tenant_id`                 BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
    `partner_id`                BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
    `enterprise_code`           VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用代码',

    `trace_id`                  VARCHAR(64) NOT NULL COMMENT '整笔报备全链路号,贯穿OA->智评云->评协',
    `filing_no`                 VARCHAR(64) NOT NULL COMMENT '我方报备单号',
    `external_filing_no`        VARCHAR(128) DEFAULT NULL COMMENT '评协返回的报备号/备案号',

    `oa_project_id`             BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
    `oa_project_code`           VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
    `project_group_id`          BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
    `project_group_code`        VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
    `project_group_name`        VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
    `submission_id`             BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

    `filing_initiator`          VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',
    `filing_mode`               VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',

    `account_source`            VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
    `account_config_id`         BIGINT UNSIGNED DEFAULT NULL COMMENT '使用的本地账号配置ID',
    `account_snapshot_json`     JSON DEFAULT NULL COMMENT '本次使用账号快照,建议脱敏',

    `current_version`           INT NOT NULL DEFAULT 1 COMMENT '当前编辑版本号,从1开始,用户每次保存修改+1',
    `latest_submit_version`     INT DEFAULT NULL COMMENT '最近一次提交对应的数据版本号',
    `submit_attempt_count`      INT NOT NULL DEFAULT 0 COMMENT '累计提交评协次数',

    `oa_receive_status`         VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT 'OA接收状态:PENDING/RECEIVED/PARSED/FAILED',
    `filing_status`             VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '当前报备状态:DRAFT/EDITING/READY/SUBMITTING/SUCCESS/FAILED',
    `association_status`        VARCHAR(32) NOT NULL DEFAULT 'NOT_SUBMITTED' COMMENT '评协提交状态:NOT_SUBMITTED/SUBMITTING/SUBMITTED/SUCCESS/FAILED/TIMEOUT',

    `has_field_override`        TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否存在人工字段覆盖修改:0否1是',

    `oa_request_id`             VARCHAR(64) DEFAULT NULL COMMENT 'OA推送请求流水号',
    `last_request_id`           VARCHAR(64) DEFAULT NULL COMMENT '最近一次提交评协请求流水号',

    `oa_request_body`           JSON DEFAULT NULL COMMENT 'OA推送原始请求体快照,不含文件二进制',
    `oa_response_body`          JSON DEFAULT NULL COMMENT '我方响应OA的原始响应体',
    `source_data_json`          JSON DEFAULT NULL COMMENT 'OA来源业务数据快照,不含文件二进制',
    `current_submit_data_json`  JSON DEFAULT NULL COMMENT '当前版本最终待提交业务数据快照,不含文件二进制',

    `last_request_body`         JSON DEFAULT NULL COMMENT '最近一次提交评协请求体快照,不含文件二进制',
    `last_response_body`        JSON DEFAULT NULL COMMENT '最近一次提交评协响应体快照',
    `last_result_code`          VARCHAR(64) DEFAULT NULL COMMENT '最近一次提交结果码',
    `last_result_msg`           VARCHAR(1000) DEFAULT NULL COMMENT '最近一次提交结果说明',

    `success_at`                DATETIME DEFAULT NULL COMMENT '最终成功时间',
    `last_submit_at`            DATETIME DEFAULT NULL COMMENT '最近一次提交时间',

    `lifecycle_log_json`        JSON DEFAULT NULL COMMENT '全生命周期事件日志JSON数组,记录OA接收、编辑、提交、重试、成功失败等摘要',

    `remark`                    VARCHAR(1000) DEFAULT NULL COMMENT '备注',

    `is_deleted`                TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
    `deleted_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
    `deleted_at`                DATETIME DEFAULT NULL COMMENT '删除时间',

    `created_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
    `updated_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
    `created_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updated_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_trace_id` (`trace_id`),
    UNIQUE KEY `uk_filing_no` (`filing_no`),
    KEY `idx_partner_id` (`partner_id`),
    KEY `idx_enterprise_code` (`enterprise_code`),
    KEY `idx_submission_id` (`submission_id`),
    KEY `idx_oa_project_id` (`oa_project_id`),
    KEY `idx_project_group_id` (`project_group_id`),
    KEY `idx_oa_receive_status` (`oa_receive_status`),
    KEY `idx_filing_status` (`filing_status`),
    KEY `idx_association_status` (`association_status`),
    KEY `idx_filing_initiator` (`filing_initiator`),
    KEY `idx_filing_mode` (`filing_mode`),
    KEY `idx_is_deleted` (`is_deleted`),
    KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';


-- =========================================================
-- 2. 报备详情表
-- 说明:
-- 1)一条记录代表“某张报备单在某个版本下的一条明细”
-- 2)用户修改后,不直接覆盖原明细,而是生成新版本快照
-- 3)通过 data_version + is_current 保留完整历史
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail`
(
    `id`                        BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
    `filing_record_id`          BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
    `data_version`              INT NOT NULL DEFAULT 1 COMMENT '数据版本号,对应主表current_version',
    `detail_no`                 INT NOT NULL DEFAULT 1 COMMENT '明细序号,同一版本内从1开始',
    `is_current`                TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前有效版本明细:0否1是',

    `oa_project_id`             BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
    `oa_project_code`           VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

    `report_project_group_id`   BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',
    `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',
    `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

    `contract_id`               BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
    `contract_no`               VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
    `contract_name`             VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

    `report_id`                 BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
    `report_no`                 VARCHAR(128) DEFAULT NULL COMMENT '报告号',
    `report_name`               VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

    `client_name`               VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
    `sign_appraiser_names`      VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',

    `source_type`               VARCHAR(32) NOT NULL DEFAULT 'OA_PUSH' COMMENT '明细来源:OA_PUSH/MANUAL_ADD/MANUAL_EDIT/COPY_FROM_PREVIOUS',
    `detail_status`             VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '明细状态:ACTIVE/DELETED',

    `source_detail_json`        JSON DEFAULT NULL COMMENT '来源明细快照,不含文件二进制',
    `final_detail_json`         JSON DEFAULT NULL COMMENT '当前版本最终提交明细快照,不含文件二进制',
    `detail_json`               JSON DEFAULT NULL COMMENT '扩展字段JSON',

    `is_deleted`                TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否1是',
    `deleted_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
    `deleted_at`                DATETIME DEFAULT NULL COMMENT '删除时间',

    `created_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
    `updated_by`                BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
    `created_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `updated_at`                DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

    PRIMARY KEY (`id`),
    KEY `idx_filing_record_id` (`filing_record_id`),
    KEY `idx_data_version` (`data_version`),
    KEY `idx_is_current` (`is_current`),
    KEY `idx_oa_project_id` (`oa_project_id`),
    KEY `idx_report_project_group_id` (`report_project_group_id`),
    KEY `idx_contract_no` (`contract_no`),
    KEY `idx_report_no` (`report_no`),
    KEY `idx_detail_status` (`detail_status`),
    KEY `idx_is_deleted` (`is_deleted`),
    KEY `idx_record_version_current` (`filing_record_id`, `data_version`, `is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备详情版本快照表';

五、这套设计怎么落业务

1. OA首次推送时

主表插入一条:

  • current_version = 1

  • oa_receive_status = RECEIVEDPARSED

  • filing_status = DRAFTREADY

  • association_status = NOT_SUBMITTED

详情表插入版本1的所有明细:

  • data_version = 1

  • is_current = 1

2. 用户第一次提交评协时

主表更新:

  • submit_attempt_count + 1

  • latest_submit_version = current_version

  • association_status = SUBMITTING

  • 请求完后更新 last_request_bodylast_response_bodylast_result_codelast_result_msg

如果成功:

  • association_status = SUCCESS

  • filing_status = SUCCESS

  • success_at = now()

如果失败:

  • association_status = FAILED

  • filing_status = FAILED

3. 失败后用户修改再提交时

这一步最关键。

不是直接改版本1的 detail,而是:

第一步

主表:

  • current_version = current_version + 1

  • filing_status = EDITING

第二步

把旧版本当前明细复制一份出来,形成新版本:

  • 原版本 detail 的 is_current = 0

  • 新插入的 detail:

    • data_version = 新版本号

    • is_current = 1

    • source_type = COPY_FROM_PREVIOUS

第三步

用户在新版本上编辑 detail

第四步

再次提交时:

  • latest_submit_version = 新版本号

  • submit_attempt_count + 1

这样你就完整区分了:

  • 第1版提交失败

  • 第2版修改后再提交成功


六、为什么我不建议你把“每次提交都复制一份 detail”

因为那样会把“版本”和“尝试”混在一起,数据会膨胀得很厉害。

要分清:

版本

数据内容变了

尝试

数据没变,只是再次发送

所以最合理的是:

内容历史

放在 bridge_filing_detaildata_version

提交历史

放在主表 lifecycle_log_json

比如这个 JSON 可以这样存:

[
  {
    "event": "OA_RECEIVED",
    "time": "2026-03-12 10:00:00",
    "request_id": "oa_001",
    "message": "OA推送成功"
  },
  {
    "event": "SUBMIT_ASSOCIATION",
    "time": "2026-03-12 10:10:00",
    "request_id": "cas_001",
    "version": 1,
    "attempt": 1,
    "result_code": "500",
    "result_msg": "网络超时"
  },
  {
    "event": "EDIT_SAVED",
    "time": "2026-03-12 10:20:00",
    "version": 2,
    "message": "用户修改后保存"
  },
  {
    "event": "SUBMIT_ASSOCIATION",
    "time": "2026-03-12 10:30:00",
    "request_id": "cas_002",
    "version": 2,
    "attempt": 2,
    "result_code": "200",
    "result_msg": "提交成功"
  }
]

这样你不用新表,也能把链路和提交过程保住。

七、你原表里我建议删掉或弱化的点

1. request_id 不要放 detail 里做核心字段

因为请求是“某次提交行为”的属性,不是“某条明细”的属性。
明细表里放这个意义不大,还会误导。

2. filing_result_codefiling_result_msg

建议改成 last_result_codelast_result_msg
因为它本质上表达的是“最近一次提交结果”,不是“整张单永久结果”。

3. response_body

原来你主表里这个名字太泛了。
到底是 OA 响应,还是评协响应,后期一定混乱。
所以我给你拆成:

  • oa_response_body

  • last_response_body

更清楚。

八、这套设计最适合你的原因

因为你的业务本质上不是“简单转发”,而是:

第一层:接单

OA把数据推过来,你接住

第二层:加工

智评云允许人改数据

第三层:投递

再往评协提交

第四层:返工

失败后再改再投

这已经是一个很典型的“单据生命周期 + 版本化快照”模型。
所以一定要把:

  • 当前态

  • 版本态

  • 尝试态

这三层拆开。

而我上面这套设计,刚好就在两张表、不加新表的约束下,把这三层尽量拆清楚了。

你要的话,我下一步可以继续直接帮你把这套表再往前推进一层,给你补一版:

“配套的状态流转说明 + 增删改查操作规则 + 提交失败后二次编辑的伪代码/SQL流程”

我问:

请简化下逻辑,按照最科学最合适的工程实施方案来设计,可适当增加表,主要是容易理解,且容易维护。

AI答:

可以。你这次的要求其实非常明确:

不是“尽量少表”,而是要最科学、最容易实施、最容易理解、最容易维护

那从工程角度讲,最合适的方案其实不是硬把所有东西塞进两张表,而是把概念拆开。
否则后面一定会出现:

  • 状态混乱

  • 字段语义不清

  • 修改和重提逻辑难懂

  • 查询历史麻烦

  • 运维排障困难

所以我建议你采用一个非常经典、也非常稳的四层模型:

一、最推荐的工程方案:四张表

1. bridge_filing_record

报备单主表

它只表示一件事:

“有这么一张报备单”

这里放“当前态”“归属信息”“汇总结果”。

2. bridge_filing_version

报备数据版本表

它只表示一件事:

“这张报备单在某一次编辑保存后,形成了一个数据版本”

只要用户改了内容并保存,就产生一个新版本。

3. bridge_filing_detail

报备版本明细表

它只表示一件事:

“某个版本下具体有哪些明细”

也就是说,detail 不再直接挂主表,而是挂版本表。

4. bridge_filing_submit_log

提交日志表

它只表示一件事:

“某个版本,向评协提交过几次,每次结果是什么”

这样“编辑版本”和“提交尝试”彻底分开。

这才是最清晰的。

二、为什么这是最科学的

你这个业务其实天然有三层东西:

第一层:单据本身

就是“这张报备单”。

第二层:数据版本

用户改一次,数据就变一版。

第三层:提交尝试

同一版数据可能提交多次。

这三层不是一个概念,硬揉在一起,后面必乱。

所以正确做法就是:

主表管“单”

版本表管“内容版本”

明细表管“版本里的具体行”

提交日志表管“发送记录”

这套结构最大的好处是:

1. 语义特别清楚

每张表只干一件事。

2. 开发容易写

增删改查逻辑顺。

3. 排障容易查

失败到底是哪个版本、哪次提交,一眼就清楚。

4. 后期扩展简单

将来要加回调、加文件、加异步任务,也很好接。

三、建议你这样理解整个流程

1. OA推送一笔报备过来

做两件事:

创建主表一条记录

表示“新来了一张报备单”。

同时创建版本1

把 OA 推过来的原始数据,落成 version=1。

并把这一版的明细写入 detail 表。

2. 用户在智评云里修改内容

不是直接改主表,也不是直接改老明细。

而是:

基于当前版本复制出一个新版本

比如从 v1 复制到 v2。

用户修改的是 v2

这样历史版本 v1 永远保留。

3. 用户点击提交评协

不改版本,只新增一条提交日志:

  • 提交的是哪个版本

  • 第几次尝试

  • 请求内容

  • 响应内容

  • 成功还是失败

如果成功,就把主表状态改成成功。
如果失败,主表状态改成失败,但版本还在。

4. 用户失败后再次修改

再从当前版本复制出 v3。
然后提交时,日志里记“提交的是 v3”。

整个链路就非常清晰。

四、推荐的状态设计

要想容易维护,状态不要搞太多,更不要一堆交叉状态。

我建议主表只保留一个“业务主状态”,版本表保留一个“版本状态”,提交日志保留一个“提交结果状态”。

1. 主表状态 record_status

建议就这几个:

DRAFT           草稿中
READY           已准备好,可提交
SUBMITTING      提交中
SUCCESS         提交成功
FAILED          最近一次提交失败
CLOSED          已关闭(可选)

够了,不要再膨胀。

2. 版本状态 version_status

DRAFT           编辑中
READY           已定稿,可提交
SUBMITTED       这个版本已经发起过提交
DISCARDED       已废弃

3. 提交日志状态 submit_status

SUBMITTING      提交中
SUCCESS         成功
FAILED          失败
TIMEOUT         超时

这样层级非常清楚。

五、四张表的职责边界

1. 主表:bridge_filing_record

这张表只放“这张单”的当前信息,不存太细。

建议放这些:

基础归属

租户、对接方、企业、项目组、OA项目等

当前引用

当前版本号、当前版本ID、最新成功版本ID、最新提交日志ID

当前状态

主状态、最新结果码、最新结果信息

外部标识

我方报备单号、评协报备号、trace_id

来源标识

OA_PUSH、手工创建等

一句话说,主表是“总入口”和“当前态视图”。

2. 版本表:bridge_filing_version

这张表是核心。

每次编辑保存后,产生一条新版本。

建议放这些:

属于哪张单

filing_record_id

第几版

version_no

来源

是 OA 初始导入,还是复制旧版,还是人工新建

当前快照

整版 JSON 快照、账号快照、提交快照

是否当前版

is_current

版本状态

version_status

谁创建的

创建人、更新时间

一句话说,版本表是“内容历史”。

3. 明细表:bridge_filing_detail

它只从属于版本,不从属于主表。

这样就非常干净:

一个版本有多条明细

建议放这些:

归属版本

filing_version_id

明细序号

detail_no

合同、报告、项目组信息

这些具体业务字段

明细快照

来源明细、最终明细

明细状态

有效、删除

一句话说,detail 就是“版本里的行数据”。

4. 提交日志表:bridge_filing_submit_log

这是你现在最缺的。

因为你真正要追踪的是:

  • 提交的是哪一版

  • 第几次提交

  • 请求发给谁

  • 请求报文是什么

  • 响应是什么

  • 成功还是失败

  • 耗时多少

  • 失败原因是什么

这些天然就该在一张独立日志表里。

一句话说,它是“对外发送历史”。

六、推荐表结构示意

下面我给你一版简化但能直接落地的字段设计。

1. 报备主表

DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备链路号',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回报备号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
  `project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
  `project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
  `project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前版本号',
  `latest_submit_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次提交日志ID',
  `latest_success_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次成功版本ID',

  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '主状态:DRAFT/READY/SUBMITTING/SUCCESS/FAILED/CLOSED',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次结果说明',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_partner_id` (`partner_id`),
  KEY `idx_project_group_id` (`project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';

2. 报备版本表

DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1开始递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID,首次版本为空',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT/COPY_EDIT/MANUAL_CREATE',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT/READY/SUBMITTED/DISCARDED',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本:0否1是',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '账号配置ID',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '账号快照',

  `source_data_json` JSON DEFAULT NULL COMMENT '原始来源数据快照',
  `final_data_json` JSON DEFAULT NULL COMMENT '当前版本最终数据快照',
  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否有字段覆盖修改:0否1是',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`, `version_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_parent_version_id` (`parent_version_id`),
  KEY `idx_version_status` (`version_status`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';

3. 报备明细表

DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '报备版本ID',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',

  `detail_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '明细状态:ACTIVE/DELETED',
  `source_detail_json` JSON DEFAULT NULL COMMENT '原始明细快照',
  `final_detail_json` JSON DEFAULT NULL COMMENT '最终明细快照',
  `detail_json` JSON DEFAULT NULL COMMENT '扩展数据',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_report_project_group_id` (`report_project_group_id`),
  KEY `idx_contract_no` (`contract_no`),
  KEY `idx_report_no` (`report_no`),
  KEY `idx_detail_status` (`detail_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';

4. 提交日志表

DROP TABLE IF EXISTS `bridge_filing_submit_log`;
CREATE TABLE `bridge_filing_submit_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '提交时使用的版本ID',
  `submit_no` INT NOT NULL COMMENT '该报备单的第几次提交尝试',

  `request_id` VARCHAR(64) NOT NULL COMMENT '本次请求流水号',
  `submit_target` VARCHAR(32) NOT NULL DEFAULT 'ASSOCIATION' COMMENT '提交目标:ASSOCIATION',
  `submit_status` VARCHAR(32) NOT NULL DEFAULT 'SUBMITTING' COMMENT '提交状态:SUBMITTING/SUCCESS/FAILED/TIMEOUT',

  `request_body` JSON DEFAULT NULL COMMENT '请求体快照',
  `response_body` JSON DEFAULT NULL COMMENT '响应体快照',
  `result_code` VARCHAR(64) DEFAULT NULL COMMENT '结果码',
  `result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '结果说明',

  `started_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '发起时间',
  `finished_at` DATETIME DEFAULT NULL COMMENT '结束时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_id` (`request_id`),
  UNIQUE KEY `uk_record_submit_no` (`filing_record_id`, `submit_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_submit_status` (`submit_status`),
  KEY `idx_started_at` (`started_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备提交日志表';

七、这套方案怎么用

1. OA推送时

做这三步:

第一步

插入 bridge_filing_record

第二步

插入 bridge_filing_version 一条,version_no = 1

第三步

插入这版对应的 bridge_filing_detail 多条

最后把主表的:

  • current_version_id

  • current_version_no

更新成版本1。

2. 用户修改时

做这四步:

第一步

找到当前版本,比如 v1

第二步

复制生成 v2
插入 bridge_filing_version

第三步

把 v1 的所有 detail 复制一份到 v2

第四步

用户在 v2 上改

然后把主表 current_version_id/current_version_no 指向 v2。

3. 用户提交时

做这三步:

第一步

bridge_filing_submit_log 插一条
记录本次提交的是哪个 version

第二步

请求评协

第三步

更新提交日志结果,同时回写主表:

  • 成功:record_status = SUCCESS

  • 失败:record_status = FAILED

如果成功,还可以把:

  • latest_success_version_id

  • external_filing_no

更新到主表。

八、这套方案比“两张表硬扛”好在哪

最关键的不是“规范”,而是你团队未来写代码会轻松很多

场景一:查看当前报备内容

查主表 current_version_id,再查对应版本和详情。

很自然。

场景二:看这笔报备改过几次

直接查 version 表。

场景三:看这笔报备向评协提交过几次

直接查 submit_log 表。

场景四:看第2次提交用的是哪个版本

submit_log 里直接有 filing_version_id

场景五:排查为什么失败

直接查 submit_log 的请求报文、响应报文、结果码。

不需要从一堆 JSON 里扒。

九、如果你还想再简化一点

如果你觉得四张表还是略多,那我告诉你最少还能怎么压:

压缩版三张表

1. bridge_filing_record

主表

2. bridge_filing_version

版本表,里面顺带放整版 JSON 快照

3. bridge_filing_submit_log

提交日志表

然后把 detail 明细都塞进 version.final_data_json

这样也能跑。

但是我不推荐。
原因很简单:

明细是结构化业务数据,不应该完全埋进 JSON。

否则你将来要查:

  • 某个报告号在哪些报备里出现过

  • 某个合同号对应哪些版本

  • 某个项目组被报备了多少次

都会很痛苦。

所以真正适合长期维护的,还是四张表。

十、我给你的最终建议

你这块如果按“最科学、最适合工程实施”的标准,我建议最终定为这句话:

一张主表,管报备单当前态

一张版本表,管编辑历史

一张明细表,管版本明细

一张提交日志表,管对外提交记录

这就是最稳、最清晰、最容易维护的方案。

如果你愿意,我下一步可以直接继续给你一份可上线的完整SQL终稿,我会把字段名、索引、唯一约束、状态值注释、以及推荐外键关系一次性整理好。

我问:

-- =========================================================

-- 3. 企业评协账号配置表

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_account`;

CREATE TABLE `bridge_filing_account`

(

`id`                    BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`             BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`            BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`enterprise_code`       VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用编码',


`account_source`        VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',

`association_org_name`  VARCHAR(255) DEFAULT NULL COMMENT '评协机构/企业名称',

`login_username`        VARCHAR(255) NOT NULL COMMENT '登录账号',

`login_password_enc`    VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',

`password_updated_at`   DATETIME DEFAULT NULL COMMENT '密码更新时间',


`is_default`            TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号',

`is_valid`              TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效',

`last_verify_status`    VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态:UNKNOWN/SUCCESS/FAILED/TIMEOUT',

`last_verify_msg`       VARCHAR(1000) DEFAULT NULL COMMENT '最近校验说明',


`request_id`            VARCHAR(64) DEFAULT NULL COMMENT '来源对应请求流水号',

`ext_json`              JSON DEFAULT NULL COMMENT '扩展数据',


`is_deleted`            TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`            DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`updated_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',


PRIMARY KEY (`id`),

KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_id`),

KEY `idx_login_username` (`login_username`),

KEY `idx_request_id` (`request_id`),

KEY `idx_is_deleted` (`is_deleted`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';



-- =========================================================

-- 4. 报备字段覆盖修改表

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_field_override`;

CREATE TABLE `bridge_filing_field_override`

(

`id`                  BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`           BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`          BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`filing_record_id`    BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',

`filing_detail_id`    BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID,可为空',


`trace_id`            VARCHAR(64) NOT NULL COMMENT '链路号',

`request_id`          VARCHAR(64) DEFAULT NULL COMMENT '请求流水号',


`field_scope`         VARCHAR(32) NOT NULL COMMENT '字段范围:RECORD/DETAIL/ACCOUNT',

`field_name`          VARCHAR(128) NOT NULL COMMENT '字段名',

`field_label`         VARCHAR(255) DEFAULT NULL COMMENT '字段中文名',


`source_value`        TEXT COMMENT '来源原始值',

`current_value`       TEXT COMMENT '当前值',

`override_reason`     VARCHAR(255) DEFAULT NULL COMMENT '修改原因',

`operator_id`         BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',

`operator_name`       VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',


`is_deleted`          TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`          BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`          DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`          DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`updated_at`          DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',


PRIMARY KEY (`id`),

KEY `idx_filing_record_id` (`filing_record_id`),

KEY `idx_filing_detail_id` (`filing_detail_id`),

KEY `idx_trace_id` (`trace_id`),

KEY `idx_request_id` (`request_id`),

KEY `idx_field_name` (`field_name`),

KEY `idx_is_deleted` (`is_deleted`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备字段覆盖修改表';



-- =========================================================

-- 5. 报备文件表

-- 文件快照只记录元数据,不保存文件二进制

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_file`;

CREATE TABLE `bridge_filing_file`

(

`id`                  BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`           BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`          BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`filing_record_id`    BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',

`filing_detail_id`    BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID',


`trace_id`            VARCHAR(64) NOT NULL COMMENT '链路号',

`request_id`          VARCHAR(64) DEFAULT NULL COMMENT '请求流水号',


`file_source`         VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',

`file_category`       VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',


`source_file_id`      VARCHAR(128) DEFAULT NULL COMMENT '来源系统文件ID',

`file_name`           VARCHAR(255) NOT NULL COMMENT '文件名',

`file_ext`            VARCHAR(32) DEFAULT NULL COMMENT '扩展名',

`file_size`           BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小,字节',

`mime_type`           VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',

`file_hash`           VARCHAR(128) DEFAULT NULL COMMENT '文件哈希值',


`file_path`           VARCHAR(1000) DEFAULT NULL COMMENT '存储路径',

`file_url`            VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',


`is_readonly`         TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否只读:0否1是',

`is_replaceable`      TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否允许替换:0否1是',

`file_status`         VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '文件状态:ACTIVE/DELETED/INVALID',


`remark`              VARCHAR(1000) DEFAULT NULL COMMENT '备注',


`is_deleted`          TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`          BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`          DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`          DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

`updated_at`          DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',


PRIMARY KEY (`id`),

KEY `idx_filing_record_id` (`filing_record_id`),

KEY `idx_filing_detail_id` (`filing_detail_id`),

KEY `idx_trace_id` (`trace_id`),

KEY `idx_request_id` (`request_id`),

KEY `idx_file_source` (`file_source`),

KEY `idx_file_category` (`file_category`),

KEY `idx_is_deleted` (`is_deleted`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';



-- =========================================================

-- 6. 报备请求流水日志表

-- 记录OA推送、我方拉取、评协提交等;无回调,均为即时响应

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_request_log`;

CREATE TABLE `bridge_filing_request_log`

(

`id`                    BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`             BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`            BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`filing_record_id`      BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备主表ID',

`filing_detail_id`      BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备明细ID',


`trace_id`              VARCHAR(64) NOT NULL COMMENT '链路号',

`request_id`            VARCHAR(64) NOT NULL COMMENT '请求流水号',

`parent_request_id`     VARCHAR(64) DEFAULT NULL COMMENT '父请求流水号',


`request_type`          VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH/ZPY_PULL/ASSOCIATION_SUBMIT/ASSOCIATION_QUERY/INTERNAL',

`request_direction`     VARCHAR(16) NOT NULL COMMENT '方向:INBOUND/OUTBOUND/INTERNAL',

`biz_stage`             VARCHAR(32) DEFAULT NULL COMMENT '业务阶段:RECEIVE_DATA/PULL_DATA/SUBMIT_ASSOCIATION/QUERY_RESULT',

`data_snapshot_type`    VARCHAR(16) DEFAULT NULL COMMENT '数据快照类型:SOURCE/FINAL',


`request_status`        VARCHAR(32) NOT NULL DEFAULT 'PROCESSING' COMMENT '请求状态:PROCESSING/SUCCESS/FAILED/TIMEOUT/IGNORED',


`http_method`           VARCHAR(16) DEFAULT NULL COMMENT 'HTTP方法',

`request_url`           VARCHAR(500) DEFAULT NULL COMMENT '请求地址',

`request_headers`       JSON DEFAULT NULL COMMENT '请求头',

`request_body`          JSON DEFAULT NULL COMMENT '请求体,不含文件二进制',

`response_code`         VARCHAR(64) DEFAULT NULL COMMENT '响应码',

`response_body`         JSON DEFAULT NULL COMMENT '响应体',


`duration_ms`           INT DEFAULT NULL COMMENT '耗时毫秒',

`timeout_ms`            INT DEFAULT NULL COMMENT '超时阈值毫秒',

`error_code`            VARCHAR(64) DEFAULT NULL COMMENT '错误码',

`error_msg`             VARCHAR(1000) DEFAULT NULL COMMENT '错误信息',


`operator_id`           BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',

`operator_name`         VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',


`is_deleted`            TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`            DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',


PRIMARY KEY (`id`),

UNIQUE KEY `uk_request_id` (`request_id`),

KEY `idx_filing_record_id` (`filing_record_id`),

KEY `idx_filing_detail_id` (`filing_detail_id`),

KEY `idx_trace_id` (`trace_id`),

KEY `idx_parent_request_id` (`parent_request_id`),

KEY `idx_request_type` (`request_type`),

KEY `idx_request_status` (`request_status`),

KEY `idx_is_deleted` (`is_deleted`),

KEY `idx_created_at` (`created_at`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备请求流水日志表';



-- =========================================================

-- 7. 评协交互日志表

-- =========================================================

DROP TABLE IF EXISTS `bridge_filing_association_log`;

CREATE TABLE `bridge_filing_association_log`

(

`id`                    BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',

`tenant_id`             BIGINT UNSIGNED NOT NULL COMMENT '租户ID',

`partner_id`            BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

`filing_record_id`      BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',

`filing_detail_id`      BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID',


`trace_id`              VARCHAR(64) NOT NULL COMMENT '链路号',

`request_id`            VARCHAR(64) DEFAULT NULL COMMENT '请求流水号',


`action_type`           VARCHAR(32) NOT NULL COMMENT '动作类型:LOGIN/SUBMIT/QUERY/MANUAL_NOTE/OTHER',

`action_status`         VARCHAR(32) NOT NULL DEFAULT 'SUCCESS' COMMENT '动作状态:SUCCESS/FAILED/TIMEOUT/PENDING',

`association_account`   VARCHAR(255) DEFAULT NULL COMMENT '使用的评协账号,可脱敏',


`content`               VARCHAR(2000) DEFAULT NULL COMMENT '动作说明/沟通内容',

`request_body`          JSON DEFAULT NULL COMMENT '请求体,不含文件二进制',

`response_body`         JSON DEFAULT NULL COMMENT '响应体',

`attachment_json`       JSON DEFAULT NULL COMMENT '附件元数据',

`timeout_ms`            INT DEFAULT NULL COMMENT '超时阈值毫秒',

`error_code`            VARCHAR(64) DEFAULT NULL COMMENT '错误码',

`error_msg`             VARCHAR(1000) DEFAULT NULL COMMENT '错误信息',


`operator_id`           BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',

`operator_name`         VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',


`is_deleted`            TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',

`deleted_by`            BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',

`deleted_at`            DATETIME DEFAULT NULL COMMENT '删除时间',


`created_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',


PRIMARY KEY (`id`),

KEY `idx_filing_record_id` (`filing_record_id`),

KEY `idx_filing_detail_id` (`filing_detail_id`),

KEY `idx_trace_id` (`trace_id`),

KEY `idx_request_id` (`request_id`),

KEY `idx_action_type` (`action_type`),

KEY `idx_is_deleted` (`is_deleted`),

KEY `idx_created_at` (`created_at`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评协交互日志表';



结合刚设计的,请把昨天你设计的这几张表也包含进去,目标还是简化逻辑,不要有太高的理解成本和维护成本,不必要的表就删掉,保持最简必须设计。字段稍微冗余即可,不可过度冗余。

AI答:

可以,这次我给你收敛成一套最小可维护方案

你的目标不是“表越多越规范”,而是:

一、目标重述

1. 要能覆盖核心业务

包括:

1)OA推送报备到智评云

2)智评云可编辑、可形成新版本

3)智评云向评协提交,可失败后再次修改再提

4)保留文件元数据

5)保留企业评协账号

6)保留请求日志,便于排障

2. 要尽量降低理解成本

所以不能一堆“看起来很专业,实际上边界重叠”的表。

3. 要尽量降低维护成本

所以要删掉那些和主链路重复表达的表。

二、我建议最终保留 6 张表

这是我认为最合适的“最简必须设计”:

1. bridge_filing_record

报备主表

表示“一张报备单”的当前总体状态。

2. bridge_filing_version

报备版本表

表示“这张报备单的某一个编辑版本”。

3. bridge_filing_detail

报备版本明细表

表示“某个版本下的具体明细行”。

4. bridge_filing_account

企业评协账号表

表示“这个企业可使用哪些评协账号”。

5. bridge_filing_file

报备文件表

表示“报备相关文件元数据”。

6. bridge_filing_request_log

请求流水日志表

统一记录:

  • OA推送

  • 智评云内部处理

  • 向评协提交

  • 向评协查询

  • 其他关键请求

三、明确删掉哪两张表

1. 删除 bridge_filing_field_override

这个表不建议保留。

原因很简单:

第一,它的业务价值不够大

你真正要的是“当前版本的数据长什么样”“来源数据是什么”“谁改过”。

这些已经可以通过下面几种方式表达:

1)版本表里的 source_data_json

记录原始来源快照

2)版本表里的 final_data_json

记录当前版本最终快照

3)版本表里的 has_field_override

记录这一版是否人工改过

4)updated_by / updated_at

知道谁改的、什么时候改的

如果以后你真要做“逐字段审计”,那通常也应该上通用审计日志,而不是单独为这个报备系统造一张半吊子字段覆盖表。

第二,它会提高理解成本

大家会开始纠结:

  • 改字段到底看 version 还是看 override 表?

  • 明细里的字段变化要不要一条条写 override?

  • 复制版本时 override 要不要复制?

这会把逻辑搞复杂。

所以,删掉最合适

2. 删除 bridge_filing_association_log

这个表也不建议保留。

原因是它和 bridge_filing_request_log 高度重叠。

你看它记录的东西:

  • login

  • submit

  • query

  • request_body

  • response_body

  • error_code

  • error_msg

  • timeout

这些本质上就是“请求日志”。

既然已经有 bridge_filing_request_log,那就不要再单独维护一张“评协交互日志表”。
否则会出现:

  • 同一次提交,在两张表各写一次

  • 排障时不知道以哪张为准

  • 状态不一致

所以更科学的做法是:

所有对外请求统一写 bridge_filing_request_log

通过 request_type / biz_stage 区分用途即可。

比如:

  • request_type = OA_PUSH

  • request_type = ASSOCIATION_LOGIN

  • request_type = ASSOCIATION_SUBMIT

  • request_type = ASSOCIATION_QUERY

这样就统一了。

四、最终表之间的关系

1. 主干关系

bridge_filing_record
    1 -> n bridge_filing_version
    1 -> n bridge_filing_request_log
    1 -> n bridge_filing_file

bridge_filing_version
    1 -> n bridge_filing_detail
    1 -> n bridge_filing_request_log(提交某一版时可挂版本ID)

bridge_filing_detail
    1 -> n bridge_filing_file(文件可挂到具体明细)

2. 账号关系

bridge_filing_account
    按 tenant_id + partner_id + enterprise_code 归属企业

主表和版本表里只记录:

  • account_source

  • account_config_id

  • account_snapshot_json

这样既有关联,又保留了提交当时的快照,避免后续账号被修改导致历史失真。

五、最终逻辑如何运转

1. OA推送时

第一步

插入主表一条 bridge_filing_record

第二步

插入版本表一条 bridge_filing_versionversion_no = 1

第三步

插入该版本对应的 bridge_filing_detail

第四步

插入请求日志 bridge_filing_request_log
类型记为 OA_PUSH

2. 用户编辑时

第一步

基于当前版本复制生成新版本

第二步

复制旧版本明细到新版本

第三步

用户修改新版本内容

第四步

主表 current_version_id/current_version_no 指向新版本

3. 用户提交评协时

第一步

写一条请求日志 ASSOCIATION_SUBMIT

第二步

提交成功或失败后更新日志

第三步

回写主表状态

第四步

把本次提交用的账号快照留在版本表中

六、最终推荐字段设计

下面这版就是我建议你落库的终稿思路,已经按“最简必须设计”收敛过了。

1. 报备主表

DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备链路号',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回报备号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
  `project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
  `project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
  `project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前版本号',
  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '主状态:DRAFT/READY/SUBMITTING/SUCCESS/FAILED/CLOSED',

  `last_request_id` VARCHAR(64) DEFAULT NULL COMMENT '最近一次请求流水号',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次结果说明',
  `last_submit_at` DATETIME DEFAULT NULL COMMENT '最近一次提交时间',
  `success_at` DATETIME DEFAULT NULL COMMENT '成功时间',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_partner_id` (`partner_id`),
  KEY `idx_project_group_id` (`project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';

2. 报备版本表

DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1开始递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID,首次版本为空',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT/COPY_EDIT/MANUAL_CREATE',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT/READY/SUBMITTED/DISCARDED',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本:0否1是',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '账号配置ID',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '账号快照',

  `source_data_json` JSON DEFAULT NULL COMMENT '原始来源数据快照',
  `final_data_json` JSON DEFAULT NULL COMMENT '当前版本最终数据快照',
  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否有人工改动:0否1是',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`, `version_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_parent_version_id` (`parent_version_id`),
  KEY `idx_version_status` (`version_status`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';

3. 报备版本明细表

DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '报备版本ID',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',

  `detail_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '明细状态:ACTIVE/DELETED',
  `source_detail_json` JSON DEFAULT NULL COMMENT '原始明细快照',
  `final_detail_json` JSON DEFAULT NULL COMMENT '最终明细快照',
  `detail_json` JSON DEFAULT NULL COMMENT '扩展数据',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_report_project_group_id` (`report_project_group_id`),
  KEY `idx_contract_no` (`contract_no`),
  KEY `idx_report_no` (`report_no`),
  KEY `idx_detail_status` (`detail_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';

4. 企业评协账号配置表

这里我顺手把你原 SQL 里的一个明显错误修掉:
你索引写的是 enterprise_id,但表里根本没有这个字段,应该是 enterprise_code

DROP TABLE IF EXISTS `bridge_filing_account`;
CREATE TABLE `bridge_filing_account` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) DEFAULT NULL COMMENT '企业统一信用代码',

  `account_source` VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `association_org_name` VARCHAR(255) DEFAULT NULL COMMENT '评协机构/企业名称',
  `login_username` VARCHAR(255) NOT NULL COMMENT '登录账号',
  `login_password_enc` VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',
  `password_updated_at` DATETIME DEFAULT NULL COMMENT '密码更新时间',

  `is_default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号',
  `is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效',
  `last_verify_status` VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态:UNKNOWN/SUCCESS/FAILED/TIMEOUT',
  `last_verify_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近校验说明',

  `request_id` VARCHAR(64) DEFAULT NULL COMMENT '来源对应请求流水号',
  `ext_json` JSON DEFAULT NULL COMMENT '扩展数据',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_login_username` (`login_username`),
  KEY `idx_request_id` (`request_id`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';

5. 报备文件表

这里我建议把文件归属改为:

  • 必挂 filing_record_id

  • 可挂 filing_version_id

  • 可挂 filing_detail_id

这样你既能存“整单文件”,也能存“某版本文件”,也能存“某条明细文件”。

trace_idrequest_id 可以保留,便于定位来源。

DROP TABLE IF EXISTS `bridge_filing_file`;
CREATE TABLE `bridge_filing_file` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备版本ID',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_id` VARCHAR(64) DEFAULT NULL COMMENT '请求流水号',

  `file_source` VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',
  `file_category` VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',

  `source_file_id` VARCHAR(128) DEFAULT NULL COMMENT '来源系统文件ID',
  `file_name` VARCHAR(255) NOT NULL COMMENT '文件名',
  `file_ext` VARCHAR(32) DEFAULT NULL COMMENT '扩展名',
  `file_size` BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小,字节',
  `mime_type` VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',
  `file_hash` VARCHAR(128) DEFAULT NULL COMMENT '文件哈希值',

  `file_path` VARCHAR(1000) DEFAULT NULL COMMENT '存储路径',
  `file_url` VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',

  `is_readonly` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否只读:0否1是',
  `is_replaceable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否允许替换:0否1是',
  `file_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '文件状态:ACTIVE/DELETED/INVALID',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_request_id` (`request_id`),
  KEY `idx_file_source` (`file_source`),
  KEY `idx_file_category` (`file_category`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';

6. 报备请求流水日志表

这张表是统一日志表,建议增加 filing_version_id,否则你将来很难知道“这次提交到底提交的是哪个版本”。

另外 filing_detail_id 保留可选即可。

DROP TABLE IF EXISTS `bridge_filing_request_log`;
CREATE TABLE `bridge_filing_request_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',

  `filing_record_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备版本ID',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备明细ID',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_id` VARCHAR(64) NOT NULL COMMENT '请求流水号',
  `parent_request_id` VARCHAR(64) DEFAULT NULL COMMENT '父请求流水号',

  `request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH/ASSOCIATION_LOGIN/ASSOCIATION_SUBMIT/ASSOCIATION_QUERY/INTERNAL',
  `request_direction` VARCHAR(16) NOT NULL COMMENT '方向:INBOUND/OUTBOUND/INTERNAL',
  `biz_stage` VARCHAR(32) DEFAULT NULL COMMENT '业务阶段:RECEIVE_DATA/EDIT_SAVE/SUBMIT_ASSOCIATION/QUERY_RESULT',
  `data_snapshot_type` VARCHAR(16) DEFAULT NULL COMMENT '数据快照类型:SOURCE/FINAL',

  `request_status` VARCHAR(32) NOT NULL DEFAULT 'PROCESSING' COMMENT '请求状态:PROCESSING/SUCCESS/FAILED/TIMEOUT/IGNORED',

  `http_method` VARCHAR(16) DEFAULT NULL COMMENT 'HTTP方法',
  `request_url` VARCHAR(500) DEFAULT NULL COMMENT '请求地址',
  `request_headers` JSON DEFAULT NULL COMMENT '请求头',
  `request_body` JSON DEFAULT NULL COMMENT '请求体,不含文件二进制',
  `response_code` VARCHAR(64) DEFAULT NULL COMMENT '响应码',
  `response_body` JSON DEFAULT NULL COMMENT '响应体',

  `duration_ms` INT DEFAULT NULL COMMENT '耗时毫秒',
  `timeout_ms` INT DEFAULT NULL COMMENT '超时阈值毫秒',
  `error_code` VARCHAR(64) DEFAULT NULL COMMENT '错误码',
  `error_msg` VARCHAR(1000) DEFAULT NULL COMMENT '错误信息',

  `operator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',
  `operator_name` VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_id` (`request_id`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_parent_request_id` (`parent_request_id`),
  KEY `idx_request_type` (`request_type`),
  KEY `idx_request_status` (`request_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备请求流水日志表';

七、为什么这 6 张表是最合适的

1. 主链路完整

你最核心的链路都覆盖了:

报备单

bridge_filing_record

可编辑版本

bridge_filing_version

版本下明细

bridge_filing_detail

文件

bridge_filing_file

账号

bridge_filing_account

请求日志

bridge_filing_request_log

2. 没有重复表意

删掉了两个容易打架的表:

bridge_filing_field_override

和版本快照重复

bridge_filing_association_log

和请求日志重复

3. 开发实现顺

后端写起来会非常顺:

创建报备

写 record + version + detail + request_log

编辑报备

复制 version + detail

提交报备

写 request_log,回写 record

查历史

查 version

查请求报文

查 request_log

查文件

查 file

八、再给你一个很关键的实施建议

你这套表最终好不好维护,关键不只是表结构,还取决于你们代码层怎么约束。

我建议你在代码里强约束下面三条:

1. 当前版本只允许有一条

同一 filing_record_id 下,只允许一个 is_current = 1

2. 版本号只能递增

不能回写老版本

3. 向评协提交时必须带 filing_version_id

否则日志会失去意义

九、最终结论

我给你的最终收敛方案就是:

保留

bridge_filing_record
bridge_filing_version
bridge_filing_detail
bridge_filing_account
bridge_filing_file
bridge_filing_request_log

删除

bridge_filing_field_override
bridge_filing_association_log

这套是我认为你当前场景下,理解成本最低、维护成本最低、扩展性又够用的最简必须设计。

你要是愿意,我下一步可以直接把这 6 张表整理成一份完整可执行的最终 SQL 文件,包括字段顺序、索引顺序、推荐唯一约束命名,一次性给你出成终稿。

我问:

这里面扩展数据字段没必要,这个冗余似乎用不到;另外有tenant_id的表都对应一个enterprise_code;几个表中快照数据必须注释详细一点,我有点混淆不懂。请重新设计后只输出sql。

AI答:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- =========================================================
-- 1. 报备主表
-- 一条记录代表一张报备单的当前总体状态
-- 不保存版本历史,只保存“当前视图”和最近一次处理结果
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备全链路号,贯穿OA推送、智评云处理、评协提交全过程',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方系统生成的报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回的报备号/备案号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
  `project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
  `project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
  `project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前正在使用的报备版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前正在使用的版本号',
  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '报备单当前状态:DRAFT/READY/SUBMITTING/SUCCESS/FAILED/CLOSED',

  `last_request_id` VARCHAR(64) DEFAULT NULL COMMENT '最近一次关键请求流水号,通常为最近一次提交评协或最近一次OA推送请求号',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次处理结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次处理结果说明',
  `last_submit_at` DATETIME DEFAULT NULL COMMENT '最近一次向评协提交时间',
  `success_at` DATETIME DEFAULT NULL COMMENT '报备最终成功时间',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_project_group_id` (`project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';


-- =========================================================
-- 2. 报备版本表
-- 一条记录代表该报备单在某一次保存后的完整业务版本
-- 用户修改并保存后,生成新版本;历史版本保留不覆盖
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1开始递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID,首次版本为空;后续编辑复制时指向上一版本',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT/COPY_EDIT/MANUAL_CREATE',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT/READY/SUBMITTED/DISCARDED',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本:0否1是',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '本版本使用的评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '本版本绑定的账号配置ID,关联企业评协账号表',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '本版本实际使用的评协账号快照。用于保留提交当时的账号信息,避免后续账号表被修改后历史失真。建议内容包含:账号来源、账号ID、机构名称、登录账号(可脱敏)、密码更新时间、账号校验状态等,不保存明文密码',

  `source_data_json` JSON DEFAULT NULL COMMENT '本版本的原始来源数据快照。用于保留“最初进入智评云时”的业务数据原貌,通常来自OA推送或我方拉取;用于后续对比人工修改前后差异。内容应为整单业务字段快照,不含文件二进制',
  `final_data_json` JSON DEFAULT NULL COMMENT '本版本最终业务数据快照。用于保留“本版本实际提交评协时应使用”的整单数据,是当前版本编辑后的最终结果;通常来源于source_data_json加工、补全、人工修改后的结果,不含文件二进制',
  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '本版本是否存在人工修改:0否1是',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`, `version_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_parent_version_id` (`parent_version_id`),
  KEY `idx_version_status` (`version_status`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';


-- =========================================================
-- 3. 报备版本明细表
-- 一条记录代表某个版本下的一条明细
-- 明细历史跟随版本保留,不直接覆盖旧版本数据
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备版本ID',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号,同一版本内从1开始递增',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',

  `detail_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '明细状态:ACTIVE/DELETED',
  `source_detail_json` JSON DEFAULT NULL COMMENT '本条明细的原始来源数据快照。用于保留该明细最初进入系统时的原貌,通常来自OA推送或我方拉取,不含文件二进制',
  `final_detail_json` JSON DEFAULT NULL COMMENT '本条明细在当前版本下的最终数据快照。用于保留该明细编辑后的最终结果,也是提交评协时应使用的数据,不含文件二进制',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_report_project_group_id` (`report_project_group_id`),
  KEY `idx_contract_no` (`contract_no`),
  KEY `idx_report_no` (`report_no`),
  KEY `idx_detail_status` (`detail_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';


-- =========================================================
-- 4. 企业评协账号配置表
-- 保存企业可用于评协登录和提交的账号配置
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_account`;
CREATE TABLE `bridge_filing_account` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `account_source` VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `association_org_name` VARCHAR(255) DEFAULT NULL COMMENT '评协机构/企业名称',
  `login_username` VARCHAR(255) NOT NULL COMMENT '登录账号',
  `login_password_enc` VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',
  `password_updated_at` DATETIME DEFAULT NULL COMMENT '密码更新时间',

  `is_default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号:0否1是',
  `is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效:0否1是',
  `last_verify_status` VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态:UNKNOWN/SUCCESS/FAILED/TIMEOUT',
  `last_verify_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近校验说明',

  `request_id` VARCHAR(64) DEFAULT NULL COMMENT '来源对应请求流水号,如账号由某次拉取或推送生成时可记录',
  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_login_username` (`login_username`),
  KEY `idx_request_id` (`request_id`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';


-- =========================================================
-- 5. 报备文件表
-- 只保存文件元数据和存储定位信息,不保存文件二进制
-- 文件既可挂整单,也可挂某个版本,或某条明细
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_file`;
CREATE TABLE `bridge_filing_file` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备版本ID,文件若跟随某次版本保存则记录',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID,文件若归属某条明细则记录',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_id` VARCHAR(64) DEFAULT NULL COMMENT '来源请求流水号',

  `file_source` VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',
  `file_category` VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',

  `source_file_id` VARCHAR(128) DEFAULT NULL COMMENT '来源系统文件ID',
  `file_name` VARCHAR(255) NOT NULL COMMENT '文件名',
  `file_ext` VARCHAR(32) DEFAULT NULL COMMENT '扩展名',
  `file_size` BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小,字节',
  `mime_type` VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',
  `file_hash` VARCHAR(128) DEFAULT NULL COMMENT '文件哈希值',

  `file_path` VARCHAR(1000) DEFAULT NULL COMMENT '内部存储路径',
  `file_url` VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',

  `is_readonly` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否只读:0否1是',
  `is_replaceable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否允许替换:0否1是',
  `file_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '文件状态:ACTIVE/DELETED/INVALID',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_request_id` (`request_id`),
  KEY `idx_file_source` (`file_source`),
  KEY `idx_file_category` (`file_category`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';


-- =========================================================
-- 6. 报备请求流水日志表
-- 统一记录OA推送、内部处理、评协登录、评协提交、评协查询等请求过程
-- 不再额外拆评协交互日志表,避免重复维护
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_request_log`;
CREATE TABLE `bridge_filing_request_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备版本ID;提交评协、保存版本等操作建议记录该字段',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备明细ID;仅在明细级请求场景下使用',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_id` VARCHAR(64) NOT NULL COMMENT '本次请求流水号',
  `parent_request_id` VARCHAR(64) DEFAULT NULL COMMENT '父请求流水号,用于串联同一业务下的子请求',

  `request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH/ASSOCIATION_LOGIN/ASSOCIATION_SUBMIT/ASSOCIATION_QUERY/INTERNAL',
  `request_direction` VARCHAR(16) NOT NULL COMMENT '请求方向:INBOUND/OUTBOUND/INTERNAL',
  `biz_stage` VARCHAR(32) DEFAULT NULL COMMENT '业务阶段:RECEIVE_DATA/EDIT_SAVE/SUBMIT_ASSOCIATION/QUERY_RESULT',
  `data_snapshot_type` VARCHAR(16) DEFAULT NULL COMMENT '本次请求使用的数据形态:SOURCE表示原始来源数据,FINAL表示最终提交数据',

  `request_status` VARCHAR(32) NOT NULL DEFAULT 'PROCESSING' COMMENT '请求状态:PROCESSING/SUCCESS/FAILED/TIMEOUT/IGNORED',

  `http_method` VARCHAR(16) DEFAULT NULL COMMENT 'HTTP方法',
  `request_url` VARCHAR(500) DEFAULT NULL COMMENT '请求地址',
  `request_headers` JSON DEFAULT NULL COMMENT '请求头',
  `request_body` JSON DEFAULT NULL COMMENT '请求体快照。用于保留本次请求真实发送的数据内容,不含文件二进制;若为提交评协请求,应尽量保存提交时的整单或明细结构',
  `response_code` VARCHAR(64) DEFAULT NULL COMMENT '响应码',
  `response_body` JSON DEFAULT NULL COMMENT '响应体快照。用于保留对方系统返回的原始响应内容,便于排障与审计',

  `duration_ms` INT DEFAULT NULL COMMENT '耗时毫秒',
  `timeout_ms` INT DEFAULT NULL COMMENT '超时阈值毫秒',
  `error_code` VARCHAR(64) DEFAULT NULL COMMENT '错误码',
  `error_msg` VARCHAR(1000) DEFAULT NULL COMMENT '错误信息',

  `operator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',
  `operator_name` VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_id` (`request_id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_parent_request_id` (`parent_request_id`),
  KEY `idx_request_type` (`request_type`),
  KEY `idx_request_status` (`request_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备请求流水日志表';

SET FOREIGN_KEY_CHECKS = 1;

我问:

`is_readonly` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否只读:0否1是',

  `is_replaceable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否允许替换:0否1是',这两个必要性不大,可删减。

`request_id` VARCHAR(64) NOT NULL COMMENT '本次请求流水号',

  `parent_request_id` VARCHAR(64) DEFAULT NULL COMMENT '父请求流水号,用于串联同一业务下的子请求',这一对的业务含义我还是不明白,请你更明确注释。

ASSOCIATION_QUERY/INTERNAL这两的业务含义也请明确,我内部没有请求,另外我也不会在报备中做查询,因为报备同时就返回了结果了。

还有请求状态以及请求体和相应体,感觉有冗余。请你考虑,如果是必要的就保留,不必要请合并删减。我的目的用最少的必要字段完成功能,而不是做大量冗余,维护困难。

AI答:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- =========================================================
-- 1. 报备主表
-- 一条记录代表一张报备单的当前总体状态
-- 不保存版本历史,只保存“当前视图”和最近一次处理结果
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备全链路号,贯穿OA推送、智评云处理、评协提交全过程',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方系统生成的报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回的报备号/备案号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
  `project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
  `project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
  `project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH/ZPY_MANUAL',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH/ZPY_PULL/ZPY_REPORT/OFFLINE_REPORT',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前正在使用的报备版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前正在使用的版本号',
  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '报备单当前状态:DRAFT/READY/SUBMITTING/SUCCESS/FAILED/CLOSED',

  `last_request_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次关键请求日志ID,通常指最近一次OA推送处理或最近一次提交评协日志',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次处理结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次处理结果说明',
  `last_submit_at` DATETIME DEFAULT NULL COMMENT '最近一次向评协提交时间',
  `success_at` DATETIME DEFAULT NULL COMMENT '报备最终成功时间',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_project_group_id` (`project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_is_deleted` (`is_deleted`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';


-- =========================================================
-- 2. 报备版本表
-- 一条记录代表该报备单在某一次保存后的完整业务版本
-- 用户修改并保存后,生成新版本;历史版本保留不覆盖
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1开始递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID,首次版本为空;后续编辑复制时指向上一版本',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT/COPY_EDIT/MANUAL_CREATE',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT/READY/SUBMITTED/DISCARDED',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本:0否1是',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '本版本使用的评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '本版本绑定的账号配置ID,关联企业评协账号表',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '本版本实际使用的评协账号快照。用于保留提交当时实际采用的账号信息,避免账号配置后续被修改导致历史失真。建议仅保存:账号来源、账号配置ID、机构名称、登录账号(可脱敏)、密码更新时间、最近校验状态等,不保存明文密码',

  `source_data_json` JSON DEFAULT NULL COMMENT '本版本的原始来源数据快照。表示该版本数据在进入智评云时的原貌,通常来自OA推送或我方拉取;主要用于与最终提交数据对比,不含文件二进制',
  `final_data_json` JSON DEFAULT NULL COMMENT '本版本最终业务数据快照。表示该版本经过补全、修正、人工编辑后最终要提交给评协的整单数据,不含文件二进制',
  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '本版本是否存在人工修改:0否1是',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`, `version_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_parent_version_id` (`parent_version_id`),
  KEY `idx_version_status` (`version_status`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';


-- =========================================================
-- 3. 报备版本明细表
-- 一条记录代表某个版本下的一条明细
-- 明细历史跟随版本保留,不直接覆盖旧版本数据
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备版本ID',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号,同一版本内从1开始递增',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名,多个逗号分隔',

  `detail_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '明细状态:ACTIVE/DELETED',
  `source_detail_json` JSON DEFAULT NULL COMMENT '本条明细的原始来源数据快照。表示该明细最初进入系统时的原貌,通常来自OA推送或我方拉取,不含文件二进制',
  `final_detail_json` JSON DEFAULT NULL COMMENT '本条明细在当前版本下的最终数据快照。表示该明细经过人工编辑后最终要随版本一起提交评协的数据,不含文件二进制',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_report_project_group_id` (`report_project_group_id`),
  KEY `idx_contract_no` (`contract_no`),
  KEY `idx_report_no` (`report_no`),
  KEY `idx_detail_status` (`detail_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';


-- =========================================================
-- 4. 企业评协账号配置表
-- 保存企业可用于评协登录和提交的账号配置
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_account`;
CREATE TABLE `bridge_filing_account` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `account_source` VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `association_org_name` VARCHAR(255) DEFAULT NULL COMMENT '评协机构/企业名称',
  `login_username` VARCHAR(255) NOT NULL COMMENT '登录账号',
  `login_password_enc` VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',
  `password_updated_at` DATETIME DEFAULT NULL COMMENT '密码更新时间',

  `is_default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号:0否1是',
  `is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效:0否1是',
  `last_verify_status` VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态:UNKNOWN/SUCCESS/FAILED/TIMEOUT',
  `last_verify_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近校验说明',

  `request_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '来源请求日志ID。如该账号来源于某次OA推送或系统导入,可记录对应请求日志',
  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_login_username` (`login_username`),
  KEY `idx_request_log_id` (`request_log_id`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';


-- =========================================================
-- 5. 报备文件表
-- 只保存文件元数据和存储定位信息,不保存文件二进制
-- 文件既可挂整单,也可挂某个版本,或某条明细
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_file`;
CREATE TABLE `bridge_filing_file` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备版本ID,文件若跟随某次版本保存则记录',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备明细ID,文件若归属某条明细则记录',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '来源请求日志ID。表示该文件由哪一次请求或处理过程带入系统,例如OA推送本次报备时携带的文件',

  `file_source` VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',
  `file_category` VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',

  `source_file_id` VARCHAR(128) DEFAULT NULL COMMENT '来源系统文件ID',
  `file_name` VARCHAR(255) NOT NULL COMMENT '文件名',
  `file_ext` VARCHAR(32) DEFAULT NULL COMMENT '扩展名',
  `file_size` BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小,字节',
  `mime_type` VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',
  `file_hash` VARCHAR(128) DEFAULT NULL COMMENT '文件哈希值',

  `file_path` VARCHAR(1000) DEFAULT NULL COMMENT '内部存储路径',
  `file_url` VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',

  `file_status` VARCHAR(32) NOT NULL DEFAULT 'ACTIVE' COMMENT '文件状态:ACTIVE/DELETED/INVALID',
  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_request_log_id` (`request_log_id`),
  KEY `idx_file_source` (`file_source`),
  KEY `idx_file_category` (`file_category`),
  KEY `idx_is_deleted` (`is_deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';


-- =========================================================
-- 6. 报备请求流水日志表
-- 统一记录关键请求过程,只保留最少必要字段
-- 主要覆盖两类场景:
-- 1)OA_PUSH:OA推送报备到我方
-- 2)ASSOCIATION_SUBMIT:我方向评协提交报备
--
-- request_no:
--   本次请求自己的唯一流水号。每发生一次实际请求,就生成一个新的request_no。
--   例如:OA推送一次,生成一个request_no;我方向评协提交一次,再生成一个新的request_no。
--
-- parent_request_no:
--   上游来源请求流水号。用于表达“这次请求是由哪一次上游请求衍生出来的”。
--   例如:OA推送到我方时,产生 request_no=A;
--        我方基于这笔报备再向评协提交时,新的提交请求产生 request_no=B;
--        此时 B 的 parent_request_no=A,表示“这次提交动作来源于那次OA推送”。
--   如果本次请求本身就是链路起点,则 parent_request_no 为空。
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_request_log`;
CREATE TABLE `bridge_filing_request_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备主表ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备版本ID;向评协提交时应记录本次提交使用的是哪个版本',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '关联报备明细ID;仅在明细级处理场景下使用',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',
  `request_no` VARCHAR(64) NOT NULL COMMENT '本次请求自身的唯一流水号。每发生一次实际请求就生成一个新的编号,用于唯一标识这一次OA推送或这一次评协提交',
  `parent_request_no` VARCHAR(64) DEFAULT NULL COMMENT '上游来源请求流水号。用于串联请求来源关系:如果本次请求是由前一次请求衍生出来的,则记录前一次请求的request_no;如果本次请求就是整条链路的起点,则为空',

  `request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH表示OA推送报备到我方;ASSOCIATION_SUBMIT表示我方向评协提交报备',
  `request_direction` VARCHAR(16) NOT NULL COMMENT '请求方向:INBOUND表示外部请求进我方;OUTBOUND表示我方向外部发起请求',
  `data_snapshot_type` VARCHAR(16) DEFAULT NULL COMMENT '本次请求使用的数据形态:SOURCE表示原始来源数据;FINAL表示最终提交数据',

  `result_code` VARCHAR(64) DEFAULT NULL COMMENT '本次请求处理结果码',
  `result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '本次请求处理结果说明',
  `request_body` JSON DEFAULT NULL COMMENT '请求体快照。仅在需要排查问题时保存关键请求内容,不含文件二进制;OA推送时可保存OA原始入参,提交评协时可保存最终提交报文',
  `response_body` JSON DEFAULT NULL COMMENT '响应体快照。仅在需要排查问题时保存关键返回结果;OA推送时可保存我方响应OA内容,提交评协时可保存评协返回结果',

  `duration_ms` INT DEFAULT NULL COMMENT '本次请求处理耗时,单位毫秒',
  `operator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人',
  `operator_name` VARCHAR(128) DEFAULT NULL COMMENT '操作人名称',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_no` (`request_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`, `partner_id`, `enterprise_code`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`),
  KEY `idx_parent_request_no` (`parent_request_no`),
  KEY `idx_request_type` (`request_type`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备请求流水日志表';

SET FOREIGN_KEY_CHECKS = 1;

我问:

报备单当前状态应该加一个TIMEOUT。报告所属项目组ID,报告所属项目组编号,报告所属项目组名称,这三字段统一一下,都要含有report,标记跟OA的映射关系。那是否意味着明细在复制的时候也得同步跟版本复制一条?请你注释在comment里,如果需要的话。另外账号表如果来源于OA,可能多次提交报备是同一个,这个如何反应在表中?用账号名+密码来匹配这个用户,然后在业务逻辑中选择更新还是不更新么?请体现在注释里。另外一个版本应该是对应一个明细吧,而一个明细会对应多个文件吧。也体现在注释里。对于parent_request_no,如果是OA提交报备,触发我们自动提交,这个没问题,那如果是他提交了之后,用户在智评云系统修改后提交评协,此时还有这个parent_request_no关系吗?请体现在注释里。

`request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH表示OA推送报备到我方;ASSOCIATION_SUBMIT表示我方向评协提交报备',这个似乎没体现我们去拉取OA的报备信息这一种。请你对以上5个表也检查下这个拉取是否包含在内。必要信息写在注释里,注释越相近越好,便于后续维护。仅输出sql。

AI答:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- =========================================================
-- 1. 报备主表
-- 一条记录代表一张报备单的当前总体状态
-- 只保存当前状态,不保存历史版本
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备全链路号。OA推送或OA拉取进入系统后生成,贯穿整个链路:OA -> 智评云 -> 评协提交',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方系统生成的报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回的报备号/备案号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',
  `project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '项目组ID',
  `project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '项目组编号',
  `project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '项目组名称',
  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH=OA主动推送;ZPY_MANUAL=智评云手工创建',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH=OA推送;OA_PULL=我方主动拉取OA;ZPY_REPORT=智评云生成报备;OFFLINE_REPORT=线下报备',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前正在使用的报备版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前版本号',

  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT'
  COMMENT '报备单当前状态:DRAFT=草稿;READY=准备提交;SUBMITTING=提交中;SUCCESS=成功;FAILED=失败;TIMEOUT=提交超时(例如评协未返回或接口超时);CLOSED=已关闭',

  `last_request_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次关键请求日志ID,通常指最近一次OA交互或最近一次提交评协',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次处理结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次处理结果说明',
  `last_submit_at` DATETIME DEFAULT NULL COMMENT '最近一次向评协提交时间',
  `success_at` DATETIME DEFAULT NULL COMMENT '报备最终成功时间',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`,`partner_id`,`enterprise_code`),
  KEY `idx_project_group_id` (`project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';



-- =========================================================
-- 2. 报备版本表
-- 一条记录代表一次“保存后的报备版本”
--
-- 版本设计说明:
-- 1)每次用户编辑并保存报备单,都会生成一个新版本
-- 2)历史版本不修改,只新增
-- 3)当前版本通过 is_current=1 标识
-- 4)版本复制逻辑:
--    当用户修改旧版本内容时,系统应复制上一版本生成新版本,
--    同时复制该版本对应的明细数据(bridge_filing_detail),
--    然后在新版本基础上进行编辑
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID;新版本复制自哪个版本',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT=OA进入系统初始版本;COPY_EDIT=复制旧版本编辑;MANUAL_CREATE=人工创建',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT=编辑中;READY=准备提交;SUBMITTED=已提交;DISCARDED=废弃',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/ZPY_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '使用的账号配置ID',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '账号快照:记录本版本提交评协时使用的账号信息,用于防止账号表后续修改导致历史记录不一致',

  `source_data_json` JSON DEFAULT NULL COMMENT '原始来源数据快照:OA推送或拉取进入系统时的完整业务数据',
  `final_data_json` JSON DEFAULT NULL COMMENT '最终提交数据快照:经过人工编辑或补全后提交评协的最终业务数据',

  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否存在人工字段修改',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`,`version_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';



-- =========================================================
-- 3. 报备版本明细表
--
-- 关系说明:
-- 一个版本 -> 多个明细
-- 一个明细 -> 多个文件
--
-- 当版本复制时:
-- 系统应复制上一版本的所有明细记录到新版本
--
-- report_project_group_* 字段说明:
-- 这些字段统一带 report 前缀,
-- 表示“报告所属项目组”,用于与OA系统字段映射区分
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '所属版本ID',
  `detail_no` INT NOT NULL COMMENT '明细序号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID(OA映射字段)',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号(OA映射字段)',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称(OA映射字段)',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名',

  `source_detail_json` JSON DEFAULT NULL COMMENT '原始来源明细数据',
  `final_detail_json` JSON DEFAULT NULL COMMENT '最终提交明细数据',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_version_id` (`filing_version_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';



-- =========================================================
-- 4. 企业评协账号配置表
--
-- 账号来源说明:
-- 如果账号来源于OA推送,
-- 同一个账号(用户名+密码)可能会多次随报备进入系统。
--
-- 系统处理建议:
-- 业务逻辑中应根据 login_username + login_password_enc
-- 判断是否为同一个账号:
--   若已存在,则更新账号信息
--   若不存在,则新增账号
--
-- 这样可避免产生大量重复账号配置
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_account`;
CREATE TABLE `bridge_filing_account` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `account_source` VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/OA_PULL/LOCAL_CONFIG/USER_INPUT',
  `association_org_name` VARCHAR(255) DEFAULT NULL COMMENT '评协机构名称',

  `login_username` VARCHAR(255) NOT NULL COMMENT '登录账号',
  `login_password_enc` VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',

  `password_updated_at` DATETIME DEFAULT NULL COMMENT '密码更新时间',

  `is_default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号',
  `is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效',

  `last_verify_status` VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态',
  `last_verify_msg` VARCHAR(1000) DEFAULT NULL COMMENT '校验说明',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_enterprise` (`tenant_id`,`partner_id`,`enterprise_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';



-- =========================================================
-- 5. 报备文件表
--
-- 关系说明:
-- 一个明细可以对应多个文件
-- 文件只保存元数据,不保存二进制
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_file`;
CREATE TABLE `bridge_filing_file` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备单ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '版本ID',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '明细ID',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',

  `file_source` VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',
  `file_category` VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',

  `file_name` VARCHAR(255) NOT NULL COMMENT '文件名',
  `file_ext` VARCHAR(32) DEFAULT NULL COMMENT '扩展名',
  `file_size` BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小',
  `mime_type` VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',

  `file_path` VARCHAR(1000) DEFAULT NULL COMMENT '存储路径',
  `file_url` VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  KEY `idx_detail` (`filing_detail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';



-- =========================================================
-- 6. 请求日志表
--
-- request_type说明:
-- OA_PUSH = OA主动推送报备
-- OA_PULL = 我方主动拉取OA报备
-- ASSOCIATION_SUBMIT = 我方向评协提交报备
--
-- parent_request_no说明:
-- 情况1:OA推送后自动提交评协
--   request_no=A (OA_PUSH)
--   request_no=B (ASSOCIATION_SUBMIT) parent=A
--
-- 情况2:用户在系统中修改后再提交
--   request_no=C (ASSOCIATION_SUBMIT)
--   parent_request_no 为空
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_request_log`;
CREATE TABLE `bridge_filing_request_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备单ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '版本ID',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',

  `request_no` VARCHAR(64) NOT NULL COMMENT '本次请求唯一流水号',
  `parent_request_no` VARCHAR(64) DEFAULT NULL COMMENT '上游请求流水号',

  `request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH/OA_PULL/ASSOCIATION_SUBMIT',
  `request_direction` VARCHAR(16) NOT NULL COMMENT 'INBOUND=进入系统;OUTBOUND=系统发出',

  `result_code` VARCHAR(64) DEFAULT NULL COMMENT '结果码',
  `result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '结果说明',

  `request_body` JSON DEFAULT NULL COMMENT '请求报文快照',
  `response_body` JSON DEFAULT NULL COMMENT '返回报文快照',

  `duration_ms` INT DEFAULT NULL COMMENT '耗时毫秒',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_no` (`request_no`),
  KEY `idx_trace` (`trace_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='请求日志表';


SET FOREIGN_KEY_CHECKS = 1;

我问:

一个版本怎么可能有多个明细?我觉得一套版本就一套明细。请你考虑清楚后纠正。宝贝主表的项目组id、编号、名称也要加report前缀,便于快速识别,降低维护成本。再根据我指令优化后输出最终版sql。

AI答:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- =========================================================
-- 1. 报备主表
-- 一条记录代表一张报备单的当前总体状态
-- 只保存当前状态,不保存历史版本
-- 主表中的 report_project_group_* 字段统一表示“报告所属项目组”
-- 之所以统一加 report 前缀,是为了和其他普通项目组字段快速区分,降低后续维护成本
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_record`;
CREATE TABLE `bridge_filing_record` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '整笔报备全链路号。OA推送或OA拉取进入系统后生成,贯穿整个链路:OA -> 智评云 -> 评协提交',
  `filing_no` VARCHAR(64) NOT NULL COMMENT '我方系统生成的报备单号',
  `external_filing_no` VARCHAR(128) DEFAULT NULL COMMENT '评协返回的报备号/备案号',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID(OA映射字段)',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号(OA映射字段)',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称(OA映射字段)',

  `submission_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '提交记录ID/提审记录ID',

  `filing_initiator` VARCHAR(32) NOT NULL COMMENT '报备发起方:OA_PUSH=OA主动推送;ZPY_MANUAL=智评云手工创建',
  `filing_mode` VARCHAR(32) NOT NULL COMMENT '报备方式:OA_PUSH=OA推送;OA_PULL=我方主动拉取OA;ZPY_REPORT=智评云生成报备;OFFLINE_REPORT=线下报备',

  `current_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '当前正在使用的报备版本ID',
  `current_version_no` INT NOT NULL DEFAULT 1 COMMENT '当前版本号',

  `record_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT'
  COMMENT '报备单当前状态:DRAFT=草稿;READY=准备提交;SUBMITTING=提交中;SUCCESS=成功;FAILED=失败;TIMEOUT=提交超时(例如评协未返回或接口超时);CLOSED=已关闭',

  `last_request_log_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '最近一次关键请求日志ID,通常指最近一次OA交互或最近一次提交评协',
  `last_result_code` VARCHAR(64) DEFAULT NULL COMMENT '最近一次处理结果码',
  `last_result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '最近一次处理结果说明',
  `last_submit_at` DATETIME DEFAULT NULL COMMENT '最近一次向评协提交时间',
  `success_at` DATETIME DEFAULT NULL COMMENT '报备最终成功时间',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',

  `is_deleted` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否删除:0否1是',
  `deleted_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '删除人',
  `deleted_at` DATETIME DEFAULT NULL COMMENT '删除时间',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_trace_id` (`trace_id`),
  UNIQUE KEY `uk_filing_no` (`filing_no`),
  KEY `idx_tenant_partner_enterprise` (`tenant_id`,`partner_id`,`enterprise_code`),
  KEY `idx_report_project_group_id` (`report_project_group_id`),
  KEY `idx_record_status` (`record_status`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备主表';



-- =========================================================
-- 2. 报备版本表
-- 一条记录代表一次“保存后的报备版本”
--
-- 版本设计说明:
-- 1)每次用户编辑并保存报备单,都会生成一个新版本
-- 2)历史版本不修改,只新增
-- 3)当前版本通过 is_current=1 标识
-- 4)本系统按“一套版本对应一套明细”建模,即一个版本只对应一条明细记录
-- 5)当用户基于旧版本修改时,系统应复制上一版本生成新版本,
--    同时复制上一版本对应的那一条明细到新版本,再在新版本基础上编辑
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_version`;
CREATE TABLE `bridge_filing_version` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '所属报备主表ID',
  `version_no` INT NOT NULL COMMENT '版本号,从1递增',
  `parent_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '父版本ID;新版本复制自哪个版本',
  `version_source` VARCHAR(32) NOT NULL COMMENT '版本来源:OA_INIT=OA进入系统初始版本;COPY_EDIT=复制旧版本编辑;MANUAL_CREATE=人工创建',
  `version_status` VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '版本状态:DRAFT=编辑中;READY=准备提交;SUBMITTED=已提交;DISCARDED=废弃',
  `is_current` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否当前版本',

  `account_source` VARCHAR(32) DEFAULT NULL COMMENT '评协账号来源:OA_PUSH/OA_PULL/LOCAL_CONFIG/USER_INPUT',
  `account_config_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '使用的账号配置ID',
  `account_snapshot_json` JSON DEFAULT NULL COMMENT '账号快照:记录本版本提交评协时实际使用的账号信息,用于防止账号表后续修改导致历史记录不一致。建议仅保存账号来源、账号配置ID、机构名称、登录账号(可脱敏)、密码更新时间、最近校验状态等,不保存明文密码',

  `source_data_json` JSON DEFAULT NULL COMMENT '原始来源数据快照:OA推送或OA拉取进入系统时的完整业务数据原貌,用于保留初始入参,不含文件二进制',
  `final_data_json` JSON DEFAULT NULL COMMENT '最终提交数据快照:当前版本经过人工编辑、补全、修正后,最终要提交给评协的整单业务数据,不含文件二进制',

  `has_field_override` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否存在人工字段修改',

  `remark` VARCHAR(1000) DEFAULT NULL COMMENT '版本备注',

  `created_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '创建人',
  `updated_by` BIGINT UNSIGNED DEFAULT NULL COMMENT '更新人',
  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_record_version_no` (`filing_record_id`,`version_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_is_current` (`is_current`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本表';



-- =========================================================
-- 3. 报备版本明细表
--
-- 关系说明:
-- 1)一个版本只对应一条明细
-- 2)因此 filing_version_id 在本表中应唯一
-- 3)一个明细可以对应多个文件
-- 4)当版本复制时,系统应同步复制旧版本对应的这一条明细到新版本
--
-- report_project_group_* 字段说明:
-- 这些字段统一带 report 前缀,表示“报告所属项目组”,用于与其他普通项目组概念区分
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '所属版本ID。按当前设计,一个版本只对应一条明细,因此该字段应唯一',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号。当前设计固定为1,保留该字段是为了兼容未来扩展',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID(OA映射字段)',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号(OA映射字段)',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称(OA映射字段)',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名',

  `source_detail_json` JSON DEFAULT NULL COMMENT '原始来源明细数据:该版本对应明细在最初进入系统时的原貌,不含文件二进制',
  `final_detail_json` JSON DEFAULT NULL COMMENT '最终提交明细数据:该版本对应明细经过人工编辑后,最终要提交给评协的明细内容,不含文件二进制',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_filing_version_id` (`filing_version_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';



-- =========================================================
-- 4. 企业评协账号配置表
--
-- 账号来源说明:
-- 1)如果账号来源于OA推送或OA拉取,同一个账号可能会多次随不同报备进入系统
-- 2)业务逻辑建议按 tenant_id + partner_id + enterprise_code + login_username + login_password_enc 识别是否为同一个账号
-- 3)若识别为同一个账号,则更新账号信息;若不存在,则新增
-- 4)这样可避免同一企业下产生大量重复账号配置
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_account`;
CREATE TABLE `bridge_filing_account` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `account_source` VARCHAR(32) NOT NULL COMMENT '账号来源:OA_PUSH/OA_PULL/LOCAL_CONFIG/USER_INPUT',
  `association_org_name` VARCHAR(255) DEFAULT NULL COMMENT '评协机构名称',

  `login_username` VARCHAR(255) NOT NULL COMMENT '登录账号',
  `login_password_enc` VARCHAR(1000) DEFAULT NULL COMMENT '加密后的登录密码',

  `password_updated_at` DATETIME DEFAULT NULL COMMENT '密码更新时间',

  `is_default` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否默认账号',
  `is_valid` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效',

  `last_verify_status` VARCHAR(32) DEFAULT NULL COMMENT '最近校验状态',
  `last_verify_msg` VARCHAR(1000) DEFAULT NULL COMMENT '校验说明',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  KEY `idx_enterprise` (`tenant_id`,`partner_id`,`enterprise_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业评协账号配置表';



-- =========================================================
-- 5. 报备文件表
--
-- 关系说明:
-- 1)一个明细可以对应多个文件
-- 2)文件只保存元数据,不保存二进制
-- 3)文件通常挂在明细上;同时冗余保存报备单ID和版本ID,便于快速查询和排障
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_file`;
CREATE TABLE `bridge_filing_file` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED NOT NULL COMMENT '报备单ID',
  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '版本ID',
  `filing_detail_id` BIGINT UNSIGNED NOT NULL COMMENT '明细ID。一个明细可以对应多个文件',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',

  `file_source` VARCHAR(16) NOT NULL COMMENT '文件来源:OA/ZPY/MANUAL',
  `file_category` VARCHAR(32) NOT NULL COMMENT '文件类别:CONTRACT/REPORT/ATTACHMENT/OTHER',

  `file_name` VARCHAR(255) NOT NULL COMMENT '文件名',
  `file_ext` VARCHAR(32) DEFAULT NULL COMMENT '扩展名',
  `file_size` BIGINT UNSIGNED DEFAULT NULL COMMENT '文件大小',
  `mime_type` VARCHAR(128) DEFAULT NULL COMMENT 'MIME类型',

  `file_path` VARCHAR(1000) DEFAULT NULL COMMENT '存储路径',
  `file_url` VARCHAR(1000) DEFAULT NULL COMMENT '访问地址',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备文件表';



-- =========================================================
-- 6. 请求日志表
--
-- request_type 说明:
-- OA_PUSH = OA主动推送报备到我方
-- OA_PULL = 我方主动拉取OA报备到我方
-- ASSOCIATION_SUBMIT = 我方向评协提交报备
--
-- parent_request_no 说明:
-- 1)如果是“OA推送后系统自动提交评协”或“OA拉取后系统自动提交评协”,
--    那么提交评协这次请求的 parent_request_no 应指向那次 OA_PUSH 或 OA_PULL 的 request_no
-- 2)如果是“用户后来在智评云中修改版本后,再手工提交评协”,
--    这次提交已经是新的人工业务动作,不再直接继承最初OA请求关系,
--    因此 parent_request_no 应为空
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_request_log`;
CREATE TABLE `bridge_filing_request_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_record_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报备单ID',
  `filing_version_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '版本ID。向评协提交时,应记录本次提交所使用的版本',
  `filing_detail_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '明细ID。当前设计下一个版本只有一条明细,此字段主要用于快速定位文件或明细侧问题',

  `trace_id` VARCHAR(64) NOT NULL COMMENT '链路号',

  `request_no` VARCHAR(64) NOT NULL COMMENT '本次请求唯一流水号',
  `parent_request_no` VARCHAR(64) DEFAULT NULL COMMENT '上游来源请求流水号。仅当本次提交是由OA_PUSH或OA_PULL自动触发时才有值;若是用户后续在系统中修改后再提交,则为空',

  `request_type` VARCHAR(32) NOT NULL COMMENT '请求类型:OA_PUSH/OA_PULL/ASSOCIATION_SUBMIT',
  `request_direction` VARCHAR(16) NOT NULL COMMENT 'INBOUND=进入系统;OUTBOUND=系统发出',

  `result_code` VARCHAR(64) DEFAULT NULL COMMENT '结果码',
  `result_msg` VARCHAR(1000) DEFAULT NULL COMMENT '结果说明',

  `request_body` JSON DEFAULT NULL COMMENT '请求报文快照。OA_PUSH/OA_PULL 时可保存进入系统的原始业务数据;ASSOCIATION_SUBMIT 时可保存最终提交给评协的报文,不含文件二进制',
  `response_body` JSON DEFAULT NULL COMMENT '返回报文快照。OA_PUSH 时可保存我方响应OA结果;ASSOCIATION_SUBMIT 时可保存评协返回结果',

  `duration_ms` INT DEFAULT NULL COMMENT '耗时毫秒',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_no` (`request_no`),
  KEY `idx_filing_record_id` (`filing_record_id`),
  KEY `idx_filing_version_id` (`filing_version_id`),
  KEY `idx_filing_detail_id` (`filing_detail_id`),
  KEY `idx_trace_id` (`trace_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='请求日志表';


SET FOREIGN_KEY_CHECKS = 1;

我问:

给明细表把收益法、市场法、资产基础法、单项资产的底稿版本也保留一下,新增一个字段加进去。只输出明细表。

AI答:

-- =========================================================
-- 3. 报备版本明细表
--
-- 关系说明:
-- 1)一个版本只对应一条明细
-- 2)因此 filing_version_id 在本表中应唯一
-- 3)一个明细可以对应多个文件
-- 4)当版本复制时,系统应同步复制旧版本对应的这一条明细到新版本
--
-- report_project_group_* 字段说明:
-- 这些字段统一带 report 前缀,表示“报告所属项目组”,用于与其他普通项目组概念区分
--
-- working_paper_version_json 字段说明:
-- 用于保留本条明细对应的底稿版本信息,建议按 JSON 结构保存各类底稿版本号或版本标识,
-- 例如:收益法、市场法、资产基础法、单项资产等,便于后续追溯报备时所使用的底稿版本
-- =========================================================
DROP TABLE IF EXISTS `bridge_filing_detail`;
CREATE TABLE `bridge_filing_detail` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `tenant_id` BIGINT UNSIGNED NOT NULL COMMENT '租户ID',
  `partner_id` BIGINT UNSIGNED NOT NULL COMMENT '对接方ID',
  `enterprise_code` VARCHAR(128) NOT NULL COMMENT '企业统一信用代码',

  `filing_version_id` BIGINT UNSIGNED NOT NULL COMMENT '所属版本ID。按当前设计,一个版本只对应一条明细,因此该字段应唯一',
  `detail_no` INT NOT NULL DEFAULT 1 COMMENT '明细序号。当前设计固定为1,保留该字段是为了兼容未来扩展',

  `oa_project_id` BIGINT UNSIGNED DEFAULT NULL COMMENT 'OA项目ID',
  `oa_project_code` VARCHAR(128) DEFAULT NULL COMMENT 'OA项目编号',

  `report_project_group_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告所属项目组ID(OA映射字段)',
  `report_project_group_code` VARCHAR(128) DEFAULT NULL COMMENT '报告所属项目组编号(OA映射字段)',
  `report_project_group_name` VARCHAR(255) DEFAULT NULL COMMENT '报告所属项目组名称(OA映射字段)',

  `contract_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '合同ID',
  `contract_no` VARCHAR(128) DEFAULT NULL COMMENT '合同编号',
  `contract_name` VARCHAR(255) DEFAULT NULL COMMENT '合同名称',

  `report_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '报告ID',
  `report_no` VARCHAR(128) DEFAULT NULL COMMENT '报告号',
  `report_name` VARCHAR(255) DEFAULT NULL COMMENT '报告名称',

  `client_name` VARCHAR(255) DEFAULT NULL COMMENT '委托方名称',
  `sign_appraiser_names` VARCHAR(500) DEFAULT NULL COMMENT '签字评估师姓名',

  `working_paper_version_json` JSON DEFAULT NULL COMMENT '底稿版本快照。用于保留本条明细对应的各类底稿版本信息,建议包含:income_method=收益法底稿版本、market_method=市场法底稿版本、asset_based_method=资产基础法底稿版本、single_asset=单项资产底稿版本',

  `source_detail_json` JSON DEFAULT NULL COMMENT '原始来源明细数据:该版本对应明细在最初进入系统时的原貌,不含文件二进制',
  `final_detail_json` JSON DEFAULT NULL COMMENT '最终提交明细数据:该版本对应明细经过人工编辑后,最终要提交给评协的明细内容,不含文件二进制',

  `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',

  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_filing_version_id` (`filing_version_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报备版本明细表';