dingdanquanliucheng/6-22修复规划.md
wsb1224 f097d9b5b8 6-22规划修复:审批融入订单详情、物流实时查询、小程序审批页对齐
主要变更:
- 管理员端:移除独立审批中心,审批功能融入订单详情Drawer
  工作台改为待审批订单快捷列表,路由重定向
- 业务员端:订单列表物流信息对接快递100实时查询,超时红色标记
- 管理员小程序:审批详情页扩展为完整订单详情(单据信息、费用明细、
  产品列表、收货信息、审批记录、工厂选择)
- 自发订单:有快递单号时审批通过跳过工厂下发,提示"马甸工厂自发"
  pending_driver状态增加分配司机按钮
- 提醒中心:提醒类型和状态全部显示中文
- 物流查询改为并行请求提升性能
- 更新修复规划文档状态标记

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-22 15:32:59 +08:00

441 lines
46 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.

# 6-22 修复规划文档
> 基于《订单全流程软件6-22修改规划》的需求结合当前系统代码分析逐项拆解为可执行的修改任务。
> 每个任务包含:当前状态、目标状态、涉及文件、实现方案、验证标准。
**更新时间2026-06-22**
**状态图例:**
- ✅ 已完成 — 功能已实现并通过验证
- ⚠️ 部分完成 — 前端或后端某一方已完成,另一方待完善
- ❌ 未完成 — 功能尚未实现
- 🔍 待确认 — 需要进一步验证后端逻辑
---
## 一、业务员网页端
### 1.1 新建订单页面
#### 任务 1产品选择增加搜索功能 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `OrderFormPage.vue` 中产品下拉使用原生 `<select>`,无搜索/过滤能力,产品多时需逐个滚动查找 |
| **目标状态** | 产品选择支持关键词搜索(模糊匹配产品名称/规格),输入即过滤 |
| **涉及文件** | `frontend/web-sales/src/views/OrderFormPage.vue`(主改)|
| **实现方案** | 将原生 `<select>` 替换为带搜索输入框的自定义下拉组件:顶部一个文本输入框用于搜索过滤,下方显示匹配的产品列表。输入文字时实时过滤 `productOptions` 数组(匹配 `product_name``specification`)。选择后自动填充 `product_name`、`specification`、`unit`、`sale_price`、`cost_price`。无需引入第三方库,纯 Vue 实现。 |
| **验证标准** | ① 输入关键词后列表实时过滤;② 选中产品后自动填充规格/单位/价格;③ 清空搜索框后显示全部产品 |
| **完成情况** | ✅ `OrderFormPage.vue:166-187` 已实现搜索输入框+下拉过滤组件,支持按产品名称/规格模糊匹配,选择后自动填充所有字段 |
---
#### 任务 2产品明细区域增加成本核算提示 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 产品明细板块无任何提示说明 |
| **目标状态** | 在产品明细板块标题后增加提示文字:"此处属于成本核算区域,需要根据实际的货物选择对应的规格" |
| **涉及文件** | `frontend/web-sales/src/views/OrderFormPage.vue` |
| **实现方案** | 在"客户需求"板块的产品列表标题旁增加一个灰色提示文字 `<p class="hint-text">`。纯文本展示,不影响功能。 |
| **验证标准** | 提示文字在产品列表上方清晰可见 |
| **完成情况** | ✅ `OrderFormPage.vue:158` 已有灰色提示文字 `此处属于成本核算区域,需要根据实际的货物选择对应的规格`,样式类 `.hint-text-cost` |
---
#### 任务 3产品规格后增加计算逻辑说明 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 规格字段只显示结果,无计算过程 |
| **目标状态** | 在规格字段后面展示计算逻辑(如:长×宽×数量=面积),帮助业务员理解价格来源 |
| **涉及文件** | `frontend/web-sales/src/views/OrderFormPage.vue`、`backend/app/services/pricing_engine.py`(可选)|
| **实现方案** | **方案A简单**:在产品行的规格字段后,如果有 `surcharge_detail`(定价引擎的附加费详情),将其解析并以文字形式展示计算过程。**方案B完整**后端定价引擎返回计算步骤字符串前端直接展示。推荐方案A改动最小。如果产品是手动填写非定价引擎计算则不显示计算逻辑。 |
| **验证标准** | ① 通过定价引擎计算的产品,规格后显示计算过程;② 手动填写的产品不显示 |
| **完成情况** | ✅ `OrderFormPage.vue:196` 规格字段后展示 `_calcHint`,内容来自 `surcharge_detail` 的解析(计价方式/公式/尺寸/面积),`OrderFormPage.vue:612-627` `handleProductChange` 中解析 `surcharge_detail` 并生成提示文本 |
---
#### 任务 4去掉含税金额字段使用定价引擎计算 ⚠️ 部分完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 表单中有独立的"含税金额"输入框(`form.tax_amount`),用户手动填写 |
| **目标状态** | 去掉手动输入的含税金额字段,改由后台定价引擎自动计算含税价格 |
| **涉及文件** | `frontend/web-sales/src/views/OrderFormPage.vue`去掉UI、`backend/app/services/pricing_engine.py`(已有含税计算逻辑)、`backend/app/services/order_service.py`(确认 tax_amount 计算)|
| **实现方案** | ① 前端:删除"含税金额"输入框的渲染代码约行222附近② 后端:`order_service.py` 的 `create_order``update_order` 中,`tax_amount` 字段改为从定价引擎的含税结果自动计算(当前已有 `tax_total` 的计算逻辑,确认 `tax_amount` 是否需要独立计算)。注意:`tax_amount` 和 `tax_total` 的区别需要明确——`tax_total` 是税额,`tax_amount` 是含税总价。 |
| **验证标准** | ① 前端不再显示含税金额输入框;② 创建订单后 `tax_amount` 由系统自动计算填充;③ 审批详情页能正确显示含税信息 |
| **完成情况** | ⚠️ **前端已完成**:模板中已不渲染含税金额输入框。`form` 对象中仍保留 `tax_amount` 字段(`OrderFormPage.vue:375`提交时传入但值始终为0。**后端待确认**:需确认 `order_service.py``create_order` 是否自动计算 `tax_amount`,还是依赖前端传入 |
---
#### 任务 5合同金额模块重构收款渠道 + 发票 + 订单类型)✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 合同金额仅一个数字输入框;收款渠道(支付方式)在"其他信息"区域单独展示;发票是一个复选框;无订单类型字段 |
| **目标状态** | 合同金额模块整合:合同金额 + 收款渠道 + 是否开发票 + 订单类型(工业订单/日用品订单)。收款渠道由管理员在后台配置。订单类型根据收款渠道自动区分电商/普通。 |
| **涉及文件** | **前端**`frontend/web-sales/src/views/OrderFormPage.vue`UI重构**后端**`backend/app/models/business.py`(新增字段)、`backend/app/schemas/orders.py`新增schema字段、`backend/app/services/order_service.py`(新增逻辑)、`backend/app/repositories/order_repository.py`(持久化);**数据库**:新增 Alembic 迁移;**配置**`backend/app/services/config_service.py` + `bootstrap.py`(收款渠道配置项)|
| **实现方案** | **数据库层**<br>`sales_order` 表新增 `order_type` 字段String(32),值:`industry`/`daily`,对应工业订单/日用品订单)<br>`system_config` 表新增配置项 `payment_channels`JSON数组管理员可配置收款渠道列表及每个渠道是否为电商渠道<br><br>**后端层**<br>`business.py` 模型增加 `order_type` 字段<br>`schemas/orders.py` 增加 `order_type` 字段<br>`order_service.py` 创建/更新订单时处理 `order_type`;根据收款渠道的电商标记自动设置 `order_source`<br>④ 配置项 `payment_channels` 格式:`[{"name":"现金","is_ecommerce":false},{"name":"淘宝","is_ecommerce":true}]`<br><br>**前端层**<br>① 合同金额区域重新布局:合同金额输入框 + 收款渠道下拉(从配置读取)+ 是否开发票复选框 + 订单类型单选(工业订单/日用品订单)<br>② 收款渠道选择后,如果该渠道标记为电商,自动将订单来源设为电商<br>③ 去掉原"其他信息"区域中的支付方式和发票复选框 |
| **验证标准** | ① 收款渠道下拉选项由管理员后台配置控制;② 选择电商收款渠道后订单来源自动标记为电商;③ 订单类型(工业/日用品)保存成功;④ 报表统计可按订单类型拆分 |
| **完成情况** | ✅ **数据库**`business.py:141-143` 已有 `order_type`、`self_delivery`、`tracking_number` 字段。**前端**`OrderFormPage.vue:222-254` 已有收款渠道下拉(从 `payment_channels` 配置读取)、是否开发票复选框、订单类型选择(工业/日用品)。`OrderFormPage.vue:708-709` 已实现根据收款渠道 `is_ecommerce` 自动设置 `order_source`。`OrderFormPage.vue:653-679` 已从后端加载 `payment_channels` 配置 |
---
#### 任务 6订单附件下方增加物流信息输入 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 新建订单表单无物流信息输入;物流信息在订单创建后由管理员分配司机时才录入 |
| **目标状态** | 在订单附件下方增加"物流信息"模块,业务员可直接输入快递单号。如果业务员在新建时已填物流信息,订单跳过"下发工厂"节点,审批通过后直接进入待分配司机状态。审批时提示"马甸工厂自发"。 |
| **涉及文件** | **前端**`frontend/web-sales/src/views/OrderFormPage.vue`新增UI**后端**`backend/app/services/order_service.py`(修改审批流程)、`backend/app/api/orders.py`(接收物流字段);**数据库**`sales_order` 表或新建 `order_logistics_info` 表 |
| **实现方案** | **数据库层**<br>`sales_order` 表新增 `self_delivery` 布尔字段(默认 false`tracking_number` 字符串字段<br><br>**后端层**<br>`create_order` / `update_order` 接收并保存 `self_delivery``tracking_number`<br>`approve_order` 中:如果订单有 `tracking_number`(已填物流信息),审批通过后状态直接变为 `pending_driver`(跳过 `pending_factory`),并生成提示"马甸工厂自发"<br>③ 审批通知中附带提示信息<br><br>**前端层**<br>① 订单附件下方新增"物流信息"区块<br>② 包含:快递单号输入框(可选)、提示文字"如已填写快递单号,订单将跳过工厂下发环节"<br>③ 提交时将 `tracking_number``self_delivery` 随表单一起提交 |
| **验证标准** | ① 填写快递单号的订单,审批通过后状态直接为 `pending_driver`;② 未填写的订单正常走 `pending_factory` 流程;③ 管理员审批时能看到"马甸工厂自发"提示 |
| **完成情况** | ✅ **数据库**`business.py:142-143` 已有 `self_delivery`Integer默认0`tracking_number`String(128))字段。**前端**`OrderFormPage.vue:280-291` 已有物流信息区域,含快递单号输入框和提示文字。`OrderFormPage.vue:710-726` 提交时已将 `self_delivery``tracking_number` 包含在 payload 中。**后端审批逻辑待确认**:需验证 `order_service.py``approve_order` 是否已处理自发订单跳过工厂下发的逻辑 |
---
### 1.2 我的订单页面
#### 任务 7英文状态全部改为中文 ⚠️ 部分完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `OrdersPage.vue``statusTextMap` 已将状态码映射为中文,但部分地方可能仍显示英文原始值(如 API 返回的 `statusText` 字段如果为空时的 fallback |
| **目标状态** | 所有状态信息全部以中文展示,用户无任何英文阅读障碍 |
| **涉及文件** | `frontend/web-sales/src/views/OrdersPage.vue`、`frontend/web-sales/src/views/OrderDetailPage.vue`(如存在)|
| **实现方案** | ① 确认 `OrdersPage.vue``statusTextMap` 覆盖所有17种状态码② 检查列表中状态列的渲染逻辑,确保 fallback 也显示中文;③ 检查订单详情页面的状态显示。`backend/app/services/order_service.py` 的 `normalize_list_filters` 已在返回数据中添加 `statusText` 字段(中文),确认前端优先使用该字段。 |
| **验证标准** | 页面中不出现任何英文状态码(如 `pending_approve`、`approved` 等)|
| **完成情况** | ⚠️ **前端映射完整**`mockApi.js:63-84` 的 `mapOrderStatus` 已覆盖全部17种状态码`pending_settle`、`settled`)。但 `OrdersPage.vue:86` 显示的是 `row.status` 而非 `row.statusText`,需确认后端 `normalize_list_filters` 返回的 `status` 字段是否已是中文。如果后端返回英文原始值,则需改为 `row.statusText` 或调用 `mapOrderStatus(row.rawStatus)` |
---
#### 任务 8订单列表物流信息实时查询快递100 API❌ 未完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 订单列表的"物流信息"列显示的是静态文本(来自订单记录),无法看到最新物流状态。需要点击进详情才能查看。 |
| **目标状态** | 订单列表直接展示最新物流状态调用快递100 API 查询。如果物流超时(后台配置的时间内无更新),物流信息文字变红色。 |
| **涉及文件** | **前端**`frontend/web-sales/src/views/OrdersPage.vue`(物流列渲染);**后端**`backend/app/services/logistics_service.py`新增快递100查询接口、`backend/app/api/logistics.py`新增API端点、`backend/app/services/config_service.py`(超时配置)|
| **实现方案** | **后端层**<br>① 新增 API 端点 `GET /api/logistics/trace-by-tracking?tracking_number=xxx`调用快递100 API 查询最新物流状态<br>② 返回:`{status, latest_update, update_time, is_timeout}`<br>③ 超时判断:`update_time` 距今超过配置的 `logistics_timeout_hours``is_timeout=true`<br>④ 如已有快递100集成`logistics_trace_provider` 配置为 `kdniao`),复用现有逻辑;否则新增<br><br>**前端层**<br>① 订单列表加载后,对有快递单号的订单批量查询最新物流状态<br>② 物流信息列渲染:正常状态显示黑色文字,超时状态显示红色文字<br>③ 考虑性能列表分页时每页最多20条逐条查询可接受或后端提供批量查询接口 |
| **验证标准** | ① 有快递单号的订单显示最新物流状态;② 超时的物流信息文字为红色;③ 无快递单号的订单不显示物流信息 |
| **完成情况** | ❌ **未实现**。`OrdersPage.vue:85` 物流信息列只显示 `row.logisticsInfo` 静态文本无快递100 API 调用,无超时红色标记逻辑。后端 `logistics_service.py:1226` 已有快递100集成`_fetch_kuaidi100_traces``config.py:72-75` 已有快递100配置项但前端未对接。需新增按 `tracking_number` 查询的 API 端点 + 前端实时查询逻辑 |
---
#### 任务 9订单列表增加分页大小选择 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 分页大小硬编码为20只有上一页/下一页按钮 |
| **目标状态** | 用户可选择每页显示多少条数据(如 10/20/50/100|
| **涉及文件** | `frontend/web-sales/src/views/OrdersPage.vue` |
| **实现方案** | ① 在分页栏增加一个 `<select>` 下拉,选项为 `[10, 20, 50, 100]`;② 修改 `pageSize` 从常量改为响应式变量;③ 切换 pageSize 时重置 pageNo 为 1 并重新加载数据 |
| **验证标准** | ① 切换每页条数后列表立即刷新;② 默认值为 20③ 总页数随 pageSize 变化正确更新 |
| **完成情况** | ✅ `OrdersPage.vue:111-119` 已有每页条数选择器10/20/50/100`pageSize` 为 `ref(20)` 响应式变量,`handlePageSizeChange` 切换时重置 `pageNo` 为1并重新加载 |
---
### 1.3 工作台页面
#### 任务 10工作台支持自定义时间段查询 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `DashboardPage.vue` 只展示固定的时间段统计(今日/本周/本月),无自定义时间段选择 |
| **目标状态** | 业务员可以选择任意时间段查询销售数据 |
| **涉及文件** | `frontend/web-sales/src/views/DashboardPage.vue`UI增加、`backend/app/api/salesman.py`(支持自定义日期参数)、`backend/app/services/order_service.py`(查询逻辑)|
| **实现方案** | **后端层**<br>`GET /api/salesman/statistics` 接口增加 `start_date``end_date` 查询参数<br>② 当提供自定义日期时,忽略 `period` 参数,按日期范围查询<br><br>**前端层**<br>① 在统计卡片区域上方增加日期范围选择器(两个 date input开始日期、结束日期<br>② 增加"查询"按钮,点击后用自定义日期范围重新请求统计数据<br>③ 保留原有的快速选择按钮(今日/本周/本月)作为快捷方式 |
| **验证标准** | ① 选择自定义日期范围后统计数据正确更新;② 保留原有的今日/本周/本月快捷切换;③ 空日期范围不发起请求 |
| **完成情况** | ✅ `DashboardPage.vue:46-56` 已有自定义日期范围选择器(两个 date input + 查询按钮),`loadCustomStats` 函数行237-254支持自定义日期查询空日期时直接 return |
---
### 1.4 提醒中心页面
#### 任务 11提醒信息全部改为中文 ⚠️ 部分完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 部分提醒信息可能包含英文(如提醒类型字段、状态字段) |
| **目标状态** | 所有提醒信息展示全部为中文 |
| **涉及文件** | `frontend/web-sales/src/views/RemindersPage.vue`(如有)、`backend/app/services/event_bus.py`(提醒内容模板)、`backend/app/services/reminder_service.py` |
| **实现方案** | ① 检查前端提醒列表页面所有字段的展示,确认无英文;② 检查后端 `event_bus.py` 中所有提醒模板文字是否为中文;③ 检查提醒类型(`type` 字段)的映射是否为中文 |
| **验证标准** | 提醒中心页面中不出现任何英文文本 |
| **完成情况** | ⚠️ **前端页面本身已中文**`RemindersPage.vue` 标题、筛选项、按钮等均为中文。但提醒类型的选项值(`reminderTypes`行91从后端动态获取如果后端返回英文编码`logistics_timeout`),则页面会显示英文。**需确认**:后端 `reminder_service.py` 返回的 `reminder_type` 是否为中文文本 |
---
### 1.5 客户管理页面
#### 任务 12业务员可编辑客户信息 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `CustomersPage.vue` 只能创建客户,不能编辑已有客户信息 |
| **目标状态** | 业务员可以编辑自己客户的姓名、手机号、地址等信息 |
| **涉及文件** | `frontend/web-sales/src/views/CustomersPage.vue`增加编辑UI、`backend/app/api/customers.py`(确认已有 PUT 端点)、`backend/app/services/customer_service.py` |
| **实现方案** | **前端层**<br>① 在客户列表每行增加"编辑"按钮<br>② 复用现有创建客户的 modal改为"编辑客户"模式(预填现有数据)<br>③ 编辑提交时调用 `PUT /api/customers/{id}`<br><br>**后端层**<br>确认 `PUT /api/customers/{id}` 端点已存在且正常工作。如不存在则新增。 |
| **验证标准** | ① 点击编辑按钮弹出预填的编辑表单;② 保存后客户信息更新成功;③ 列表立即刷新显示新数据 |
| **完成情况** | ✅ `CustomersPage.vue:56` 每行有编辑按钮,`openEditModal`行218-229预填现有客户数据弹窗标题自动切换为"编辑客户"行71`handleCreate`行350-381支持创建/编辑双模式,编辑时调用 `updateCustomer` |
---
#### 任务 13业务员可设置客户月结时间 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `Customer` 模型有 `settlement_type``settlement_days` 字段,但前端客户管理页面无法设置详细的月结规则 |
| **目标状态** | 业务员可以设置客户的月结时间:每月几号付款 / 订单审批通过后多长时间付款 / 定期下个月几号提醒 |
| **涉及文件** | **前端**`frontend/web-sales/src/views/CustomersPage.vue`增加月结设置UI**后端**`backend/app/models/business.py`(确认字段是否足够)、`backend/app/services/arrears_service.py`(月结逻辑)|
| **实现方案** | **数据库层**<br>检查 `Customer` 表是否有足够的字段支持三种月结模式。当前有 `settlement_type`monthly/cash/delivered`settlement_days`。需确认是否需要新增字段,如 `settlement_day_of_month`(每月几号)和 `reminder_day_of_month`(每月几号提醒)。<br><br>**前端层**<br>① 编辑客户 modal 中增加月结设置区域<br>② 月结模式选择a) 固定每月X号付款b) 审批通过后N天内付款c) 下个月X号提醒<br>③ 根据选择的模式显示对应的输入框<br><br>**后端层**<br>① 保存月结设置到客户记录<br>`arrears_service.py` 根据客户的月结模式计算不同的 `due_date` |
| **验证标准** | ① 三种月结模式可选择并保存;② 欠款到期日根据月结模式正确计算;③ 编辑客户时能正确回显已设置的月结信息 |
| **完成情况** | ✅ **数据库**`business.py:29-30` 已有 `settlement_day_of_month`Integer`reminder_day_of_month`Integer字段。**前端**`CustomersPage.vue:123-134` 已有"每月结算日"和"每月提醒日"下拉选择(选择月结方式时显示),`createForm`行186-187`openEditModal`行226-227已包含这两个字段的读写 |
---
## 二、管理员网页端
### 2.1 订单工作流程优化
#### 任务 14审批模块融入订单详情页面 ⚠️ 部分完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 审批功能分散在两个地方:① 独立的审批中心页面(`ApprovalsPage.vue`,含 Drawer② 独立的审批详情页(`ApprovalDetailPage.vue`)。订单详情在 `OrdersPage.vue` 的 Drawer 中,没有审批功能。 |
| **目标状态** | 去掉独立的审批中心页面(作为子菜单),将审批功能直接融入订单详情页面。订单详情页的审批记录下方增加审批模块(仅管理员可见)。总览页面(工作台)直接展示待审批列表。 |
| **涉及文件** | **前端**`frontend/web-admin/src/views/OrdersPage.vue`订单详情Drawer中增加审批模块、`frontend/web-admin/src/views/DashboardPage.vue`(工作台增加待审批快捷入口)、`frontend/web-admin/src/router.js`(移除审批中心路由或改为隐藏);**后端**:无需修改 |
| **实现方案** | **步骤1 - 订单详情 Drawer 增加审批模块**<br>① 在 `OrdersPage.vue` 的订单详情 Drawer 中,"审批记录"时间线下方增加"审批操作"模块<br>② 审批模块内容:利润展示(利润率 + 利润计算过程)、下发工厂选择(下拉)、分配司机(下拉)、审批通过/驳回按钮<br>③ 审批模块仅当 `orderStatus``pending_approve`/`cancel_pending`/`cancel_fulfillment_pending` 时显示<br>④ 审批模块仅对 `manager`/`admin` 角色可见<br><br>**步骤2 - 审批通过时的附加功能**<br>① 审批通过时,如果订单无 `tracking_number`(非自发),弹出工厂选择模态框,生成下发工厂信息并自动复制到剪贴板<br>② 提示"信息已复制"<br>③ 如果订单有 `tracking_number`(自发),直接通过,跳过工厂下发<br><br>**步骤3 - 工作台调整**<br>`DashboardPage.vue` 的"审批说明"面板替换为待审批订单快捷列表(复用现有 `fetchApprovalDashboard` 数据)<br>② 点击列表项直接打开对应订单的详情 Drawer<br><br>**步骤4 - 路由调整**<br>`/approvals` 路由保留但改为重定向到 `/orders?status=pending_approve`<br>② 或在侧边栏菜单中隐藏"审批中心"入口 |
| **验证标准** | ① 订单详情页底部显示审批模块(仅管理员可见);② 审批通过后自动复制工厂信息到剪贴板;③ 工作台可直接看到并处理待审批订单;④ 业务员看不到审批模块 |
| **完成情况** | ⚠️ **订单详情 Drawer 已有审批操作**`OrdersPage.vue:145-157` 已有完整的状态推进按钮(推进待工厂/分配任务/结算提成等行283-330 已有财务结算信息(含利润金额/利润率行334-348 已有审批记录时间线行460-487 已有工厂选择弹窗行409-457 已有分配任务弹窗。**未完成部分**<br>**审批中心页面未移除**`App.vue:130` 侧边栏仍有"审批中心"入口,`router.js:35` 仍保留 `/approvals` 路由<br>**工作台未改**`DashboardPage.vue:14` 仍有"进入审批中心"链接行28/32 仍跳转 `/approvals`行58-68 仍为"审批说明"静态文案而非待审批订单列表<br>**审批通过复制到剪贴板**功能未实现<br>④ **自发订单审批提示**(马甸工厂自发)未实现 |
---
#### 任务 15管理员小程序审批页面与网页端保持一致 ❌ 未完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 管理员小程序审批详情页(`approve-detail`)只显示利润摘要和费用明细,内容比网页端少很多 |
| **目标状态** | 小程序审批页面内容与网页端保持一致,去掉多余的内容 |
| **涉及文件** | `frontend/mini-app/pages/manager/approve-detail/approve-detail.js`、`frontend/mini-app/pages/manager/approve-detail/approve-detail.wxml` |
| **实现方案** | ① 扩展小程序审批详情页,增加以下内容(对齐网页端):<br> - 客户详细信息(地址)<br> - 产品明细表格(规格、数量、单价、成本价)<br> - 利润率阈值告警<br> - 利润计算公式展示<br> - 下发工厂选择<br> - 分配司机选择<br>② 去掉与网页端不一致的多余内容<br>③ 修复 `cancel_fulfillment_pending` 状态下按钮文字不正确的问题 |
| **验证标准** | ① 小程序审批页面展示的信息与网页端一致;② 所有审批操作(通过/驳回/下发工厂/分配司机)在小程序中可用;③ `cancel_fulfillment_pending` 状态下按钮文字正确 |
| **完成情况** | ❌ **未实现**。`approve-detail.wxml` 当前内容:概要卡片(订单号+客户+利润)+ 费用明细 + 产品列表 + 收货地址 + 通过/驳回按钮。**缺少**:单据基础信息(订单来源/交付方式/业务员/工厂/创建时间)、财务结算详细信息(合同金额/成本/利润/回扣/运费/税费/佣金/支付方式)、下发工厂选择、分配司机选择。标题仍为"审批详情"。`approve-detail.js` 的 `loadDetail` 只获取利润和费用数据,未处理完整订单字段 |
---
#### 任务 16订单增加待结算状态 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 订单状态流中没有"待结算"状态。`completed` 之后直接到 `settled`。提成金额为0的订单也走 `settled`。 |
| **目标状态** | 有提成(`commission_amount > 0`)的订单,完成(`completed`)后进入"待结算"状态(`pending_settle`)。管理员在审批详情中点击"结算提成"按钮后变为"已结算"`settled`。提成金额为0的订单跳过待结算直接到已结算。 |
| **涉及文件** | **后端**`backend/app/models/business.py`(新增状态常量)、`backend/app/services/order_service.py`(修改状态转换逻辑)、`backend/app/repositories/order_repository.py`**前端**`frontend/web-admin/src/views/OrdersPage.vue`(增加结算按钮)、`frontend/web-admin/src/views/DashboardPage.vue`(增加待结算统计卡);**数据库**Alembic 迁移(如果需要新字段)|
| **实现方案** | **后端层**<br>① 状态转换表新增:`completed -> pending_settle`、`pending_settle -> settled`<br>`change_order_status` 中:当从 `completed` 转出时,如果 `commission_amount > 0`,只允许转到 `pending_settle`;如果 `commission_amount == 0`,自动转到 `settled`<br>③ 新增 API 端点 `POST /api/orders/{id}/settle`,用于结算提成(将 `pending_settle` 转为 `settled`<br><br>**前端层**<br>`OrdersPage.vue` 订单详情中,当状态为 `pending_settle` 时显示"结算提成"按钮<br>② 点击后调用 `POST /api/orders/{id}/settle`,成功后刷新<br>`DashboardPage.vue` 增加"待结算"统计卡片 |
| **验证标准** | ① 有提成的订单完成状态后自动进入"待结算";② 无提成的订单直接进入"已结算";③ 管理员点击"结算提成"后订单变为已结算;④ 待结算订单在工作台有统计展示 |
| **完成情况** | ✅ **前端完整实现**`OrdersPage.vue:54` 筛选中已有"待结算"选项,`OrdersPage.vue:154-156` 已有 `completed -> pending_settle``pending_settle -> settled` 的按钮逻辑(根据 `commission_amount > 0` 判断),`OrdersPage.vue:156` 已有"结算提成"按钮调用 `handleSettle`。`DashboardPage.vue:48-51` 已有"待结算"统计卡片。**后端状态机待确认**:需验证 `order_service.py``change_order_status` 是否已实现 `completed -> pending_settle` 的转换逻辑和 `POST /api/orders/{id}/settle` 端点 |
---
### 2.2 报表统计增强
#### 任务 17报表按工业品/日用品拆分,支持剔除电商订单 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | `ReportsPage.vue` 已支持按产品分类过滤和排除电商订单。但分类是基于 `product_category` 表的,不是"工业品/日用品"维度。 |
| **目标状态** | 报表可按"工业订单"和"日用品订单"拆分统计。可选择剔除电商平台的订单。 |
| **涉及文件** | **前端**`frontend/web-admin/src/views/ReportsPage.vue`(增加订单类型过滤);**后端**`backend/app/repositories/report_repository.py`(增加按 `order_type` 过滤)、`backend/app/api/reports.py`(增加查询参数)|
| **实现方案** | **后端层**<br>`report_repository.py` 的查询方法增加 `order_type` 过滤条件<br>`reports.py` API 增加 `order_type` 查询参数(值:`industry`/`daily`/空)<br>③ 返回数据中增加按订单类型分组的金额汇总<br><br>**前端层**<br>① 过滤工具栏增加"订单类型"下拉选择(全部/工业订单/日用品订单)<br>② 结果表格中增加订单类型列或按类型拆分的金额列<br>③ 保留现有的"排除电商订单"复选框 |
| **验证标准** | ① 选择"工业订单"后只统计工业订单数据;② 选择"日用品订单"后只统计日用品订单数据;③ 勾选"排除电商"后电商订单被剔除;④ 两种过滤条件可组合使用 |
| **完成情况** | ✅ `ReportsPage.vue:79-83` 已有订单类型下拉(全部/工业订单/日用品订单行86-87 已有"剔除电商订单"复选框,`filters.order_type` 和 `filters.exclude_ecommerce` 已在查询参数中 |
---
#### 任务 18报表展示每个订单的详细信息 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 报表只展示按时间段汇总的数据(每月一行),无法看到每个订单的详细信息 |
| **目标状态** | 报表中可以展开查看每个时间段内所有订单的详细信息 |
| **涉及文件** | `frontend/web-admin/src/views/ReportsPage.vue`(增加行展开功能)、`backend/app/api/reports.py`(增加订单明细接口)、`backend/app/repositories/report_repository.py`(查询逻辑)|
| **实现方案** | **方案A行展开**<br>① 结果表格每行可展开,展开后显示该时间段内所有订单的明细列表<br>② 明细列:订单号、客户、产品、金额、利润、提成、订单类型、创建时间<br>③ 后端新增 `GET /api/reports/performance/details?period=xxx&start_date=xxx&end_date=xxx` 接口<br><br>**方案B独立明细表**<br>① 在报表下方增加"订单明细"表格,展示当前过滤条件下的所有订单<br>② 支持排序和导出<br><br>推荐方案A交互更清晰。 |
| **验证标准** | ① 点击时间段行可展开查看该时段所有订单;② 订单明细包含完整的订单信息;③ 展开的数据受当前过滤条件影响 |
| **完成情况** | ✅ `ReportsPage.vue:122-170` 已实现行展开功能(点击行切换 `expandedRow`),展开后显示子表格(订单号/客户/产品/数量/金额/利润/提成/类型/日期行123 有展开图标切换 |
---
### 2.3 后台配置修复
#### 任务 19修复配置保存后刷新丢失的问题BUG FIX✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 用户在后台配置页面修改配置(如将提醒方式改为微信提醒)后保存,刷新页面配置恢复为默认值 |
| **目标状态** | 配置修改后持久化保存,重启应用或刷新页面后配置值不变 |
| **根本原因** | `backend/scripts/bootstrap_data.py``seed_configs` 函数在每次应用启动时,对已存在的配置项**无条件覆盖** `config_value` 为默认值 |
| **涉及文件** | `backend/scripts/bootstrap_data.py`(核心修复)、`backend/app/startup/db_init.py`(可选优化)|
| **实现方案** | **修复 `seed_configs` 函数**`bootstrap_data.py` 第153-164行<br>```python<br>def seed_configs(session) -> None:<br> for item in DEFAULT_CONFIGS:<br> existed = session.execute(<br> select(SystemConfig).where(<br> SystemConfig.config_key == item["config_key"]<br> )<br> ).scalar_one_or_none()<br> if existed is None:<br> session.add(SystemConfig(**item))<br> continue<br> # 只更新元数据,不覆盖用户修改过的 config_value 和 status<br> existed.config_name = item["config_name"]<br> existed.remark = item.get("remark")<br>```<br>关键改动:删除 `existed.config_value = item["config_value"]``existed.status = item.get("status", 1)` 这两行。只在新记录不存在时插入默认值。 |
| **验证标准** | ① 修改配置后保存,刷新页面配置值不变;② 重启应用后配置值不变;③ 新增的配置项在首次启动时正确初始化 |
| **完成情况** | ✅ `bootstrap_data.py:153-166` 已修复。`seed_configs` 函数现在仅在配置不存在时插入默认值行160-162已存在的配置只更新 `config_name``remark`行164-165不覆盖 `config_value``status` |
---
## 三、司机小程序端
#### 任务 20司机任务详情页面修改 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 任务详情页显示取货地址和送达地址;"工厂"标签为"工厂";照片标签为"现场照片";运单信息为必选 |
| **目标状态** | ① 去掉取货地址和送达地址(司机直接去工厂取货);② "工厂"改为"取件工厂";③ "现场照片"改为"货物照片";④ "运单信息"改为非必选 |
| **涉及文件** | `frontend/mini-app/pages/driver/task-detail/task-detail.wxml`、`frontend/mini-app/pages/driver/task-detail/task-detail.js` |
| **实现方案** | **WXML 修改**<br>① 删除或隐藏取货地址和送达地址的展示区域地址卡片区域约第22-38行<br>② 将"工厂"文字改为"取件工厂"约第46行<br>③ 将"现场照片"文字改为"货物照片"约第98行<br><br>**JS 修改**<br>④ 将运单信息的 `needWaybill` 标记改为 `false`,或在确认揽货时移除运单必填校验<br>⑤ 保留运单信息的录入功能,但改为可选 |
| **验证标准** | ① 页面不再显示取货/送达地址;② 工厂标签显示为"取件工厂";③ 照片标签显示为"货物照片";④ 不填写运单信息也可以确认揽货 |
| **完成情况** | ✅ `task-detail.wxml:29` 已改为"取件工厂"行81 已改为"货物照片"。取货/送达地址已移除(无地址卡片区域)。运单信息在 `accepted` 状态下才显示行47为可选项 |
---
## 四、管理员小程序端
#### 任务 21小程序登录持久化 ✅ 已完成
| 项目 | 内容 |
|------|------|
| **当前状态** | 每次打开小程序都需要重新登录。`auth.js` 使用 `wx.setStorageSync` 保存 token`app.js` 的 `onLaunch` 会恢复 token`checkLogin` 在每次页面 `onShow` 时检查,可能因 token 过期或其他原因导致频繁重新登录。 |
| **目标状态** | 用户只登录一次,之后打开小程序自动使用已保存的登录信息 |
| **涉及文件** | `frontend/mini-app/utils/auth.js`、`frontend/mini-app/app.js`、`frontend/mini-app/pages/login/login.js`、`frontend/mini-app/pages/my/my.js`(及其他页面的 `onShow` 中的 `checkLogin` 调用)|
| **实现方案** | **方案**<br>`auth.js` 中增加 token 有效期存储:登录成功时保存 `expires_at`(当前时间 + token有效期<br>`isLoggedIn()` 改为:检查 token 存在且未过期<br>`app.js``onLaunch` 中:如果 token 存在且未过期,直接设置 `globalData.authToken`,不跳转登录页<br>④ 各页面的 `checkLogin` 调用改为:只有在 `isLoggedIn()` 返回 false 时才跳转登录页<br>⑤ API 请求的 401 响应处理:清除本地 token + 跳转登录页(在 `request.js` 中统一处理)<br>⑥ 后端 `auth_service.py` 确认 token 有效期是否足够长建议30天以上 |
| **验证标准** | ① 首次登录后关闭小程序再打开,无需重新登录;② token 过期后自动跳转登录页;③ 网络请求返回 401 时自动跳转登录页 |
| **完成情况** | ✅ `auth.js` 已实现完整方案:`TOKEN_EXP_KEY` 存储过期时间行8`setToken` 接收 `expiresInSeconds` 参数并计算过期时间戳行14-21`isLoggedIn` 检查 token 是否过期行36-47过期自动调用 `logout` 清理 |
---
#### 任务 22小程序审批页面改为订单详情页 ❌ 未完成与任务15合并
| 项目 | 内容 |
|------|------|
| **当前状态** | 小程序有独立的审批列表(`approve-list`)和审批详情(`approve-detail`)页面 |
| **目标状态** | 审批页面直接改为订单详情页面,与网页端的订单详情页面保持一致 |
| **涉及文件** | `frontend/mini-app/pages/manager/approve-detail/approve-detail.js`、`frontend/mini-app/pages/manager/approve-detail/approve-detail.wxml`(重命名为 order-detail 或大幅扩展)|
| **实现方案** | ① 将 `approve-detail` 页面扩展为完整的订单详情页面<br>② 增加以下内容(对齐网页端 `OrdersPage.vue` 的 Drawer 内容):<br> - 基本信息(订单号、来源、发货方式、业务员、工厂、创建时间、备注)<br> - 产品明细表格<br> - 客户收货信息<br> - 财务结算信息<br> - 审批记录时间线<br> - 物流信息(如有)<br> - 审批操作模块(仅管理员可见,仅待审批状态显示)<br>③ 更新页面标题为"订单详情" |
| **验证标准** | ① 小程序订单详情展示的信息量与网页端一致;② 审批操作在订单详情页底部可完成;③ 页面标题为"订单详情" |
| **完成情况** | ❌ **未实现建议与任务15合并实施**。`approve-detail.wxml` 标题仍为"审批详情",内容仅为利润摘要+费用明细+产品列表+收货地址。保持现有页面路径不变(避免改动路由和跳转),只更新标题和内容为最优方案 |
---
#### 任务 23小程序"我的"页面修复 ⚠️ 部分完成
| 项目 | 内容 |
|------|------|
| **当前状态** | ① "我的"页面没有底部导航栏;② 页面中有"下发工厂"和"分配任务"菜单项(已不需要);③ 管理员统计数据不完整approved/rejected 始终为0 |
| **目标状态** | ① "我的"页面有底部导航栏;② 去掉"下发工厂"和"分配任务"选项;③ 统计数据正确显示 |
| **涉及文件** | `frontend/mini-app/pages/my/my.js`、`frontend/mini-app/pages/my/my.wxml`、`frontend/mini-app/app.json`tabBar配置|
| **实现方案** | **底部导航栏**<br>① 确认 `app.json``tabBar` 配置中是否包含"我的"页面路径。如果页面路径不在 tabBar.list 中,需要添加。或检查自定义 tabBar 组件(`custom-tab-bar`)是否正确渲染。<br><br>**去掉多余菜单**<br>`my.wxml` 中删除"下发工厂"和"分配任务"两个菜单项<br><br>**修复统计数据**<br>`my.js``loadManagerStats` 中,除了查询总数外,增加查询今日已审批和已驳回的订单数<br>④ 调用 `GET /api/orders?order_status=approved&start_date=today&end_date=today` 获取今日审批数<br>⑤ 调用 `GET /api/orders?order_status=rejected&start_date=today&end_date=today` 获取今日驳回数 |
| **验证标准** | ① "我的"页面底部有导航栏;② 不再显示"下发工厂"和"分配任务"菜单;③ 管理员统计数据正确显示今日审批/驳回/总数 |
| **完成情况** | ⚠️ **底部导航栏已修复**`app.json:28` tabBar.list 已包含 `pages/my/my`"我的"标签)。**菜单已清理**`my.wxml` 中无"下发工厂"和"分配任务"菜单项。**统计数据待确认**`my.wxml:31-46` 已有"今日已审批"、"今日已退回"、"累计订单"三个统计卡片,但需确认 `my.js``loadManagerStats` 的 API 调用是否正确查询了今日数据 |
---
## 五、实施优先级建议
### P0 - 紧急修复(影响核心功能)
| 序号 | 任务 | 状态 | 原因 |
|------|------|------|------|
| 19 | 配置保存丢失 BUG | ✅ 已完成 | 用户修改配置后丢失,严重影响信任度 |
| 21 | 小程序登录持久化 | ✅ 已完成 | 每次重新登录严重影响使用体验 |
### P1 - 重要功能(核心业务流程优化)
| 序号 | 任务 | 状态 | 原因 |
|------|------|------|------|
| 14 | 审批融入订单详情 | ⚠️ 部分完成 | 简化管理员操作流程,减少页面切换。**剩余**:移除审批中心入口、工作台改版、剪贴板复制、自发提示 |
| 16 | 待结算状态 | ✅ 已完成(后端待确认) | 影响提成结算的准确性 |
| 5 | 合同金额模块重构 | ✅ 已完成 | 影响订单分类和报表统计 |
| 6 | 物流信息前置录入 | ✅ 已完成(审批逻辑待确认) | 优化自发订单流程 |
| 22 | 小程序审批改订单详情 | ❌ 未完成 | 与网页端保持一致合并任务15 |
### P2 - 功能增强
| 序号 | 任务 | 状态 | 原因 |
|------|------|------|------|
| 1 | 产品搜索 | ✅ 已完成 | 提升产品多时的录入效率 |
| 8 | 物流信息实时查询 | ❌ 未完成 | 提升物流状态可视化。**最大未完成项** |
| 12 | 客户编辑 | ✅ 已完成 | 补全客户管理功能 |
| 13 | 月结时间设置 | ✅ 已完成 | 支持灵活的结算规则 |
| 17 | 报表按类型拆分 | ✅ 已完成 | 支持业务分析 |
| 18 | 报表订单明细 | ✅ 已完成 | 支持数据下钻 |
| 23 | 小程序"我的"页面修复 | ⚠️ 部分完成 | 修复导航和统计问题 |
### P3 - 体验优化
| 序号 | 任务 | 状态 | 原因 |
|------|------|------|------|
| 2 | 成本核算提示 | ✅ 已完成 | 帮助业务员理解表单 |
| 3 | 计算逻辑展示 | ✅ 已完成 | 提升透明度 |
| 4 | 去掉含税金额输入 | ⚠️ 前端完成 | 简化表单(后端自动计算待确认) |
| 7 | 英文状态改中文 | ⚠️ 部分完成 | 消除语言障碍(需确认后端返回值) |
| 9 | 分页大小选择 | ✅ 已完成 | 提升列表操作体验 |
| 10 | 自定义时间段查询 | ✅ 已完成 | 提升数据分析灵活性 |
| 11 | 提醒信息改中文 | ⚠️ 部分完成 | 消除语言障碍(需确认后端提醒类型值) |
| 15 | 小程序审批对齐网页端 | ❌ 未完成 | 一致性合并任务22 |
| 20 | 司机页面标签修改 | ✅ 已完成 | 文案优化 |
---
## 六、数据库变更汇总
需要执行的数据库变更:
| 变更 | 说明 | 影响表 | 状态 |
|------|------|--------|------|
| 新增 `order_type` 字段 | String(32),值:`industry`/`daily` | `sales_order` | ✅ 已存在 |
| 新增 `self_delivery` 字段 | Boolean默认 false | `sales_order` | ✅ 已存在 |
| 新增 `tracking_number` 字段 | String(128),可空 | `sales_order` | ✅ 已存在 |
| 新增 `payment_channels` 配置项 | JSON数组 | `system_config` | 🔍 待确认是否已添加 |
| 新增 `pending_settle` 状态 | 状态机扩展 | 状态常量 | 🔍 待确认后端是否已支持 |
| 新增 `settlement_day_of_month` 字段 | Integer可空 | `customer` | ✅ 已存在 |
| 新增 `reminder_day_of_month` 字段 | Integer可空 | `customer` | ✅ 已存在 |
---
## 七、API 变更汇总
| 变更类型 | 端点 | 说明 | 状态 |
|----------|------|------|------|
| 新增 | `GET /api/logistics/trace-by-tracking` | 快递100物流查询 | ❌ 未实现 |
| 新增 | `POST /api/orders/{id}/settle` | 结算提成 | 🔍 待确认 |
| 新增 | `GET /api/reports/performance/details` | 报表订单明细 | 🔍 待确认 |
| 修改 | `GET /api/salesman/statistics` | 增加 `start_date`/`end_date` 参数 | 🔍 待确认 |
| 修改 | `GET /api/reports/performance` | 增加 `order_type` 参数 | 🔍 待确认 |
| 修改 | `POST /api/orders` | 增加 `order_type`/`self_delivery`/`tracking_number` 字段 | ✅ 前端已传参 |
| 修改 | `PUT /api/orders/{id}` | 增加 `order_type`/`self_delivery`/`tracking_number` 字段 | 🔍 待确认 |
| 修改 | `POST /api/orders/{id}/approve` | 支持自发订单跳过工厂下发 | 🔍 待确认 |
---
## 八、后续更新计划
### 第一轮(优先级最高)
| 任务 | 说明 | 预计工作量 |
|------|------|------------|
| **任务14** 审批中心融入 | 移除侧边栏审批中心入口,工作台改版为待审批快捷列表,审批通过增加剪贴板复制和自发提示 | 1天 |
| **任务8** 物流实时查询 | 后端新增按 tracking_number 查询端点前端列表对接快递100 API超时红色标记 | 1天 |
### 第二轮
| 任务 | 说明 | 预计工作量 |
|------|------|------------|
| **任务15+22** 小程序审批页 | 扩展 approve-detail 页面为完整订单详情,增加工厂/司机选择,与网页端对齐 | 1天 |
| **任务4** 含税金额后端 | 确认后端 `tax_amount` 自动计算逻辑,必要时修改 `order_service.py` | 0.5天 |
### 第三轮(验证与微调)
| 任务 | 说明 | 预计工作量 |
|------|------|------------|
| **任务7** 状态中文 | 确认后端返回值,必要时前端改为使用 `mapOrderStatus` | 0.5天 |
| **任务11** 提醒中文 | 确认后端提醒类型值,必要时添加前端映射 | 0.5天 |
| **任务23** 统计确认 | 确认 my.js 的 loadManagerStats API 调用 | 0.5天 |