PayrollManagementSystem/db/migration/V5__add_business_data_tables.sql
liuwenxin 20fcf06f51 feat(business): 新增业务数据七表及 V5 迁移(业务/明细/状态留痕/发货/回款/评级配置)
- businesses 五项汇总冗余列服务层事务内维护;毛利润不落库(派生值,M3 台账固化)
- 行级 product_category 折算锚点(#14);回款 settlement_status 预置为 M3 防重锚点
- 评级等级种子四条(迁移+init-dev 双写);编号前缀常量 YW/SH/HK
- 双轨 SQL 同步(V4/V5 重导,schema_sync+test_models 164 例全绿)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:22:34 +08:00

187 lines
14 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Running upgrade e1133a7c670a -> 8efc189b131f
CREATE TABLE customer_rating_grades (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
grade_name VARCHAR(32) NOT NULL COMMENT '等级名称(如 A/优秀)',
min_score NUMERIC(5, 1) NOT NULL COMMENT '总分下限(含);判定=按 sort_order 升序首个 min_score ≤ 总分',
max_score NUMERIC(5, 1) NOT NULL COMMENT '总分上限(展示用)',
sort_order INTEGER NOT NULL COMMENT '排序(判定顺序,升序)' DEFAULT '0',
remark VARCHAR(255) COMMENT '说明',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT pk_customer_rating_grades PRIMARY KEY (id),
CONSTRAINT uk_customer_rating_grades_grade_name UNIQUE (grade_name)
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='客户评级等级配置表(等级映射可配置;判定按 sort_order 升序首个 min_score≤总分)' COLLATE utf8mb4_general_ci;
CREATE TABLE business_status_logs (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
business_id BIGINT UNSIGNED NOT NULL COMMENT '业务ID(固化,无外键;删除保护由服务层承担)',
old_status TINYINT NOT NULL COMMENT '变更前状态(创建首条为 1)',
new_status TINYINT NOT NULL COMMENT '变更后状态',
change_reason VARCHAR(255) COMMENT '变更原因(终止时必填)',
operator_id BIGINT UNSIGNED COMMENT '操作人ID(账号删除后置空)',
operator_name VARCHAR(64) NOT NULL COMMENT '操作人用户名(冗余固化)',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT pk_business_status_logs PRIMARY KEY (id),
CONSTRAINT fk_business_status_logs_operator_id FOREIGN KEY(operator_id) REFERENCES users (id) ON DELETE SET NULL
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='业务状态变更记录表(append-only)' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_business_status_logs_business_id ON business_status_logs (business_id);
CREATE INDEX idx_business_status_logs_create_time ON business_status_logs (create_time);
CREATE TABLE businesses (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
business_no VARCHAR(32) NOT NULL COMMENT '业务编号,自动生成 YW{YYYYMMDD}-{4位当日序号}(报表合同编号)',
customer_id BIGINT UNSIGNED NOT NULL COMMENT '客户ID(customers.id)',
business_date DATE COMMENT '业务日期(T+ 同步口径)',
status TINYINT NOT NULL COMMENT '业务状态:1执行中 2已完成 3已终止(终态不可变更;T+同步不覆盖)' DEFAULT '1',
owner_personnel_id BIGINT UNSIGNED COMMENT '负责营销人员ID(核算归属锚点;NULL=待指定,M3 核算前置校验非空;变更留痕不回溯)',
assistant_personnel_id BIGINT UNSIGNED COMMENT '协助营销人员ID(一期核算不使用,对照表 #15;仅记录事实)',
is_special TINYINT NOT NULL COMMENT '特殊业务标记:1是 0否(公司参与等)' DEFAULT '0',
special_note VARCHAR(255) COMMENT '特殊业务说明',
total_sale_amount NUMERIC(14, 2) COMMENT '销售额合计(明细行汇总冗余,服务层事务内维护,禁手工直改;不含运费口径)' DEFAULT '0',
total_cost_amount NUMERIC(14, 2) COMMENT '成本合计(明细行汇总冗余,服务层事务内维护,禁手工直改)' DEFAULT '0',
total_ship_amount NUMERIC(14, 2) COMMENT '发货金额合计(发货明细汇总冗余,服务层事务内维护,禁手工直改)' DEFAULT '0',
total_received_amount NUMERIC(14, 2) COMMENT '回款合计(回款记录汇总冗余,服务层事务内维护;M3 起付判定直接消费)' DEFAULT '0',
total_freight_amount NUMERIC(14, 2) COMMENT '运费合计(发货单汇总冗余,仅记录展示;不计入毛利润口径,对照表 #2)' DEFAULT '0',
remark VARCHAR(255) COMMENT '备注',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
source_no VARCHAR(64) COMMENT 'T+ 原始单据号(同步幂等去重锚点;唯一键待 IT 定键后升级)',
t_plus_id VARCHAR(64) COMMENT 'T+ 系统内部标识',
sync_batch_no VARCHAR(32) COMMENT '同步批次号(同步模块写入)',
synced_at DATETIME COMMENT '最近同步时间',
CONSTRAINT pk_businesses PRIMARY KEY (id),
CONSTRAINT fk_businesses_assistant_personnel_id FOREIGN KEY(assistant_personnel_id) REFERENCES personnel (id) ON DELETE RESTRICT,
CONSTRAINT fk_businesses_customer_id FOREIGN KEY(customer_id) REFERENCES customers (id) ON DELETE RESTRICT,
CONSTRAINT fk_businesses_owner_personnel_id FOREIGN KEY(owner_personnel_id) REFERENCES personnel (id) ON DELETE RESTRICT,
CONSTRAINT uk_businesses_business_no UNIQUE (business_no)
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='业务表(业务编号自动生成;T+同步不覆盖业务状态)' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_businesses_business_date ON businesses (business_date);
CREATE INDEX idx_businesses_customer_id ON businesses (customer_id);
CREATE INDEX idx_businesses_owner_personnel_id ON businesses (owner_personnel_id);
CREATE INDEX idx_businesses_source_no ON businesses (source_no);
CREATE INDEX idx_businesses_status ON businesses (status);
CREATE TABLE business_items (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
business_id BIGINT UNSIGNED NOT NULL COMMENT '业务ID(businesses.id)',
product_id BIGINT UNSIGNED COMMENT '产品ID(products.id;NULL=自由录入,未入产品库)',
product_name VARCHAR(128) NOT NULL COMMENT '产品名称(引用产品时冗余固化)',
spec_model VARCHAR(128) NOT NULL COMMENT '规格型号(冗余固化;空串对齐 products 组合唯一键口径)' DEFAULT '',
unit VARCHAR(16) COMMENT '计量单位',
product_category VARCHAR(32) NOT NULL COMMENT '产品类别(行级折算锚点,混合业务按产品逐条计算,对照表 #14;值域同 PRODUCT_CATEGORIES)',
quantity NUMERIC(14, 2) NOT NULL COMMENT '数量(>0)',
sale_price NUMERIC(14, 4) COMMENT '销售单价(元;T+ 同步或人工)',
sale_amount NUMERIC(14, 2) NOT NULL COMMENT '销售额 = 数量×销售单价(服务层计算固化;不含运费口径,毛利润率分母)',
cost_amount NUMERIC(14, 2) COMMENT '成本额(T+ 同步或人工录入,来源待 T+ 确认;毛利润额 = 销售额 − 成本额)',
guided_price NUMERIC(14, 4) COMMENT '指导价(人工录入;T+同步不覆盖,需规 2.2.1/2.2.4)',
remark VARCHAR(255) COMMENT '备注',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT pk_business_items PRIMARY KEY (id),
CONSTRAINT fk_business_items_business_id FOREIGN KEY(business_id) REFERENCES businesses (id) ON DELETE RESTRICT,
CONSTRAINT fk_business_items_product_id FOREIGN KEY(product_id) REFERENCES products (id) ON DELETE RESTRICT
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='业务产品明细表(毛利润行级源数据;指导价 T+同步不覆盖)' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_business_items_business_id ON business_items (business_id);
CREATE INDEX idx_business_items_product_category ON business_items (product_category);
CREATE INDEX idx_business_items_product_id ON business_items (product_id);
CREATE TABLE shipments (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
shipment_no VARCHAR(32) NOT NULL COMMENT '发货单号,自动生成 SH{YYYYMMDD}-{4位当日序号}(内部追溯用)',
business_id BIGINT UNSIGNED NOT NULL COMMENT '业务ID(businesses.id;终态业务禁止新发货)',
ship_date DATE NOT NULL COMMENT '发货日期(回款天数基准日,发货日首日=第 1 天)',
freight_amount NUMERIC(14, 2) NOT NULL COMMENT '运费金额(仅记录展示;不计入毛利润口径,对照表 #2)' DEFAULT '0',
total_amount NUMERIC(14, 2) NOT NULL COMMENT '发货总金额(明细行汇总冗余,服务层事务内维护,禁手工直改)' DEFAULT '0',
remark VARCHAR(255) COMMENT '备注',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
source_no VARCHAR(64) COMMENT 'T+ 原始单据号(同步幂等去重锚点;唯一键待 IT 定键后升级)',
t_plus_id VARCHAR(64) COMMENT 'T+ 系统内部标识',
sync_batch_no VARCHAR(32) COMMENT '同步批次号(同步模块写入)',
synced_at DATETIME COMMENT '最近同步时间',
CONSTRAINT pk_shipments PRIMARY KEY (id),
CONSTRAINT fk_shipments_business_id FOREIGN KEY(business_id) REFERENCES businesses (id) ON DELETE RESTRICT,
CONSTRAINT uk_shipments_shipment_no UNIQUE (shipment_no)
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='发货单表(发货日为回款天数基准日,发货日首日计第 1 天)' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_shipments_business_id ON shipments (business_id);
CREATE INDEX idx_shipments_ship_date ON shipments (ship_date);
CREATE INDEX idx_shipments_source_no ON shipments (source_no);
CREATE TABLE receipts (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
receipt_batch_no VARCHAR(32) NOT NULL COMMENT '回款批次号,自动生成 HK{YYYYMMDD}-{4位当日序号}(系统内唯一;T+ 同步回款以 source_no 幂等)',
business_id BIGINT UNSIGNED NOT NULL COMMENT '业务ID(businesses.id)',
shipment_id BIGINT UNSIGNED COMMENT '发货单ID(shipments.id;手动指定的回款对应批次,须与本行业务一致;NULL=暂未指定)',
receipt_date DATE NOT NULL COMMENT '回款到账日(M3 按此日匹配参数版本,对照表 #11)',
amount NUMERIC(14, 2) NOT NULL COMMENT '回款金额(≥0;一期禁负数/红字)',
is_barter TINYINT NOT NULL COMMENT '以物抵顶标记:1是 0否(M3 核算按应发绩效×barter.discount 折算,M2 仅标记)' DEFAULT '0',
settlement_status TINYINT NOT NULL COMMENT '绩效核算状态:0未核算 1已核算(M3 核算防重锚点;已核算回款禁改禁删)' DEFAULT '0',
remark VARCHAR(255) COMMENT '备注',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
source_no VARCHAR(64) COMMENT 'T+ 原始单据号(同步幂等去重锚点;唯一键待 IT 定键后升级)',
t_plus_id VARCHAR(64) COMMENT 'T+ 系统内部标识',
sync_batch_no VARCHAR(32) COMMENT '同步批次号(同步模块写入)',
synced_at DATETIME COMMENT '最近同步时间',
CONSTRAINT pk_receipts PRIMARY KEY (id),
CONSTRAINT fk_receipts_business_id FOREIGN KEY(business_id) REFERENCES businesses (id) ON DELETE RESTRICT,
CONSTRAINT fk_receipts_shipment_id FOREIGN KEY(shipment_id) REFERENCES shipments (id) ON DELETE RESTRICT,
CONSTRAINT uk_receipts_receipt_batch_no UNIQUE (receipt_batch_no)
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='回款表(手动指定发货批次;已核算回款禁改禁删)' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_receipts_business_id ON receipts (business_id);
CREATE INDEX idx_receipts_receipt_date ON receipts (receipt_date);
CREATE INDEX idx_receipts_settlement_status ON receipts (settlement_status);
CREATE INDEX idx_receipts_shipment_id ON receipts (shipment_id);
CREATE INDEX idx_receipts_source_no ON receipts (source_no);
CREATE TABLE shipment_items (
id BIGINT UNSIGNED NOT NULL COMMENT '主键ID' AUTO_INCREMENT,
shipment_id BIGINT UNSIGNED NOT NULL COMMENT '发货单ID(shipments.id)',
product_id BIGINT UNSIGNED COMMENT '产品ID(products.id;NULL=自由录入)',
product_name VARCHAR(128) NOT NULL COMMENT '产品名称(引用产品时冗余固化)',
spec_model VARCHAR(128) NOT NULL COMMENT '规格型号(冗余固化;空串对齐 products 组合唯一键口径)' DEFAULT '',
unit VARCHAR(16) COMMENT '计量单位',
quantity NUMERIC(14, 2) NOT NULL COMMENT '发货数量(>0)',
sale_price NUMERIC(14, 4) COMMENT '发货单价(元;T+ 同步或人工,口径待 IT 确认)',
amount NUMERIC(14, 2) NOT NULL COMMENT '行金额 = 数量×单价(服务层计算固化,不信任前端传值)',
create_time DATETIME NOT NULL COMMENT '创建时间' DEFAULT CURRENT_TIMESTAMP,
update_time DATETIME NOT NULL COMMENT '更新时间' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT pk_shipment_items PRIMARY KEY (id),
CONSTRAINT fk_shipment_items_product_id FOREIGN KEY(product_id) REFERENCES products (id) ON DELETE RESTRICT,
CONSTRAINT fk_shipment_items_shipment_id FOREIGN KEY(shipment_id) REFERENCES shipments (id) ON DELETE RESTRICT
)CHARSET=utf8mb4 ENGINE=InnoDB COMMENT='发货产品明细表' COLLATE utf8mb4_general_ci;
CREATE INDEX idx_shipment_items_product_id ON shipment_items (product_id);
CREATE INDEX idx_shipment_items_shipment_id ON shipment_items (shipment_id);
INSERT INTO customer_rating_grades (grade_name, min_score, max_score, sort_order, remark) VALUES ('A', 90, 100, 1, '优秀');
INSERT INTO customer_rating_grades (grade_name, min_score, max_score, sort_order, remark) VALUES ('B', 75, 89, 2, '良好');
INSERT INTO customer_rating_grades (grade_name, min_score, max_score, sort_order, remark) VALUES ('C', 60, 74, 3, '合格');
INSERT INTO customer_rating_grades (grade_name, min_score, max_score, sort_order, remark) VALUES ('D', 0, 59, 4, '待改进');
UPDATE alembic_version SET version_num='8efc189b131f' WHERE alembic_version.version_num = 'e1133a7c670a';