307 lines
13 KiB
Markdown
307 lines
13 KiB
Markdown
|
|
# 数据库调整设计
|
|||
|
|
|
|||
|
|
## 1. 调整目标
|
|||
|
|
|
|||
|
|
基于现有 `数据库.sql`,补齐开发总纲中新增或明确的能力:
|
|||
|
|
|
|||
|
|
- 订单状态新增 `cancel_pending`
|
|||
|
|
- 订单固定提成金额
|
|||
|
|
- 订单取消申请与取消前状态记录
|
|||
|
|
- 产品分类独立维护
|
|||
|
|
- 报表分类映射配置
|
|||
|
|
- 欠款生成模式配置
|
|||
|
|
- 阿里云 OSS 文件字段补充
|
|||
|
|
- 司机任务手动创建/分配需要的字段补充
|
|||
|
|
- 工厂下发确认记录
|
|||
|
|
|
|||
|
|
## 2. 状态与枚举调整
|
|||
|
|
|
|||
|
|
### 2.1 订单状态
|
|||
|
|
|
|||
|
|
`sales_order.order_status` 继续使用 `varchar(32)`,业务层限制枚举。
|
|||
|
|
|
|||
|
|
| 状态值 | 说明 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `draft` | 草稿 |
|
|||
|
|
| `pending_approve` | 待审核 |
|
|||
|
|
| `approved` | 已通过,待生成/确认下发工厂文本 |
|
|||
|
|
| `rejected` | 已退回 |
|
|||
|
|
| `pending_factory` | 已确认下发工厂,待工厂处理 |
|
|||
|
|
| `pending_driver` | 待司机接单 |
|
|||
|
|
| `accepted` | 已接单 |
|
|||
|
|
| `picked_up` | 已揽货 |
|
|||
|
|
| `delivered` | 已送达 |
|
|||
|
|
| `production` | 生产中 |
|
|||
|
|
| `shipped` | 已发货 |
|
|||
|
|
| `completed` | 已完成 |
|
|||
|
|
| `settled` | 已结算 |
|
|||
|
|
| `cancel_pending` | 取消申请中 |
|
|||
|
|
| `canceled` | 已取消 |
|
|||
|
|
|
|||
|
|
### 2.2 欠款生成模式
|
|||
|
|
|
|||
|
|
使用 `system_config` 保存。
|
|||
|
|
|
|||
|
|
| config_key | config_value | 说明 |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| `arrears_generate_mode` | `delivered` | 默认,送达后生成欠款 |
|
|||
|
|
| `arrears_generate_mode` | `shipped` | 发货后生成欠款 |
|
|||
|
|
|
|||
|
|
## 3. 表结构调整清单
|
|||
|
|
|
|||
|
|
### 3.1 `sales_order` 调整
|
|||
|
|
|
|||
|
|
新增字段:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认值 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `commission_amount` | decimal(18,2) | 0.00 | 订单固定提成金额 |
|
|||
|
|
| `cancel_requested_by` | bigint | null | 取消申请人 |
|
|||
|
|
| `cancel_requested_at` | datetime | null | 取消申请时间 |
|
|||
|
|
| `cancel_reason` | varchar(255) | null | 取消原因 |
|
|||
|
|
| `cancel_opinion` | varchar(1000) | null | 取消说明 |
|
|||
|
|
| `cancel_previous_status` | varchar(32) | null | 进入 `cancel_pending` 前状态 |
|
|||
|
|
| `supplier_text_confirmed_at` | datetime | null | 确认下发工厂时间 |
|
|||
|
|
| `supplier_text_confirmed_by` | bigint | null | 确认下发人 |
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
|
|||
|
|
| 索引 | 字段 | 说明 |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| `idx_sales_order_cancel_requested_by` | `cancel_requested_by` | 取消申请查询 |
|
|||
|
|
| `idx_sales_order_supplier_confirmed_at` | `supplier_text_confirmed_at` | 下发确认查询 |
|
|||
|
|
|
|||
|
|
### 3.2 新增 `product_category`
|
|||
|
|
|
|||
|
|
用于管理员维护产品分类,不再将工业品/日用品写死。
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `id` | bigint | PK | 主键 |
|
|||
|
|
| `category_name` | varchar(64) | not null | 分类名称 |
|
|||
|
|
| `category_code` | varchar(64) | not null unique | 分类编码 |
|
|||
|
|
| `sort_no` | int | default 0 | 排序 |
|
|||
|
|
| `status` | tinyint | default 1 | 1 启用,0 停用 |
|
|||
|
|
| `remark` | varchar(500) | null | 备注 |
|
|||
|
|
| `created_at` | datetime | default current_timestamp | 创建时间 |
|
|||
|
|
| `updated_at` | datetime | on update current_timestamp | 更新时间 |
|
|||
|
|
| `deleted` | tinyint | default 0 | 逻辑删除 |
|
|||
|
|
|
|||
|
|
### 3.3 `product` 调整
|
|||
|
|
|
|||
|
|
新增字段:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认值 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `category_id` | bigint | null | 产品分类 ID |
|
|||
|
|
|
|||
|
|
保留 `category` 快照/冗余字段,方便历史兼容和展示。
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
|
|||
|
|
| 索引 | 字段 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `idx_product_category_id` | `category_id` |
|
|||
|
|
|
|||
|
|
### 3.4 新增 `order_supplier_text_log`
|
|||
|
|
|
|||
|
|
记录下发工厂文本生成与确认历史。
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 约束 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `id` | bigint | PK | 主键 |
|
|||
|
|
| `order_id` | bigint | not null | 订单 ID |
|
|||
|
|
| `supplier_id` | bigint | not null | 工厂/供应商 ID |
|
|||
|
|
| `template_type` | varchar(64) | null | 模板类型 |
|
|||
|
|
| `text_content` | longtext | not null | 下发文本 |
|
|||
|
|
| `confirmed` | tinyint | default 0 | 是否确认下发 |
|
|||
|
|
| `confirmed_by` | bigint | null | 确认人 |
|
|||
|
|
| `confirmed_at` | datetime | null | 确认时间 |
|
|||
|
|
| `created_by` | bigint | null | 生成人 |
|
|||
|
|
| `created_at` | datetime | default current_timestamp | 创建时间 |
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
|
|||
|
|
| 索引 | 字段 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `idx_supplier_text_order_id` | `order_id` |
|
|||
|
|
| `idx_supplier_text_supplier_id` | `supplier_id` |
|
|||
|
|
|
|||
|
|
### 3.5 `logistics_task` 调整
|
|||
|
|
|
|||
|
|
现有字段基本满足手动创建司机任务。建议补充:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认值 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `created_by` | bigint | null | 任务创建人 |
|
|||
|
|
| `canceled_at` | datetime | null | 任务取消时间 |
|
|||
|
|
| `canceled_by` | bigint | null | 任务取消人 |
|
|||
|
|
| `cancel_reason` | varchar(500) | null | 任务取消原因 |
|
|||
|
|
|
|||
|
|
### 3.6 `file_attachment` 调整
|
|||
|
|
|
|||
|
|
为阿里云 OSS 图片、视频和附件补充元数据。
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认值 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `storage_provider` | varchar(32) | `aliyun_oss` | 存储服务商 |
|
|||
|
|
| `bucket_name` | varchar(128) | null | OSS Bucket |
|
|||
|
|
| `object_key` | varchar(1000) | null | OSS Object Key |
|
|||
|
|
| `content_type` | varchar(128) | null | MIME 类型 |
|
|||
|
|
| `file_ext` | varchar(32) | null | 扩展名 |
|
|||
|
|
| `file_category` | varchar(32) | null | image/video/document/export/import |
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
|
|||
|
|
| 索引 | 字段 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `idx_file_attachment_category` | `file_category` |
|
|||
|
|
| `idx_file_attachment_object_key` | `object_key` |
|
|||
|
|
|
|||
|
|
### 3.7 `customer_arrears` 调整
|
|||
|
|
|
|||
|
|
补充结算关闭字段:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 默认值 | 说明 |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| `generated_mode` | varchar(32) | null | `shipped` 或 `delivered` |
|
|||
|
|
| `settled_at` | datetime | null | 结算时间 |
|
|||
|
|
| `settled_by` | bigint | null | 结算操作人 |
|
|||
|
|
| `closed_at` | datetime | null | 关闭时间 |
|
|||
|
|
|
|||
|
|
### 3.8 `system_config` 初始化配置
|
|||
|
|
|
|||
|
|
建议初始化以下配置:
|
|||
|
|
|
|||
|
|
| config_key | config_value | config_name |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| `arrears_generate_mode` | `delivered` | 欠款生成模式 |
|
|||
|
|
| `logistics_timeout_hours` | `48` | 物流超时小时数 |
|
|||
|
|
| `inactive_customer_days` | `90` | 沉默客户周期 |
|
|||
|
|
| `inactive_customer_amount_threshold` | `1000` | 沉默客户金额阈值 |
|
|||
|
|
| `report_category_mapping` | `{}` | 报表分类映射 |
|
|||
|
|
| `aliyun_oss_bucket` | 空 | 阿里云 OSS Bucket |
|
|||
|
|
| `aliyun_oss_endpoint` | 空 | 阿里云 OSS Endpoint |
|
|||
|
|
| `aliyun_ai_region` | 空 | 阿里云 AI/OCR 地域 |
|
|||
|
|
|
|||
|
|
敏感凭证不写入数据库明文字段,使用环境变量或安全配置。
|
|||
|
|
|
|||
|
|
## 4. 建议迁移 SQL
|
|||
|
|
|
|||
|
|
以下 SQL 是基于现有 `数据库.sql` 的增量调整示例,实际执行应通过 Alembic 迁移管理。
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE IF NOT EXISTS `product_category` (
|
|||
|
|
`id` bigint NOT NULL COMMENT '主键',
|
|||
|
|
`category_name` varchar(64) NOT NULL COMMENT '分类名称',
|
|||
|
|
`category_code` varchar(64) NOT NULL COMMENT '分类编码',
|
|||
|
|
`sort_no` int NOT NULL DEFAULT 0 COMMENT '排序号',
|
|||
|
|
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1启用 0停用',
|
|||
|
|
`remark` varchar(500) 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 '更新时间',
|
|||
|
|
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '逻辑删除:0否 1是',
|
|||
|
|
PRIMARY KEY (`id`),
|
|||
|
|
UNIQUE KEY `uk_product_category_code` (`category_code`),
|
|||
|
|
KEY `idx_product_category_status` (`status`)
|
|||
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='产品分类表';
|
|||
|
|
|
|||
|
|
ALTER TABLE `product`
|
|||
|
|
ADD COLUMN `category_id` bigint DEFAULT NULL COMMENT '产品分类ID' AFTER `category`,
|
|||
|
|
ADD KEY `idx_product_category_id` (`category_id`);
|
|||
|
|
|
|||
|
|
ALTER TABLE `sales_order`
|
|||
|
|
ADD COLUMN `commission_amount` decimal(18,2) NOT NULL DEFAULT 0.00 COMMENT '订单固定提成金额' AFTER `profit_rate`,
|
|||
|
|
ADD COLUMN `cancel_requested_by` bigint DEFAULT NULL COMMENT '取消申请人' AFTER `canceled_at`,
|
|||
|
|
ADD COLUMN `cancel_requested_at` datetime DEFAULT NULL COMMENT '取消申请时间' AFTER `cancel_requested_by`,
|
|||
|
|
ADD COLUMN `cancel_reason` varchar(255) DEFAULT NULL COMMENT '取消原因' AFTER `cancel_requested_at`,
|
|||
|
|
ADD COLUMN `cancel_opinion` varchar(1000) DEFAULT NULL COMMENT '取消说明' AFTER `cancel_reason`,
|
|||
|
|
ADD COLUMN `cancel_previous_status` varchar(32) DEFAULT NULL COMMENT '取消前状态' AFTER `cancel_opinion`,
|
|||
|
|
ADD COLUMN `supplier_text_confirmed_at` datetime DEFAULT NULL COMMENT '确认下发工厂时间' AFTER `cancel_previous_status`,
|
|||
|
|
ADD COLUMN `supplier_text_confirmed_by` bigint DEFAULT NULL COMMENT '确认下发人' AFTER `supplier_text_confirmed_at`,
|
|||
|
|
ADD KEY `idx_sales_order_cancel_requested_by` (`cancel_requested_by`),
|
|||
|
|
ADD KEY `idx_sales_order_supplier_confirmed_at` (`supplier_text_confirmed_at`);
|
|||
|
|
|
|||
|
|
CREATE TABLE IF NOT EXISTS `order_supplier_text_log` (
|
|||
|
|
`id` bigint NOT NULL COMMENT '主键',
|
|||
|
|
`order_id` bigint NOT NULL COMMENT '订单ID',
|
|||
|
|
`supplier_id` bigint NOT NULL COMMENT '工厂/供应商ID',
|
|||
|
|
`template_type` varchar(64) DEFAULT NULL COMMENT '模板类型',
|
|||
|
|
`text_content` longtext NOT NULL COMMENT '下发文本',
|
|||
|
|
`confirmed` tinyint NOT NULL DEFAULT 0 COMMENT '是否确认下发:0否 1是',
|
|||
|
|
`confirmed_by` bigint DEFAULT NULL COMMENT '确认人',
|
|||
|
|
`confirmed_at` datetime DEFAULT NULL COMMENT '确认时间',
|
|||
|
|
`created_by` bigint DEFAULT NULL COMMENT '生成人',
|
|||
|
|
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|||
|
|
PRIMARY KEY (`id`),
|
|||
|
|
KEY `idx_supplier_text_order_id` (`order_id`),
|
|||
|
|
KEY `idx_supplier_text_supplier_id` (`supplier_id`)
|
|||
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='工厂下发文本记录表';
|
|||
|
|
|
|||
|
|
ALTER TABLE `logistics_task`
|
|||
|
|
ADD COLUMN `created_by` bigint DEFAULT NULL COMMENT '任务创建人' AFTER `factory_id`,
|
|||
|
|
ADD COLUMN `canceled_at` datetime DEFAULT NULL COMMENT '任务取消时间' AFTER `delivered_at`,
|
|||
|
|
ADD COLUMN `canceled_by` bigint DEFAULT NULL COMMENT '任务取消人' AFTER `canceled_at`,
|
|||
|
|
ADD COLUMN `cancel_reason` varchar(500) DEFAULT NULL COMMENT '任务取消原因' AFTER `canceled_by`;
|
|||
|
|
|
|||
|
|
ALTER TABLE `file_attachment`
|
|||
|
|
ADD COLUMN `storage_provider` varchar(32) NOT NULL DEFAULT 'aliyun_oss' COMMENT '存储服务商' AFTER `file_size`,
|
|||
|
|
ADD COLUMN `bucket_name` varchar(128) DEFAULT NULL COMMENT 'OSS Bucket' AFTER `storage_provider`,
|
|||
|
|
ADD COLUMN `object_key` varchar(1000) DEFAULT NULL COMMENT 'OSS Object Key' AFTER `bucket_name`,
|
|||
|
|
ADD COLUMN `content_type` varchar(128) DEFAULT NULL COMMENT 'MIME类型' AFTER `object_key`,
|
|||
|
|
ADD COLUMN `file_ext` varchar(32) DEFAULT NULL COMMENT '扩展名' AFTER `content_type`,
|
|||
|
|
ADD COLUMN `file_category` varchar(32) DEFAULT NULL COMMENT '文件类别' AFTER `file_ext`,
|
|||
|
|
ADD KEY `idx_file_attachment_category` (`file_category`),
|
|||
|
|
ADD KEY `idx_file_attachment_object_key` (`object_key`(191));
|
|||
|
|
|
|||
|
|
ALTER TABLE `customer_arrears`
|
|||
|
|
ADD COLUMN `generated_mode` varchar(32) DEFAULT NULL COMMENT '欠款生成模式:shipped/delivered' AFTER `status`,
|
|||
|
|
ADD COLUMN `settled_at` datetime DEFAULT NULL COMMENT '结算时间' AFTER `reminded_at`,
|
|||
|
|
ADD COLUMN `settled_by` bigint DEFAULT NULL COMMENT '结算操作人' AFTER `settled_at`,
|
|||
|
|
ADD COLUMN `closed_at` datetime DEFAULT NULL COMMENT '关闭时间' AFTER `settled_by`;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. 初始化数据建议
|
|||
|
|
|
|||
|
|
### 5.1 产品分类
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
INSERT INTO `product_category` (`id`, `category_name`, `category_code`, `sort_no`, `status`)
|
|||
|
|
VALUES
|
|||
|
|
(1, '工业品', 'industry', 1, 1),
|
|||
|
|
(2, '日用品', 'daily', 2, 1);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 系统配置
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
INSERT INTO `system_config` (`id`, `config_key`, `config_value`, `config_name`, `remark`, `status`)
|
|||
|
|
VALUES
|
|||
|
|
(1001, 'arrears_generate_mode', 'delivered', '欠款生成模式', 'shipped=发货后记账,delivered=送达后记账', 1),
|
|||
|
|
(1002, 'logistics_timeout_hours', '48', '物流超时小时数', '首个物流节点超过该小时数无流转提醒', 1),
|
|||
|
|
(1003, 'inactive_customer_days', '90', '沉默客户周期', '超过该天数未下单触发检查', 1),
|
|||
|
|
(1004, 'inactive_customer_amount_threshold', '1000', '沉默客户金额阈值', '低于该金额不提醒', 1),
|
|||
|
|
(1005, 'report_category_mapping', '{}', '报表分类映射', '按产品分类配置统计口径', 1);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 6. 数据一致性规则
|
|||
|
|
|
|||
|
|
| 场景 | 规则 |
|
|||
|
|
| --- | --- |
|
|||
|
|
| 客户去重 | `crm_customer.customer_name + mobile` 唯一 |
|
|||
|
|
| 产品快照 | 订单明细保存名称、规格、单位快照,历史订单不随产品变化 |
|
|||
|
|
| 取消审批 | 进入 `cancel_pending` 时保存 `cancel_previous_status`,拒绝取消后恢复 |
|
|||
|
|
| 下发确认 | 确认下发时写 `order_supplier_text_log`,订单状态变为 `pending_factory` |
|
|||
|
|
| 欠款生成 | 按 `arrears_generate_mode` 在 `shipped` 或 `delivered` 状态生成 |
|
|||
|
|
| 附件存储 | OSS 上传成功后必须写入 `file_attachment` |
|
|||
|
|
| 审计日志 | 所有关键写操作必须写入 `audit_log` |
|
|||
|
|
|
|||
|
|
## 7. Alembic 迁移要求
|
|||
|
|
|
|||
|
|
- 每次表结构变更必须生成独立 migration 文件。
|
|||
|
|
- migration 文件必须包含 upgrade 和 downgrade。
|
|||
|
|
- 初始化数据可以单独 migration,避免和结构变更混在一起。
|
|||
|
|
- 生产环境禁止直接手工改表,必须通过迁移执行。
|
|||
|
|
- 敏感配置如 OSS AccessKey、阿里云模型凭证不得写入 migration。
|
|||
|
|
|