Files
shanxia2.0/docs/db-migration/00-migration-plan.md
T
2026-06-10 22:59:34 +08:00

171 lines
7.4 KiB
Markdown
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.
# 地磅系统(db)移植实施方案
> **编写日期**:2026-06-07(修订:搬运 + 适配策略)
> **状态**:方案已定稿,**旧重写代码已清理**,待按阶段实施
> **源系统**:`simple-dibang-xiaoshou/backend` + `simple-dibang-xiaoshou/art-design-pro`
> **目标系统**:`shanxia2.0/backend` + `shanxia2.0/web-admin`
> **DDL 基线**:`docs/sql/db_tables.sql`(已写入 `docs/sql/shanxia2.0.sql`)
> **对照参考**:[`docs/bx-migration/00-migration-plan.md`](../bx-migration/00-migration-plan.md)
---
## 1. 迁移目标
将原地磅系统五模块迁入山峡一体化门户,实现:
1. **业务等价**:仪表盘、计划、出入库、地磅单、车牌及联动逻辑与原系统一致;
2. **API 契约保持**:路径、HTTP 方法、Query 参数、响应 JSON 结构 **尽量与原系统一致**(直接返回 `list[Read]` / 实体,**不用**门户 CRM 的 `success_response` + `data.list`);
3. **体系融合**:用户/角色/菜单/认证使用门户 `sys_*`;业务表使用 `db_*` + 门户公共字段;
4. **UI 融合**:先拷贝 `art-design-pro` 页面与 `*Api.ts`,再逐步适配 Fresh Mint(第二阶段)。
**不在本次范围**:原 `auth/users/cargos/companies` 独立模块(分别用门户登录、CRM 下拉替代)。
---
## 2. 核心原则(对齐 bx「搬运 + 适配」)
| 原则 | 说明 |
|------|------|
| **Router 近原样复制** | 从 `simple-dibang-xiaoshou/backend/app/api/routes/` 复制到 `backend/app/api/db/`,仅改 Depends、import、租户、UUID |
| **Service/联动逻辑整段迁移** | 尤其 `weighing.py` 的 `_process_weighing_business_logic`、`inventory/create-link-for-plan`、`plans/third-party-page` |
| **响应协议保持原样** | 列表返回数组或 Pydantic Read 模型;**禁止**改为 `/web/admin/db/*` + 门户 envelope |
| **路径保持原语义** | 挂载后仍为 `/api/plans`、`/api/weighing` 等(router prefix 不含 `/api`,由 `main.py` 统一加 `API_V1_PREFIX`) |
| **最小改动** | 不重命名 URL、不改 PATCH→PUT、不删 special endpoints(`related`、`void`、`create-link-for-plan`) |
| **门户能力注入** | 认证(`db_auth`)、租户、`tenant_no`、DB Session、MinIO 用 shanxia2.0 现有能力 |
| **主数据方案 A** | 产品/客户用 CRM 远程下拉,存名称文本;不建 `cargos`/`companies` 表 |
### 与 bx 的差异(勿混淆)
| 项 | bx | 地磅 db |
|----|-----|---------|
| 响应 envelope | `code:0` + `msg` + `data.rows` | **无 envelope**,FastAPI 直接返回 JSON |
| 原 ORM | SQLAlchemy sync | SQLModel **async** → 须改为 sync Session |
| 列表分页 | 服务端分页 | 多数列表 **全量返回**,前端筛选/分页 |
---
## 3. 范围边界
### 3.1 数据库(4 张业务表,DDL 已完成)
| 表 | 用途 | DDL |
|----|------|-----|
| `db_vehicle` | 车牌 | ✅ `docs/sql/db_tables.sql` |
| `db_purchase_plan` | 计划 | ✅ |
| `db_inbound_outbound` | 出入库 | ✅ |
| `db_weighing_slip` | 地磅单 | ✅ |
### 3.2 后端 API(移植清单见 `01-api-inventory.md`)
| 模块 | 源文件 | 原 prefix | 优先级 |
|------|--------|-----------|--------|
| 车牌 | `routes/vehicles.py` | `/vehicles` | P1 |
| 计划 | `routes/plans.py` | `/plans` | P1 |
| 出入库 | `routes/inventory.py` | `/inventory` | P2 |
| 地磅单 | `routes/weighing.py` | `/weighing` | P2(含联动) |
| 仪表盘 | `routes/dashboard.py` | `/dashboard` | P3 |
**不移植**:`auth.py`、`users.py`、`cargos.py`、`companies.py`。
### 3.3 前端页面(拷贝 + 适配)
| 分组 | 源路径 | 目标 |
|------|--------|------|
| 计划 | `art-design-pro/src/views/plans` | `web-admin/src/views/db/plans` |
| 出入库 | `art-design-pro/src/views/inventory` | `web-admin/src/views/db/inventory` |
| 地磅单 | `art-design-pro/src/views/weighing` | `web-admin/src/views/db/weighing` |
| 车牌 | master-data 车辆 Tab 或 vehicles 页 | `web-admin/src/views/db/vehicles` |
| 仪表盘 | `art-design-pro/src/views/dashboard` | `web-admin/src/views/db/dashboard` |
| API | `art-design-pro/src/api/*Api.ts` | `web-admin/src/api/db/*.ts` |
---
## 4. 目标架构
```
backend/app/
├── models/db_models.py # 按 db_tables.sql 重写(非 SQLModel)
├── schemas/db/ # 从原 schemas 复制 + id→str
├── services/db/ # 从原 routes 内联逻辑抽出或直接保留在 router(与 bx 一致,优先 router 薄层)
├── core/db_auth.py # 类比 bx_auth:门户 user → DbUserContext
└── api/db/
├── __init__.py # db_router 聚合
├── vehicles.py # prefix="/vehicles"
├── plans.py # prefix="/plans"
├── inventory.py # prefix="/inventory"
├── weighing.py # prefix="/weighing"
└── dashboard.py # prefix="/dashboard"
```
```python
# main.py
from app.api.db import db_router
app.include_router(db_router, prefix=settings.API_V1_PREFIX)
# → /api/plans、/api/weighing ...
```
---
## 5. 门户适配层
### 5.1 认证(`core/db_auth.py`)
- 原:`get_async_session` + 无统一门户用户
- 新:`Depends(get_db_current_user)`,从 `require_admin_or_super_admin` 或菜单权限取 `tenant_no`、`user_id`、`dept_id`
### 5.2 数据模型改造
| 原 | 新 |
|----|-----|
| `id: int` | `id: str` UUID |
| `is_deleted` | `del_flag` |
| `created_at: str` | `create_time: datetime` |
| 无租户 | `tenant_no` 必填 |
| `remarks` | `remark`(门户公共字段) |
### 5.3 async → sync
原系统使用 SQLModel `AsyncSession`;门户使用同步 `Session`。搬运时:
- `await session.exec(select(...))` → `db.query(...).filter(...)`
- `await session.commit()` → `db.commit()`(在 router 或 service 层统一)
---
## 6. 分阶段交付
| 阶段 | 内容 | 验收 |
|------|------|------|
| P0 | ORM + `db_router` 骨架 + `db_auth` + health | `/api/db/health` 或模块 health |
| P1 | vehicles + plans(含 fill-link、third-party-page、related) | 端点对照表 P1 全绿 |
| P2 | inventory + weighing(含联动、void、related) | 计划→地磅→出入库全链路 |
| P3 | dashboard 统计 SQL | 与原 dashboard 数值一致 |
| P4 | 定时任务:计划按月自动生成 | 手动触发成功 |
| P5 | sys_menu 菜单 SQL | 侧栏五模块可见 |
| P6 | 前端拷贝 + API 路径对齐 | 原页面功能可跑通 |
| P6-FM | Fresh Mint UI 换皮 | 对照 ui-spec |
---
## 7. 历史数据
- 脚本:`backend/scripts/migrate_dibang_data.py`(**保留原地磅 int id**,写入 `VARCHAR(64)` 如 `"12"`;外键同值传递)
- 主键策略:int → 同值字符串(非 UUID);`purchase_plan_id`、`inbound_outbound_id`、`last_weighing_slip_id` 随主键一并保留
---
## 8. 文档索引
| 文件 | 用途 |
|------|------|
| [01-api-inventory.md](./01-api-inventory.md) | 端点全量清单(防遗漏) |
| [ref-backend-adapt.md](./ref-backend-adapt.md) | Router/Service 改造检查清单 |
| [module-status.md](./module-status.md) | 实施进度 |
| [../superpowers/specs/2026-06-07-dibang-migration-design.md](../superpowers/specs/2026-06-07-dibang-migration-design.md) | 业务设计(方案 A、联动、单位) |
---
## 9. 已废弃方案说明
2026-06-07 前曾按「门户 CRM 式 CRUD 重写」实现过 `/api/web/admin/db/*` 路由与 Fresh Mint 新页面,**已全部删除**。后续实施 **必须** 以本文档与 `01-api-inventory.md` 为准。