docs: add design for optional reimburse detail occur date
Capture the agreed plan to add nullable occur_date (YYYY-MM-DD) on bx_reimburse_detail across backend, web-admin, and bx-mobile. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
8558d9439e
commit
071281150d
1 file changed
+142
@@ -0,0 +1,142 @@
|
||||
# 报销明细「发生时间」字段 — 设计文档
|
||||
|
||||
> **日期**: 2026-08-17
|
||||
> **状态**: 已确认设计(待实现)
|
||||
> **仓库**: shanxia2.0(`backend/` + `web-admin/` + `bx-mobile/`)
|
||||
> **入口页**: `http://localhost:3006/#/bx/reimburse/apply`
|
||||
|
||||
## 背景与问题
|
||||
|
||||
报销申请「新增 / 编辑」弹窗的报销明细当前列为:序号、费用项目、金额、报销事由、操作。
|
||||
客户希望在「报销事由」后增加可选字段「发生时间」,可填可不填;精度为年月日。
|
||||
|
||||
## 已确认决策
|
||||
|
||||
| # | 决策 | 说明 |
|
||||
|---|------|------|
|
||||
| D1 | **独立字段** | 表 `bx_reimburse_detail` 新增可空 `occur_date`(DATE),不用拼进 `remark` |
|
||||
| D2 | **仅年月日** | API / 前端统一 `YYYY-MM-DD`;不做时分秒 |
|
||||
| D3 | **可选** | 不校验必填;空串 / null → 库 `NULL` |
|
||||
| D4 | **只读空值** | 始终展示该列/字段,空显示为 `—` |
|
||||
| D5 | **三端一致** | backend + web-admin + bx-mobile 同步读写与展示 |
|
||||
| D6 | **不做** | 列表筛选、导出、未来日期限制、主表列、列表卡片摘要 |
|
||||
|
||||
---
|
||||
|
||||
## 一、目标与范围
|
||||
|
||||
### 目标
|
||||
|
||||
每条报销明细可记录可选的费用发生日期,并在申请录入与各只读明细场景一致展示。
|
||||
|
||||
### 范围内
|
||||
|
||||
- 库表 / Model / Schema / API 写入与回读
|
||||
- Web:申请弹窗录入 + 查看弹窗;审批页与 view(mine/todo/all)明细表
|
||||
- Mobile:申请页录入;详情页与审批页明细展示
|
||||
|
||||
### 范围外
|
||||
|
||||
- 列表筛选 / 导出 / 打印
|
||||
- `ApprovalDetailPage`(当前未展示报销明细分列,不改)
|
||||
- 历史数据回填(存量保持 `NULL`)
|
||||
|
||||
---
|
||||
|
||||
## 二、数据模型与 API
|
||||
|
||||
### 2.1 表字段
|
||||
|
||||
`bx_reimburse_detail` 新增:
|
||||
|
||||
| 列名 | 类型 | 可空 | 位置 | 注释 |
|
||||
|------|------|------|------|------|
|
||||
| `occur_date` | `date` | YES | `amount` 之后、`tenant_no` 之前 | 费用发生日期 |
|
||||
|
||||
存量行:`occur_date = NULL`。
|
||||
|
||||
### 2.2 DDL 与快照
|
||||
|
||||
- 迁移脚本:`backend/scripts/migrate_20260817_bx_reimburse_detail_occur_date.sql`
|
||||
- 同步更新:`docs/sql/shanxia2.0.sql` 中 `bx_reimburse_detail` 表定义
|
||||
|
||||
### 2.3 Model / Schema
|
||||
|
||||
- Model:`BxReimburseDetail.occur_date`(nullable Date)
|
||||
- `ReimburseDetailCreate.occur_date: Optional[str] = None`
|
||||
- `ReimburseDetailOut.occur_date: OptDateToStr = None`(序列化为 `YYYY-MM-DD` 或 null)
|
||||
- JSON 驼峰别名:`occurDate`
|
||||
|
||||
### 2.4 写入链路
|
||||
|
||||
1. `api/bx/reimburse.py` → `_build_details_data` 透传 `occur_date`
|
||||
2. `services/bx/reimburse.py` → `create_with_details` / `update_with_details` 写入明细
|
||||
3. 解析:空 → `NULL`;非空按与 `reimburse_date` 同类的日期解析(`YYYY-MM-DD`)
|
||||
4. 出参:`ReimburseDetailOut.model_validate` 自然带出(字段挂在 Model 上即可)
|
||||
|
||||
---
|
||||
|
||||
## 三、前端交互
|
||||
|
||||
### 3.1 列 / 字段顺序
|
||||
|
||||
费用项目 → 金额 → 报销事由 → **发生时间** →(操作列,仅编辑表)
|
||||
|
||||
### 3.2 web-admin
|
||||
|
||||
**录入** — `views/bx/reimburse/apply/index.vue`
|
||||
|
||||
- 明细表新增「发生时间」列(无必填星号)
|
||||
- `el-date-picker`:`type="date"`,`value-format="YYYY-MM-DD"`,可清空
|
||||
- `DetailLine`、提交 payload、编辑回填增加 `occurDate`
|
||||
- 不做必填校验
|
||||
|
||||
**只读**(始终显示列,空为 `—`)
|
||||
|
||||
- 同页查看弹窗明细表
|
||||
- `views/bx/reimburse/approve/index.vue`
|
||||
- `views/bx/view/mine|todo|all/index.vue`
|
||||
|
||||
### 3.3 bx-mobile
|
||||
|
||||
**录入** — `ReimburseApplyPage.vue`:报销事由后增加发生时间日期选择(可清空);提交/回填带 `occurDate`。
|
||||
|
||||
**只读**(始终显示,空为 `—`)
|
||||
|
||||
- `ReimburseDetailPage.vue`
|
||||
- `ReimburseApprovePage.vue`
|
||||
|
||||
---
|
||||
|
||||
## 四、改动文件清单
|
||||
|
||||
| 层 | 文件 |
|
||||
|----|------|
|
||||
| DB | `backend/scripts/migrate_20260817_bx_reimburse_detail_occur_date.sql` |
|
||||
| DB 快照 | `docs/sql/shanxia2.0.sql` |
|
||||
| Model | `backend/app/models/bx_models.py` |
|
||||
| Schema | `backend/app/schemas/bx/reimburse.py` |
|
||||
| API | `backend/app/api/bx/reimburse.py` |
|
||||
| Service | `backend/app/services/bx/reimburse.py` |
|
||||
| Web | `web-admin/src/views/bx/reimburse/apply/index.vue` |
|
||||
| Web | `web-admin/src/views/bx/reimburse/approve/index.vue` |
|
||||
| Web | `web-admin/src/views/bx/view/mine/index.vue` |
|
||||
| Web | `web-admin/src/views/bx/view/todo/index.vue` |
|
||||
| Web | `web-admin/src/views/bx/view/all/index.vue` |
|
||||
| Mobile | `bx-mobile/src/views/reimburse/ReimburseApplyPage.vue` |
|
||||
| Mobile | `bx-mobile/src/views/reimburse/ReimburseDetailPage.vue` |
|
||||
| Mobile | `bx-mobile/src/views/reimburse/ReimburseApprovePage.vue` |
|
||||
|
||||
---
|
||||
|
||||
## 五、验收要点
|
||||
|
||||
1. 新增/编辑:可填、可清空发生时间;不填可保存与提交。
|
||||
2. 各只读明细场景:有值显示 `YYYY-MM-DD`,无值显示 `—`。
|
||||
3. Web 与 bx-mobile 行为一致。
|
||||
4. 旧单据明细为空时展示 `—`,编辑其他字段不受影响。
|
||||
|
||||
## 六、错误处理
|
||||
|
||||
- 非法日期格式:后端解析失败时返回 400(与现有报销日期解析策略一致)。
|
||||
- 前端 date-picker 正常情况下只产出合法 `YYYY-MM-DD` 或空。
|
||||
Reference in new issue
Block a user