This commit is contained in:
zlwu committed 2026-06-10 22:59:34 +08:00
1 parent 725774ef0c
commit c3be9d1dce
176 files changed
+41925 -6342

No files matched your search

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-07
@@ -0,0 +1,83 @@
## Context
原地磅系统源码位于 `simple-dibang-xiaoshou`(FastAPI + SQLModel async + art-design-pro),DDL 快照为 `docs/sql/dibang.sql`。shanxia2.0 已具备 CRM 产品/客户主数据、统一用户权限、报销 bx 子域移植先例。用户确认采用方案 A(主数据仅存名称文本)及五模块移植范围。
**原系统核心表关系**:`db_weighing_slip` → `db_purchase_plan` → `db_inbound_outbound`,保存地磅单时在同一事务内更新计划执行量并生成出入库单。
## Goals / Non-Goals
**Goals:**
- 4 张 `db_*` 表符合 database-conventions(UUID、tenant_no、del_flag、create_time 等)
- 完整移植五模块业务功能及地磅→计划→出入库联动
- 计划按月自动生成定时任务
- web-admin Fresh Mint UI + 菜单权限
- 历史数据可迁移脚本
**Non-Goals:**
- 不移植 cargos/companies/users 表及对应 CRUD 页
- 不引入 product_id/customer_id 外键(方案 A)
- 不做小程序端地磅页面(本期仅 web-admin)
- 不改造 CRM 产品/客户模块本身
- 不保留原地磅独立登录与 JWT 体系
## Decisions
### D1: 表前缀 `db_*` 与子域 `app/api/db/`
**选择**: 业务表 `db_purchase_plan` 等,代码子域 `db`(非 `dibang` 缩写混用)
**理由**: 与 `bx_*`、`crm_*` 命名一致;路由 `/api/.../db/` 简短
**替代**: 表名保留 `purchase_plans` → 违反门户命名规范,弃用
### D2: 主数据方案 A — 文本冗余
**选择**: 业务表继续存 `product`/`cargo_name`/`customer_name` 等 varchar;表单从 CRM 下拉选中后写入名称
**理由**: 与原系统行为一致;避免 CRM 与地磅历史名称不一致导致迁移失败
**替代**: 加 FK 字段 → 改动大、历史数据对齐成本高,用户已拒绝
### D3: 后端参照 bx 子域而非照搬 SQLModel async
**选择**: SQLAlchemy 同步 Session + `DbCrudService` 基类 + 门户 `{ code, data, message }` 响应
**理由**: 与 shanxia2.0 主栈一致;bx 已验证该模式
**替代**: 保留 async SQLModel → 与门户 middleware/CRUD 模式割裂
### D4: 地磅作废保留 `is_voided` 字段
**选择**: 除 `del_flag` 外保留 `is_voided`
**理由**: 作废是业务操作(可回滚计划量),与软删除语义不同;原系统已有此区分
**替代**: 合并为 status 枚举 → 需大范围改前端逻辑,本期不采用
### D5: 前端按 P02 复杂列表 + order 模板页
**选择**: 计划/出入库/地磅单参照 `views/system/order/index.vue`;车辆参照 `unit/index.vue`
**理由**: ui-conventions 模板页要求;原 art-design-pro 样式不可直接复用
**替代**: 复制 art-design-pro 页面 → 违反 Fresh Mint 规范
### D6: 定时任务迁入 APScheduler
**选择**: `app/tasks/db_auto_plan.py`,在 `init_scheduled_tasks` 注册
**理由**: 门户已有 APScheduler;原独立 cron 脚本可退役
**替代**: 保留 shell cron → 运维分散,弃用
## Risks / Trade-offs
- **[名称不一致]** CRM 下拉与历史文本可能不匹配 → 允许手工输入;迁移不强制关联 CRM id
- **[联动回归]** weighing 保存逻辑复杂 → 移植时逐函数对照原 `weighing.py`;验收用原库样例数据
- **[ID 迁移]** int→UUID 关联易错 → 迁移脚本输出映射 CSV 并做 count 校验
- **[单位混用]** t vs kg → 文档与代码注释明确;禁止「优化」换算逻辑
- **[ecosystem 文档]** 归档前需更新 landscape spec → 本 change 含 delta
## Migration Plan
1. 执行 DDL 创建 `db_*` 表(空库可开发联调)
2. 部署后端 db 子域 + 前端页面(菜单权限 SQL)
3. 运行历史数据迁移脚本导入生产数据
4. 并行运行:原系统只读对照验收 1–2 周
5. 切换 DNS/入口至门户;退役原 backend 与 art-design-pro
6. **回滚**: 保留原库快照;门户侧 feature flag 关闭地磅菜单
## Open Questions
- (已关闭)主数据 FK vs 文本 → **方案 A 已确认**
- 生产切换窗口与是否双写:实施阶段与业务方确认
@@ -0,0 +1,34 @@
## Why
原地磅系统(`simple-dibang-xiaoshou`)与 shanxia2.0 一体化门户分离部署,存在独立用户体系、主数据重复(货物/往来单位)和 UI 规范不一致问题。CRM、报销已成功迁入门户,地磅后端同为 Python FastAPI,具备同类移植条件。现需将地磅核心业务迁入本仓库,实现统一登录、租户隔离与 Fresh Mint 管理端体验。
## What Changes
- 新增 4 张地磅业务表(`db_purchase_plan`、`db_weighing_slip`、`db_inbound_outbound`、`db_vehicle`),对齐 database-conventions 公共字段
- 不移植 `cargos`、`companies`、`users` 表;产品/客户通过 CRM 下拉选名称文本(方案 A,无 FK)
- 新增后端 `db` 子域:计划、地磅单、出入库、车辆、仪表盘 API 及地磅→计划→出入库联动逻辑
- 新增定时任务:计划按月自动生成(原 `auto-create-plan` 逻辑)
- 新增 web-admin 五页:仪表盘、计划管理、出入库管理、地磅单管理、车牌管理
- 新增菜单与权限配置;门户 `sys_user` 替代原地磅用户体系
- 提供 dibang 历史数据迁移脚本(int ID → UUID)
- 更新 ecosystem-landscape:地磅业务代码归属 shanxia2.0 本仓库
## Capabilities
### New Capabilities
- `dibang-schema`: 地磅四表 DDL、字段规范改造及历史数据迁移脚本
- `dibang-backend`: 地磅后端 API、Service、联动事务与定时任务
- `dibang-frontend`: 地磅 web-admin 五模块页面、API 层与菜单注册
### Modified Capabilities
- `ecosystem-landscape`: 地磅系统从「独立系统、非本仓库 backend」更新为「已迁入门户,代码在 shanxia2.0/backend + web-admin」
## Impact
- **数据库**: `docs/sql/shanxia2.0.sql` 新增 `db_*` 表;可选增量脚本 `docs/sql/db_tables.sql`
- **后端**: 新建 `app/models/db_models.py`、`app/api/db/`、`app/services/db/`、`app/tasks/db_auto_plan.py`;`app/main.py`、`app/api/__init__.py` 注册路由
- **前端**: 新建 `web-admin/src/views/db/**`、`web-admin/src/api/db/**`;路由与菜单配置
- **依赖**: 只读依赖已有 `crm_product`、`crm_customer` API;不修改 CRM 表结构
- **源系统**: `simple-dibang-xiaoshou` 保留只读参考,迁移完成后可退役独立部署
@@ -0,0 +1,83 @@
## ADDED Requirements
### Requirement: 地磅后端子域路由注册
系统 SHALL 在 shanxia2.0 Python 后端提供 `db` 子域 API,并在 `app/main.py` 与 `app/api/__init__.py` 注册路由。所有业务接口 SHALL 经过门户鉴权中间件,且查询与写入 SHALL 按当前用户 `tenant_no` 隔离。
#### Scenario: 路由可访问
- **WHEN** 已登录管理员请求地磅计划列表 API
- **THEN** 返回 `{ code: 0, data: ... }` 且仅含当前租户数据
### Requirement: 车牌管理 CRUD
系统 SHALL 提供 `db_vehicle` 的列表(分页)、详情、新增、修改、软删除 API。车牌号在同一租户下 SHALL 唯一(未删除记录)。
#### Scenario: 新增车牌
- **WHEN** 用户提交车牌号「皖A12345」
- **THEN** 创建成功并返回 UUID 主键,`del_flag=0`
#### Scenario: 重复车牌拒绝
- **WHEN** 用户提交已存在且未删除的车牌号
- **THEN** 返回业务错误提示车牌已存在
### Requirement: 计划管理 CRUD 与计划号生成
系统 SHALL 提供计划的分页列表、详情、新增、修改、软删除 API。新增计划时 SHALL 自动生成 `plan_no`(格式与原系统一致:`SX-` + 时间戳序号)。计划 SHALL 支持 `auto_generate_enabled` 等自动生成相关字段的读写。
#### Scenario: 创建计划
- **WHEN** 用户创建入库计划并填写产品名称、计划数量
- **THEN** 系统生成唯一 `plan_no` 并持久化,`execution_status` 为初始待执行状态
### Requirement: 出入库管理 CRUD
系统 SHALL 提供出入库单的分页列表、详情、新增、修改、软删除 API,字段语义与原 `inbound_outbound` 一致(含 `partner_company`、`quantity` 吨、`status` 等)。
#### Scenario: 查询出入库列表
- **WHEN** 用户按日期范围筛选出入库列表
- **THEN** 返回匹配记录,默认按 `create_time DESC` 排序
### Requirement: 地磅单管理与联动事务
系统 SHALL 提供地磅单的列表、详情、新增、修改、作废 API。保存地磅单时 SHALL 在同一数据库事务内:更新关联计划的 `executed_quantity` 与 `execution_status`;创建或更新关联 `db_inbound_outbound` 记录;回写 `purchase_plan_id` 与 `inbound_outbound_id`。作废地磅单 SHALL 设置 `is_voided=1` 并回滚已计入计划的执行量(若适用)。
#### Scenario: 保存地磅单联动计划
- **WHEN** 用户保存一张关联计划的地磅单且净重有效
- **THEN** 关联计划的 `executed_quantity` 增加,`last_weighing_slip_id` 更新为当前地磅单 id
#### Scenario: 作废地磅单
- **WHEN** 用户对已保存地磅单执行作废
- **THEN** 该记录 `is_voided=1`,计划执行量相应回滚,列表默认不展示作废单(或按原系统规则过滤)
### Requirement: 仪表盘统计 API
系统 SHALL 提供仪表盘聚合 API,至少包含与原系统对等的统计维度(如计划/地磅/出入库数量概览、近期趋势),数据 SHALL 按 `tenant_no` 过滤。
#### Scenario: 仪表盘数据
- **WHEN** 用户打开地磅仪表盘页并请求统计 API
- **THEN** 返回当前租户下的汇总指标 JSON
### Requirement: 计划按月自动生成任务
系统 SHALL 提供定时任务,每月对 `auto_generate_enabled=1` 且未过 `auto_generate_end_month` 的计划复制生成新月计划,并更新 `auto_generate_last_month` 以防重复,逻辑与原 `auto-create-plan` 脚本等价。
#### Scenario: 月初自动生成
- **WHEN** 定时任务在新区间第一天运行且存在符合条件的模板计划
- **THEN** 生成新计划记录且模板计划的 `auto_generate_last_month` 更新为当前月
### Requirement: 主数据下拉只读 CRM
计划/地磅/出入库表单所需产品、客户选项 SHALL 通过已有 CRM API 获取;后端 SHALL NOT 新建 cargos/companies 表或对应 CRUD 路由。
#### Scenario: 产品下拉数据源
- **WHEN** 前端请求 CRM 产品列表用于地磅单表单
- **THEN** 使用现有 CRM 产品 API,选中后仅将 `product_name` 写入地磅业务字段
@@ -0,0 +1,82 @@
## ADDED Requirements
### Requirement: 地磅管理菜单与五模块页面
web-admin SHALL 提供「地磅管理」菜单及五个页面:仪表盘、计划管理、出入库管理、地磅单管理、车牌管理。页面 SHALL 遵循 `docs/web-admin-ui-spec-fresh-mint.md` 与 ui-conventions 模板页约定。
#### Scenario: 菜单可见
- **WHEN** 已授权用户登录 web-admin
- **THEN** 侧栏可见「地磅管理」及上述五个子菜单项
### Requirement: 列表页布局规范
计划管理、出入库管理、地磅单管理列表页 SHALL 采用复杂业务列表模式(参照 `/#/demo/order`):筛选区、工具栏、表格、同容器分页;操作列 `fixed="right"`;状态类字段用 `<el-tag>` 展示。
#### Scenario: 计划列表操作列
- **WHEN** 用户打开计划管理列表
- **THEN** 操作列固定右侧且按钮不换行
### Requirement: 车牌管理标准列表
车牌管理页 SHALL 参照 `/#/demo/unit` 标准列表:分页 CRUD、软删除、Fresh Mint 筛选与弹窗表单(`label-position="top"`)。
#### Scenario: 车牌新增弹窗
- **WHEN** 用户点击新增车牌
- **THEN** 弹出两列表单弹窗,底栏取消/确定带图标
### Requirement: 主数据下拉集成 CRM
计划、地磅、出入库表单中产品与客户字段 SHALL 使用远程搜索下拉,数据源为 CRM 产品/客户 API;选中后 SHALL 将名称写入表单字段(不展示或提交 CRM id 作为业务主键)。
#### Scenario: 地磅单选择客户
- **WHEN** 用户在地磅单表单搜索并选择客户
- **THEN** `supplier` 或 `consignee` 字段填入 `customer_name` 文本
### Requirement: 磅单二维码弹窗业务例外
出入库列表「磅单二维码」弹窗 SHALL 保留现场扫码展示样式(深色遮罩、车牌黄底卡片、磅单摘要 + QR 码),作为地磅业务 UI 例外;SHALL NOT 强制套用 `SystemViewDialog` 或 `dialog-form-layout`。样式类名:`db-qrcode-dialog` / `db-qrcode-overlay` / `pound-slip-capture-inline`。
#### Scenario: 展示磅单二维码
- **WHEN** 用户在出入库列表点击「磅单二维码」
- **THEN** 弹出业务专用二维码弹窗,而非标准 Fresh Mint 查看弹窗
### Requirement: 关联数据查看弹窗
计划、出入库、地磅单列表「查看关联数据」SHALL 使用 `SystemViewDialog`(P09),通过 `DbRelatedViewDialog` 展示分区 KV 字段;状态/类型字段 SHALL 使用 `tagType` 渲染 Tag。
#### Scenario: 计划页查看关联
- **WHEN** 用户在计划列表点击「查看」
- **THEN** 弹出 SystemViewDialog 风格弹窗,按时间倒序展示关联出入库单与地磅单分区
### Requirement: 车牌下拉可选
地磅单、计划、出入库表单中车牌字段 SHALL 支持从 `db_vehicle` 列表选择或手工输入。
#### Scenario: 选择已有车牌
- **WHEN** 用户从车牌下拉选择「皖A12345」
- **THEN** 表单 `vehicle_no` 设为该车牌号
### Requirement: 仪表盘页面
仪表盘页 SHALL 展示后端统计 API 返回的概览数据与图表,布局符合 Fresh Mint 面板规范。
#### Scenario: 加载仪表盘
- **WHEN** 用户进入地磅仪表盘
- **THEN** 页面请求 dashboard API 并渲染统计卡片/图表,loading 态正确
### Requirement: API 层与类型定义
web-admin SHALL 在 `src/api/db/` 提供与后端 db 子域对应的 TypeScript API 函数;列表请求 SHALL 传递筛选参数(参照 bx 规范:`search()` 传 filter,非空 `refresh()`)。
#### Scenario: 计划列表筛选
- **WHEN** 用户点击查询并填写计划号条件
- **THEN** 前端调用 API 时携带该筛选参数且重置到第 1 页
@@ -0,0 +1,47 @@
## ADDED Requirements
### Requirement: 地磅业务表 DDL
系统 SHALL 在 shanxia2.0 库中提供四张地磅业务表:`db_purchase_plan`、`db_weighing_slip`、`db_inbound_outbound`、`db_vehicle`。每张表 SHALL 使用 `VARCHAR(64)` UUID 主键,并在业务字段之后包含 database-conventions 规定的公共字段(`tenant_no` 至 `del_flag`)。
#### Scenario: 表结构符合公共字段约定
- **WHEN** 查阅 `docs/sql/shanxia2.0.sql` 中 `db_purchase_plan` 定义
- **THEN** 可见 `id` 为 VARCHAR(64),且含 `tenant_no`、`create_time`、`update_time`、`del_flag` 等公共字段
#### Scenario: 关联字段为 UUID
- **WHEN** 查阅 `db_weighing_slip` 表定义
- **THEN** `purchase_plan_id` 与 `inbound_outbound_id` 为 VARCHAR(64),可为 NULL
### Requirement: 业务字段保留与原系统语义
四表 SHALL 保留原地磅核心业务字段名与语义(如 `plan_no`、`execution_status`、`cargo_name`、`is_voided`、`auto_generate_enabled`),仅将不符合规范的类型(如 int 主键、varchar 时间、is_deleted)改为规范形式。
#### Scenario: 地磅单保留作废标记
- **WHEN** 查阅 `db_weighing_slip` 表定义
- **THEN** 存在 `is_voided` 字段(0 正常,1 作废),与 `del_flag` 并存
#### Scenario: 计划表保留自动生成字段
- **WHEN** 查阅 `db_purchase_plan` 表定义
- **THEN** 存在 `auto_generate_enabled`、`auto_generate_end_month`、`auto_generate_last_month` 字段
### Requirement: 历史数据迁移脚本
项目 SHALL 提供可将原地磅库(`dibang.sql` 或生产库)四表数据导入 shanxia2.0 的迁移脚本,生成新 UUID 并维护旧 int id 到新 id 的映射,重写表间关联 ID。
#### Scenario: 迁移后关联完整
- **WHEN** 对迁移后的 `db_weighing_slip` 抽样检查 `purchase_plan_id`
- **THEN** 非 NULL 的 `purchase_plan_id` 均能在 `db_purchase_plan.id` 中找到对应记录
### Requirement: DDL 快照维护
表结构变更 SHALL 同步维护于 `docs/sql/`(增量脚本及/或 `shanxia2.0.sql` 全量快照)。
#### Scenario: 新环境建表
- **WHEN** 在新 MySQL 实例执行项目提供的地磅 DDL 脚本
- **THEN** 四张 `db_*` 表创建成功且无语法错误
@@ -0,0 +1,45 @@
## MODIFIED Requirements
### Requirement: 本仓库与周边系统的边界
`shanxia2.0` 仓库 SHALL 承载一体化门户(Python FastAPI + `web-admin` + `miniprogram`)及已迁入的子域业务(含 CRM、报销 bx、**地磅 db**)。CRM 代码仍在并列仓库 `shanxia/crm/`。地磅业务 SHALL 在本仓库 `backend/` 与 `web-admin/` 内实现;DDL 快照维护于 `docs/sql/shanxia2.0.sql`(`db_*` 表),`docs/sql/dibang.sql` 保留为迁移前原系统只读参考。
#### Scenario: 新人定位地磅库表(迁移后)
- **WHEN** 在 `shanxia2.0` 仓库内开发地磅、称重单、进出库等业务
- **THEN** 查阅与变更 DDL SHALL 使用 `docs/sql/shanxia2.0.sql` 中 `db_*` 表,ORM 与 database-conventions 一致
#### Scenario: 新人定位地磅代码(迁移后)
- **WHEN** 任务描述涉及地磅、称重单、计划、出入库或 `db_*` 表
- **THEN** Agent SHALL 在 `shanxia2.0/backend/app/api/db/` 与 `shanxia2.0/web-admin/src/views/db/` 查找与修改代码
#### Scenario: 跨系统需求评审
- **WHEN** 需求同时涉及门户与 CRM
- **THEN** 设计说明 SHALL 分别标明 SQL 快照与代码路径;地磅与 CRM 通过 API 读主数据,不混改 CRM DDL
### Requirement: 多系统 SQL 模型权威文件索引
山峡相关产品线 SHALL 将下列 `docs/sql/` 导出文件视为各系统数据库模型的**权威 DDL 快照**(Navicat 导出,MySQL 5.7);实现或评审时 SHALL 以对应文件为准,不得与 `shanxia2.0` 本仓库后端模型混用。
| 系统 | SQL 快照路径 | 典型库名(导出元数据) | 表命名特征 | 对应工程 |
|------|----------------|------------------------|------------|----------|
| 地磅系统(迁移前参考) | `docs/sql/dibang.sql` | `dibang-test` | `cargos`、`companies`、`weighing_slips`、`inbound_outbound` 等 | 原 `simple-dibang-xiaoshou`(只读参考) |
| 山峡一体化门户 | `docs/sql/shanxia2.0.sql` | `shanxia2.0` | `sys_*`、`crm_*`、`bx_*`、**`db_*`**;公共字段含 `tenant_no`、`del_flag` | 本仓库 `backend/` + `web-admin/` + `miniprogram/` |
| 山峡 CRM 系统 | `docs/sql/sx.sql` | `sx` | `crm_*`(线索/客户/商机/合同/回款等) | 独立仓库 `shanxia/crm/` |
#### Scenario: 新人定位门户库表
- **WHEN** 在 `shanxia2.0` 仓库内开发细胞存储、系统管理、工作流、地磅等门户能力
- **THEN** 查阅与变更 DDL SHALL 使用 `docs/sql/shanxia2.0.sql`,且 ORM/迁移与 `database-conventions` 公共字段约定一致
#### Scenario: 新人定位 CRM 库表
- **WHEN** 开发线索、客户、合同、回款等 CRM 业务
- **THEN** 查阅 DDL SHALL 使用 `docs/sql/sx.sql`,代码变更 SHALL 在 `shanxia` 仓库的 `crm/` 工程内进行,而非 `shanxia2.0/backend/`
#### Scenario: 新人定位地磅原库(历史参考)
- **WHEN** 需要对照迁移前地磅表结构或历史数据格式
- **THEN** 查阅 `docs/sql/dibang.sql`,且 SHALL NOT 将其中表结构直接当作门户库现行标准
@@ -0,0 +1,49 @@
## 1. SQL 与数据模型
- [x] 1.1 编写 `docs/sql/db_tables.sql`:四张 `db_*` 表 DDL(含公共字段、索引、注释)
- [x] 1.2 合并 DDL 至 `docs/sql/shanxia2.0.sql` 全量快照
- [x] 1.3 创建 `backend/app/models/db_models.py`:DbPurchasePlan、DbWeighingSlip、DbInboundOutbound、DbVehicle
- [x] 1.4 在 `backend/app/main.py` 导入 db_models(# noqa: F401)
## 2. 后端基础层
- [x] 2.1 创建 `backend/app/services/db/base.py`(DbCrudService,参照 BxCrudService)
- [x] 2.2 创建 `backend/app/schemas/db/`:各实体 CreateBody/UpdateBody/Response
- [x] 2.3 创建 `backend/app/api/db/__init__.py` 聚合 db_router
- [x] 2.4 在 `backend/app/api/__init__.py` 与 `backend/app/main.py` 注册 db_router
## 3. 后端业务 API(按依赖顺序)
- [x] 3.1 实现 `api/db/vehicles.py` + 主数据 CRUD(车牌;原 task 写 vehicle.py)
- [x] 3.2 实现 `api/db/plans.py` + `services/db/plan_helpers.py` 等(计划 CRUD + plan_no 生成)
- [x] 3.3 实现 `api/db/inventory.py` + 出入库 CRUD
- [x] 3.4 实现 `api/db/weighing.py` + `services/db/weighing_logic.py`(地磅单 CRUD + 联动事务 + 作废)
- [x] 3.5 实现 `api/db/dashboard.py`(统计聚合)
- [x] 3.6 创建 `backend/app/tasks/db_auto_plan.py` 并在 `app/tasks/__init__.py` 注册定时任务
## 4. 前端 API 与类型
- [x] 4.1 创建 `web-admin/src/api/db/vehicles.ts`、`plans.ts`、`inventory.ts`、`weighing.ts`、`dashboard.ts`
- [x] 4.2 TypeScript 类型定义于各 `web-admin/src/api/db/*.ts` 模块(未单独写入 api.d.ts)
## 5. 前端页面(Fresh Mint)
- [x] 5.1 创建 `web-admin/src/views/db/vehicles/index.vue`(P01,参照 unit 模板)
- [x] 5.2 创建 `web-admin/src/views/db/plans/index.vue` + 表单弹窗(P02,参照 order 模板)
- [x] 5.3 创建 `web-admin/src/views/db/inventory/index.vue` + 表单弹窗(P02)
- [x] 5.4 创建 `web-admin/src/views/db/weighing/index.vue` + 表单弹窗(P02;含 CRM 产品/客户下拉、车牌下拉、作废 Tag)
- [x] 5.5 创建 `web-admin/src/views/db/dashboard/index.vue`(统计卡片/图表,参照 console)
- [x] 5.6 注册路由与侧栏菜单(`router/modules/sqxp.ts` + `docs/sql/20260607_db_menu.sql`)
## 6. 数据迁移与权限
- [x] 6.1 编写 `backend/scripts/migrate_dibang_data.py`:int id → UUID,重写关联
- [x] 6.2 编写地磅菜单与按钮权限初始化 SQL(`docs/sql/20260607_db_menu.sql`)
- [ ] 6.3 运行 `python scripts/check_field_consistency.py`(若适用)验证字段一致性
## 7. 验证
- [ ] 7.1 Swagger 验证各 db API CRUD 与 tenant 隔离
- [ ] 7.2 全链路验收:创建计划 → 保存地磅单 → 生成出入库 → 仪表盘统计
- [ ] 7.3 验证计划 auto_generate 定时任务(可手动触发测试)
- [x] 7.4 执行 `./scripts/update-graph.sh backend frontend` 更新知识图谱