fujian_water_biz_doc/docs/guides/NUOSHUITONG_DDL_DRAFT.md
tangweijie 3fee9a2c18 docs: add Nuoshuitong integration design pack
Add a Nuoshuitong documentation set covering the implementation checklist, split interface spec notes, normalized enums, and database/DDL guidance so follow-on integration can start from a consistent source of truth.

Constraint: Current phase is documentation-first and must not require backend/frontend code changes
Rejected: Merge the material directly into formal master design docs now | would broaden scope before the integration model and dialect strategy are reviewed
Directive: Treat these guides as integration-layer inputs until they are reconciled with formal technical design masters
Confidence: high
Scope-risk: moderate

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:50:46 +08:00

14 KiB

诺税通对接 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 发票主表

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)
);

约束与索引建议

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 发票明细表

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
);

约束与索引建议

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 发票交付记录表

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
);

约束与索引建议

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 发票逆向处理表

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
);

约束与索引建议

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 红字单据主表

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
);

约束与索引建议

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 红字单据明细表

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
);

约束与索引建议

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 开票设备表

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
);

约束与索引建议

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 发票库存快照表

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
);

约束与索引建议

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 企业开票配置表

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
);

约束与索引建议

CREATE UNIQUE INDEX uk_ns_enterprise_billing_config_tax_num
    ON ns_enterprise_billing_config (tax_num);

ns_platform_event_log 平台回调事件表

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
);

约束与索引建议

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 平台请求响应日志表

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
);

约束与索引建议

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 配置字典缓存表(可选)

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
);

约束与索引建议

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 的正式章节对齐