Procházet zdrojové kódy

docs: add mobile-h5 dibang adaptation design for unified backend

Capture the approved approach to point mobile-h5 at shanxia2.0 backend APIs, portal login, and CRM/PL master-data selectors without UI permission gates.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu před 2 měsíci
rodič
revize
e1170aa855

+ 183 - 0
docs/superpowers/specs/2026-08-03-mobile-h5-dibang-adapt-design.md

@@ -0,0 +1,183 @@
+# mobile-h5 地磅移动端适配一体化后端 — 设计说明
+
+**日期:** 2026-08-03  
+**状态:** 待用户审阅  
+**方案:** 方案 1 — 以改 H5 为主,复用已有 `backend` 地磅 API
+
+## 1. 背景与目标
+
+### 现状
+
+- `mobile-h5`:原地磅移动端(Vue 3 + Vant 4),对接旧地磅后端与 `docs/sql/dibang.sql`(自增 int 主键、独立主数据表)。
+- 一体化库:`docs/sql/shanxia2.0.sql` 已含 `db_weighing_slip` / `db_purchase_plan` / `db_inbound_outbound` 等。
+- 一体化后端:`backend/app/api/db/*` 已挂载 `/api/plans|inventory|weighing|dashboard`,协议对齐原 simple-dibang-xiaoshou(camelCase、直接 JSON),且 web-admin「地磅管理」已在用。
+
+### 目标
+
+将 `mobile-h5` 改造为对接一体化 `backend` + 新 SQL 模型,保留现有业务页面与操作流,尽快可上线。
+
+### 非目标
+
+- 不重做 H5 视觉 / UI 规范迁移。
+- 不把 CRM / 报销业务做进 H5。
+- 本期不改用 token 现场链接(继续出入库单 id)。
+- 本期不在 H5 增加角色/菜单权限门禁。
+- 不改 web-admin(仅作协议与选择器参考)。
+
+## 2. 已确认约束
+
+| 项 | 决定 |
+|----|------|
+| 改造策略 | 方案 1:改 H5 为主;后端仅补缺口 |
+| 登录 | 门户 `/api/web/auth/login` + RSA + JWT(对齐 web-admin) |
+| 基础资料模块 | 删除整页与 CRUD |
+| 往来单位 | 只读选 CRM 客户管理数据 |
+| 货物 | 只读选 CRM 产品管理数据;创建须带 `productId` |
+| 车牌 | 只读选 PL 车辆(`self` 自有 + `carrier` 承运商/三方) |
+| 手输自动建档 | 全端禁止(含现场页);无「手动输入新车牌」/`ensureVehicleExists` |
+| 现场填写链 | 继续用出入库单 **id** 打开 `/inventory/fill/:id` |
+| H5 权限 UI | **不做任何限制**(不按角色藏菜单/拦入口) |
+
+## 3. 架构
+
+```text
+┌─────────────────┐     JWT Bearer         ┌──────────────────────┐
+│  mobile-h5      │ ───────────────────►  │  backend (FastAPI)   │
+│  Vue3 + Vant    │                       │                      │
+│                 │  /api/web/auth/*       │  RSA 登录 / JWT       │
+│  计划/出入库/    │  /api/plans|inventory │  db_* 地磅业务        │
+│  地磅/仪表盘    │  /weighing|dashboard  │                      │
+│                 │  /api/web/crm/*        │  客户、产品           │
+│  选择器只读     │  /api/transport/vehicle│  自有+承运商车辆      │
+└─────────────────┘                       └──────────┬───────────┘
+                                                     │
+                                          MySQL shanxia2.0
+                                          db_* / crm_* / pl_vehicle
+```
+
+### 数据归属
+
+| H5 语义 | 读来源 | 写入业务表 |
+|---------|--------|------------|
+| 往来单位 | CRM 客户 | 名称快照(`customerName` / `partnerCompany` / `supplier`·`consignee` 等) |
+| 货物 | CRM 产品 | `productId` + 名称/规格快照 |
+| 车牌 | `pl_vehicle`(`vehicle_type` ∈ {`self`,`carrier`}) | 仅 `vehicleNo` 文本,禁止 create 车辆 |
+
+### 删除范围
+
+- 仪表盘「基础资料」入口;`master-data/*` 路由与页面。
+- `companyApi` / `cargoApi` / `vehicleApi` CRUD 封装。
+- `ensureVehicleExists`、「手动输入新车牌」相关 UI/逻辑。
+- 未挂菜单的用户管理页(账号改走门户)。
+
+## 4. 登录与 HTTP
+
+### 登录流程(对齐 web-admin)
+
+1. `GET /api/web/auth/login-rsa-public-key` → `publicKeyPem`
+2. JSEncrypt 加密 `{ username, password, ts }` → `{ encryptedLogin }`
+3. `POST /api/web/auth/login` → 门户信封 `{ code, data: { token, refreshToken, expiresIn, userInfo } }`
+4. H5 存储 token;请求头 `Authorization: Bearer <token>`
+5. 可选:`POST /api/web/auth/refresh-token`(参考 web-admin)
+
+### 适配要点
+
+- 新增 `loginRsa`(参考 `web-admin/src/utils/loginRsa.ts`);依赖 `jsencrypt`。
+- 登录账号为门户 `sys_user.user_no`。
+- Token 字段:门户 `token` ↔ H5 现有 `accessToken` 映射统一。
+- 响应形态:
+  - 门户 auth / CRM:`{ code, data, message }`
+  - 地磅 db API:直接 JSON 实体(与 `web-admin/src/utils/http/db.ts` 一致)
+- Dev:Vite 代理 `/api` → backend;生产:`VITE_API_URL`。
+- API 加密:与 web-admin 同策略;登录 RSA 路径与现场免登路径列入排除列表。
+- 集合根路径须带尾斜杠:`/plans/`、`/inventory/`、`/weighing/`(避免 307 丢 Authorization)。
+
+### 关于后端 `require_admin_or_super_admin`
+
+地磅业务接口依赖 `get_db_current_user` → `require_admin_or_super_admin`。  
+门户登录时 `resolve_web_role_for_user` 会把几乎所有绑定角色映射为 JWT `admin` / `super_admin`,因此 web-admin 中普通业务账号也能调地磅 API;真正限制门户入口的是**菜单授权**。  
+
+H5 **不做**前端角色/菜单门禁;能登录即可使用各业务页。403 仅展示接口返回文案。
+
+## 5. 主数据选择器
+
+| 字段 | 接口参考(web-admin) | 交互 |
+|------|----------------------|------|
+| 客户 | `POST /api/web/crm/customer/list` 远程搜 | Picker + 搜索;`allowCreate=false` |
+| 产品 | `POST /api/web/crm/products/list`(或 options) | 选中写入 `productId` + 名称/规格 |
+| 车辆 | `GET /api/transport/vehicle`(`vehicleType`=`self`/`carrier`) | 只选车牌;无手输新建 |
+
+无匹配时提示「请到门户维护」,不提供新建入口。  
+对照:web-admin 地磅用 `DbCrmCustomerSelect` / `DbCrmProductSelect` / `PlVehicleSelect`;H5 同源,但客户亦禁止 create(比门户地磅客户选择更严)。
+
+## 6. 业务页适配
+
+### 主键与类型
+
+全部业务 `id` 及关联外键(`purchasePlanId`、`inboundOutboundId`、`lastWeighingSlipId`、`fillLinkInventoryId`、`productId`)由 `number` 改为 **`string`**。  
+路由/query 禁止 `Number(uuid)`。类型对齐 `web-admin/src/api/db/{plans,inventory,weighing}.ts`。
+
+### 创建必填
+
+计划 / 出入库 / 地磅单创建须传 **`productId`**(后端 Create schema 已要求)。
+
+### 模块能力(保留)
+
+| 模块 | 能力 |
+|------|------|
+| 仪表盘 | 今日统计、四张 DualBar 图;入口:计划 / 出入库 / 地磅(去掉基础资料) |
+| 计划 | 搜索、CRUD、生成出入库、查看关联 |
+| 出入库 | 搜索、CRUD、生成地磅、磅单二维码(内容=出入库 id)、查看关联 |
+| 地磅单 | 筛选、CRUD、作废、从出入库带入创建 |
+
+操作流保持:计划 → 出入库 → 地磅单。
+
+## 7. 现场免登页
+
+- 路由:`/inventory/fill/:id`、`/inventory/plan/:id`(`noAuth`)。
+- 继续用业务 **id** 打开;读写现有免登出入库 get/patch、计划 third-party-page 等。
+- 车牌只选;去掉自动建档。
+- 若车辆列表必须鉴权:后端补**最小只读 options**(免登或带业务上下文校验),仍禁止写入主数据。
+- 二维码 URL 形态:`#/inventory/fill/{id}`。
+
+## 8. 后端变更边界
+
+优先零改或极少改。仅当下列缺口存在时补丁:
+
+1. 现场免登场景下的车辆只读检索。
+2. (可选)车辆 self+carrier 合并检索若前端拼两次调用体验差,可加薄聚合 options。
+
+不重写 db 业务逻辑;不扩大本期权限模型。
+
+## 9. 错误处理
+
+- 业务失败:toast `detail` / `message`。
+- 401:清 token → `/login`(免登页除外)。
+- 不做 H5 侧角色预检。
+
+## 10. 验收标准
+
+1. 门户账号经 RSA 登录 H5 成功。
+2. 仪表盘可用;无「基础资料」入口。
+3. 计划 → 出入库 → 地磅 → 作废全链路成功。
+4. 客户 / 产品 / 车辆只能选择,无法手输新增。
+5. 现场 fill 页用 id 打开可填;车牌只能选。
+6. 主键为 string,无 int 强转导致的故障。
+
+## 11. 实现顺序建议
+
+1. HTTP / 登录 / 环境变量 / 代理与加密排除。
+2. API 类型与路径对齐(id→string、尾斜杠、productId)。
+3. 选择器接 CRM/PL;删除基础资料与自动建档。
+4. 业务页联调(计划 / 出入库 / 地磅 / 仪表盘)。
+5. 现场页车牌只选 + 后端只读补丁(若需要)。
+6. 验收清单回归。
+
+## 12. 参考路径
+
+- H5:`mobile-h5/`
+- 后端地磅:`backend/app/api/db/`、`backend/app/schemas/db/`、`backend/app/models/db_models.py`
+- 门户登录:`backend/app/api/public.py`(`/web/auth/*`)、`web-admin/src/utils/loginRsa.ts`
+- web-admin 地磅:`web-admin/src/views/db/`、`web-admin/src/api/db/`、`web-admin/src/utils/http/db.ts`
+- 选择器参考:`DbCrmCustomerSelect.vue`、`DbCrmProductSelect.vue`、`PlVehicleSelect`
+- SQL:`docs/sql/dibang.sql`(旧)、`docs/sql/shanxia2.0.sql`(新)