# 诺税通对接 DDL 草案 ## 文档信息 | 项目 | 内容 | | --- | --- | | 项目名称 | 福建水务营收系统 | | 文档类型 | 外部平台对接 DDL 草案 | | 对接平台 | 诺税通 saas | | 适用范围 | 发票、红字单据、设备、库存、企业配置、平台日志 | | 版本 | v1.0 | | 日期 | 2026-03-24 | | 状态 | 草案 | ## 适用说明 本文档在 `docs/guides/NUOSHUITONG_DATABASE_DESIGN.md` 的基础上,进一步给出面向实现的 DDL 草案。当前以 PostgreSQL/MySQL 均可平滑迁移的通用 SQL 风格表达为主,重点用于: - 明确核心表字段结构 - 明确主键、唯一约束与索引建议 - 为后续纳入正式数据库设计主文档提供输入 ## 使用约定 - 主键统一使用 `bigint` - 金额统一使用 `decimal(18,2)` - 数量/单价类字段视场景使用 `decimal(18,6)` - 状态类字段统一使用 `varchar(32)` - URL 字段统一预留 `varchar(1024)` - 长报文、原始回调、请求响应体统一使用 `text` / `longtext` ## DDL 草案 ## `ns_invoice` 发票主表 ```sql CREATE TABLE ns_invoice ( id BIGINT PRIMARY KEY, sys_request_no VARCHAR(64) NOT NULL, order_no VARCHAR(64), source_business_type VARCHAR(32), source_business_id VARCHAR(64), platform_invoice_serial_num VARCHAR(64), invoice_id VARCHAR(64), invoice_code VARCHAR(32), invoice_no VARCHAR(32), all_electronic_invoice_no VARCHAR(64), seller_tax_no VARCHAR(32) NOT NULL, buyer_name VARCHAR(200), buyer_tax_no VARCHAR(64), buyer_address VARCHAR(255), buyer_tel VARCHAR(64), buyer_account VARCHAR(255), invoice_type VARCHAR(16), invoice_line VARCHAR(16), list_flag SMALLINT, with_tax_flag SMALLINT, notify_phone VARCHAR(64), notify_email VARCHAR(128), cc_phone VARCHAR(256), cc_email VARCHAR(256), total_amount DECIMAL(18,2), amount_without_tax DECIMAL(18,2), tax_amount DECIMAL(18,2), request_status VARCHAR(32) NOT NULL, invoice_status VARCHAR(32), invoice_status_text VARCHAR(255), invalid_state VARCHAR(32), delivery_status VARCHAR(32), sync_status VARCHAR(32), pdf_url VARCHAR(1024), ofd_url VARCHAR(1024), image_url VARCHAR(1024), paper_pdf_url VARCHAR(1024), invoice_time DATETIME, request_time DATETIME, invalid_time DATETIME, last_sync_time DATETIME, ori_invoice_code VARCHAR(32), ori_invoice_no VARCHAR(32), old_electronic_invoice_no VARCHAR(64), remark VARCHAR(1000), specific_factor_json TEXT, latest_result VARCHAR(1000), latest_error VARCHAR(1000), try_count INT, last_try_time DATETIME, next_try_time DATETIME, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(64), updated_by VARCHAR(64) ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_invoice ADD CONSTRAINT uk_ns_invoice_sys_request_no UNIQUE (sys_request_no); CREATE UNIQUE INDEX uk_ns_invoice_platform_serial_num ON ns_invoice (platform_invoice_serial_num); CREATE INDEX idx_ns_invoice_order_no ON ns_invoice (order_no); CREATE INDEX idx_ns_invoice_status ON ns_invoice (request_status, invoice_status, delivery_status); CREATE INDEX idx_ns_invoice_seller_tax_no ON ns_invoice (seller_tax_no); CREATE INDEX idx_ns_invoice_invoice_time ON ns_invoice (invoice_time); CREATE INDEX idx_ns_invoice_next_try_time ON ns_invoice (next_try_time); ``` ## `ns_invoice_item` 发票明细表 ```sql CREATE TABLE ns_invoice_item ( id BIGINT PRIMARY KEY, invoice_id BIGINT NOT NULL, line_no INT NOT NULL, goods_name VARCHAR(255) NOT NULL, goods_code VARCHAR(64), spec VARCHAR(128), unit VARCHAR(64), quantity DECIMAL(18,6), unit_price DECIMAL(18,6), amount_with_tax DECIMAL(18,2), amount_without_tax DECIMAL(18,2), tax_rate DECIMAL(8,4), tax_amount DECIMAL(18,2), detail_type SMALLINT, favoured_policy_flag SMALLINT, zero_rate_flag SMALLINT, favoured_policy_name VARCHAR(128), created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_invoice_item ADD CONSTRAINT fk_ns_invoice_item_invoice FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id); CREATE UNIQUE INDEX uk_ns_invoice_item_invoice_line ON ns_invoice_item (invoice_id, line_no); CREATE INDEX idx_ns_invoice_item_invoice_id ON ns_invoice_item (invoice_id); ``` ## `ns_invoice_delivery` 发票交付记录表 ```sql CREATE TABLE ns_invoice_delivery ( id BIGINT PRIMARY KEY, invoice_id BIGINT NOT NULL, delivery_type VARCHAR(16) NOT NULL, delivery_target VARCHAR(256) NOT NULL, cc_target VARCHAR(512), delivery_status VARCHAR(32) NOT NULL, delivery_message VARCHAR(1000), delivery_attempt_no INT NOT NULL, is_retry SMALLINT NOT NULL, response_code VARCHAR(32), response_body TEXT, delivery_time DATETIME, created_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_invoice_delivery ADD CONSTRAINT fk_ns_invoice_delivery_invoice FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id); CREATE INDEX idx_ns_invoice_delivery_invoice_id ON ns_invoice_delivery (invoice_id); CREATE INDEX idx_ns_invoice_delivery_status ON ns_invoice_delivery (delivery_status, delivery_time); ``` ## `ns_invoice_reversal` 发票逆向处理表 ```sql CREATE TABLE ns_invoice_reversal ( id BIGINT PRIMARY KEY, invoice_id BIGINT NOT NULL, reversal_type VARCHAR(32) NOT NULL, source_invoice_code VARCHAR(32), source_invoice_no VARCHAR(32), invalid_reason VARCHAR(32), specific_reason VARCHAR(500), request_status VARCHAR(32) NOT NULL, reversal_status VARCHAR(32), platform_result_code VARCHAR(32), platform_result_msg VARCHAR(1000), target_invoice_id BIGINT, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_invoice_reversal ADD CONSTRAINT fk_ns_invoice_reversal_invoice FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id); CREATE INDEX idx_ns_invoice_reversal_invoice_id ON ns_invoice_reversal (invoice_id); CREATE INDEX idx_ns_invoice_reversal_status ON ns_invoice_reversal (request_status, reversal_status); ``` ## `ns_red_document` 红字单据主表 ```sql CREATE TABLE ns_red_document ( id BIGINT PRIMARY KEY, invoice_id BIGINT, document_type VARCHAR(16) NOT NULL, bill_no VARCHAR(64), bill_id VARCHAR(64), bill_info_no VARCHAR(64), bill_confirm_no VARCHAR(64), bill_uuid VARCHAR(64), blue_invoice_code VARCHAR(32), blue_invoice_no VARCHAR(32), blue_invoice_number VARCHAR(64), blue_invoice_line VARCHAR(16), bill_type VARCHAR(32), bill_status VARCHAR(32), bill_status_text VARCHAR(255), open_status VARCHAR(32), back_type VARCHAR(16), apply_source VARCHAR(32), red_reason VARCHAR(255), apply_remark VARCHAR(1000), pdf_url VARCHAR(1024), callback_status VARCHAR(32), last_sync_time DATETIME, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_red_document ADD CONSTRAINT fk_ns_red_document_invoice FOREIGN KEY (invoice_id) REFERENCES ns_invoice(id); CREATE UNIQUE INDEX uk_ns_red_document_bill_no ON ns_red_document (bill_no); CREATE UNIQUE INDEX uk_ns_red_document_bill_id ON ns_red_document (bill_id); CREATE INDEX idx_ns_red_document_invoice_id ON ns_red_document (invoice_id); CREATE INDEX idx_ns_red_document_status ON ns_red_document (document_type, bill_status, open_status); ``` ## `ns_red_document_item` 红字单据明细表 ```sql CREATE TABLE ns_red_document_item ( id BIGINT PRIMARY KEY, red_document_id BIGINT NOT NULL, line_no INT NOT NULL, goods_name VARCHAR(255), model VARCHAR(128), unit VARCHAR(64), quantity DECIMAL(18,6), unit_price DECIMAL(18,6), amount DECIMAL(18,2), tax_rate DECIMAL(8,4), tax_amount DECIMAL(18,2), with_tax_flag SMALLINT, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_red_document_item ADD CONSTRAINT fk_ns_red_document_item_main FOREIGN KEY (red_document_id) REFERENCES ns_red_document(id); CREATE UNIQUE INDEX uk_ns_red_document_item_line ON ns_red_document_item (red_document_id, line_no); ``` ## `ns_billing_device` 开票设备表 ```sql CREATE TABLE ns_billing_device ( id BIGINT PRIMARY KEY, tax_num VARCHAR(32) NOT NULL, company_id VARCHAR(64), extension_num VARCHAR(32), machine_num VARCHAR(64), terminal_num VARCHAR(64), server_type VARCHAR(32), invoice_type_list VARCHAR(512), login_account VARCHAR(128), equipment_cabinet_id VARCHAR(64), device_status VARCHAR(32) NOT NULL, report_tax_status VARCHAR(32), clear_card_status VARCHAR(32), lock_date VARCHAR(32), single_billing_limit DECIMAL(18,2), offline_amount DECIMAL(18,2), offline_time VARCHAR(64), last_status_sync_time DATETIME, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql CREATE UNIQUE INDEX uk_ns_billing_device_tax_ext_machine ON ns_billing_device (tax_num, extension_num, machine_num); CREATE INDEX idx_ns_billing_device_tax_num ON ns_billing_device (tax_num); CREATE INDEX idx_ns_billing_device_status ON ns_billing_device (device_status, report_tax_status, clear_card_status); ``` ## `ns_invoice_stock_snapshot` 发票库存快照表 ```sql CREATE TABLE ns_invoice_stock_snapshot ( id BIGINT PRIMARY KEY, device_id BIGINT, seller_tax_no VARCHAR(32) NOT NULL, extension_num VARCHAR(32), machine_num VARCHAR(64), terminal_num VARCHAR(64), invoice_line VARCHAR(16), invoice_code VARCHAR(32), invoice_num_start VARCHAR(32), invoice_num_end VARCHAR(32), remain_num INT, is_default SMALLINT, source_type VARCHAR(16) NOT NULL, snapshot_time DATETIME NOT NULL, created_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql ALTER TABLE ns_invoice_stock_snapshot ADD CONSTRAINT fk_ns_invoice_stock_device FOREIGN KEY (device_id) REFERENCES ns_billing_device(id); CREATE INDEX idx_ns_stock_device_time ON ns_invoice_stock_snapshot (device_id, snapshot_time); CREATE INDEX idx_ns_stock_tax_line_time ON ns_invoice_stock_snapshot (seller_tax_no, invoice_line, snapshot_time); ``` ## `ns_enterprise_billing_config` 企业开票配置表 ```sql CREATE TABLE ns_enterprise_billing_config ( id BIGINT PRIMARY KEY, tax_num VARCHAR(32) NOT NULL, company_id VARCHAR(64), use_scope VARCHAR(32), clerker VARCHAR(128), seller_address VARCHAR(255), seller_tel VARCHAR(64), seller_bank VARCHAR(255), seller_account VARCHAR(255), payee VARCHAR(64), checker VARCHAR(64), project_code VARCHAR(64), department_name VARCHAR(128), auth_status VARCHAR(32), last_auth_time DATETIME, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql CREATE UNIQUE INDEX uk_ns_enterprise_billing_config_tax_num ON ns_enterprise_billing_config (tax_num); ``` ## `ns_platform_event_log` 平台回调事件表 ```sql CREATE TABLE ns_platform_event_log ( id BIGINT PRIMARY KEY, event_type VARCHAR(32) NOT NULL, event_key VARCHAR(128) NOT NULL, seller_tax_no VARCHAR(32), business_key VARCHAR(128), payload_json TEXT NOT NULL, process_status VARCHAR(32) NOT NULL, process_message VARCHAR(1000), processed_at DATETIME, created_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql CREATE UNIQUE INDEX uk_ns_platform_event_log_event_key ON ns_platform_event_log (event_key); CREATE INDEX idx_ns_platform_event_log_type_status ON ns_platform_event_log (event_type, process_status); ``` ## `ns_platform_request_log` 平台请求响应日志表 ```sql CREATE TABLE ns_platform_request_log ( id BIGINT PRIMARY KEY, request_id VARCHAR(64) NOT NULL, business_type VARCHAR(32), business_id VARCHAR(64), method_name VARCHAR(128), request_headers_masked TEXT, request_body TEXT, response_body TEXT, response_code VARCHAR(32), success_flag SMALLINT, error_message VARCHAR(1000), created_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql CREATE UNIQUE INDEX uk_ns_platform_request_log_request_id ON ns_platform_request_log (request_id); CREATE INDEX idx_ns_platform_request_log_business ON ns_platform_request_log (business_type, business_id); CREATE INDEX idx_ns_platform_request_log_method_name ON ns_platform_request_log (method_name); ``` ## `ns_config_dictionary_cache` 配置字典缓存表(可选) ```sql CREATE TABLE ns_config_dictionary_cache ( id BIGINT PRIMARY KEY, dict_type VARCHAR(64) NOT NULL, dict_key VARCHAR(128) NOT NULL, dict_name VARCHAR(255), company_id VARCHAR(64), company_name VARCHAR(255), extra_json TEXT, last_sync_time DATETIME, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL ); ``` ### 约束与索引建议 ```sql CREATE UNIQUE INDEX uk_ns_config_dictionary_cache_type_key ON ns_config_dictionary_cache (dict_type, dict_key); CREATE INDEX idx_ns_config_dictionary_cache_type ON ns_config_dictionary_cache (dict_type); ``` ## 首期最小实施 DDL 建议 若以“最小可用”为目标,建议优先建以下 7 张表: - `ns_invoice` - `ns_invoice_item` - `ns_invoice_delivery` - `ns_invoice_reversal` - `ns_billing_device` - `ns_invoice_stock_snapshot` - `ns_platform_request_log` 第二批补充: - `ns_red_document` - `ns_red_document_item` - `ns_platform_event_log` - `ns_enterprise_billing_config` ## 后续建议 建议在此基础上继续完成: - 字段注释 SQL 草案 - 状态码 / 枚举字典与字段注释联动 - PostgreSQL 16 / openGauss 方言适配版本 - 与 `docs/design/03_Technical_Design/01_Database_Design.md` 的正式章节对齐