# 业务订单详情-修改总金额功能 ## Goal 在业务订单详情页面(`admin/src/views/consumer/prescription/order_list.vue`)增加修改总金额的功能,支持权限控制,并在操作日志中记录修改历史。已完成状态的订单不允许修改金额。 ## What I already know ### 前端架构 - 详情页面:`admin/src/views/consumer/prescription/order_list.vue`(60k+ tokens,包含详情抽屉) - API文件:`admin/src/api/tcm.ts`(已有 `prescriptionOrderDetail`、`prescriptionOrderEdit`、`prescriptionOrderLogs` 等接口) - 订单状态枚举: - `fulfillment_status = 3`:已完成 - 已完成/已取消订单不可编辑(line 3025) - 操作日志展示:详情抽屉中已有操作日志时间线(line 1192-1218) ### 后端架构 - 控制器:`server/app/adminapi/controller/tcm/PrescriptionOrderController.php` - 逻辑层:`server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php` - 模型:`server/app/common/model/tcm/PrescriptionOrder.php` - 日志模型:`server/app/common/model/tcm/PrescriptionOrderLog.php` - 日志写入方法:`PrescriptionOrderLogic::writeLog()` (line 2638-2658) - 日志读取方法:`PrescriptionOrderLogic::getLogs()` (line 1913) ### 现有日志记录模式 ```php self::writeLog($orderId, $adminId, $adminInfo, 'action_name', '操作摘要'); ``` 日志字段: - `prescription_order_id`:订单ID - `admin_id`:操作人ID - `admin_name`:操作人姓名 - `action`:操作类型(最多32字符) - `summary`:操作摘要(最多500字符) - `create_time`:创建时间 ## Confirmed Facts - ✅ 总金额字段:`amount` (decimal(10,2), NOT NULL, DEFAULT '0.00', COMMENT '业务订单金额') - ✅ 状态限制:已完成(`fulfillment_status = 3`)和已取消(`fulfillment_status = 4`)都不允许修改金额 - ✅ 权限控制:新增独立菜单权限节点 `tcm.prescriptionOrder/updateAmount` - ✅ 金额校验规则: - 最小值:必须大于 0(不能为0或负数) - 最大值:无限制 - 精度:保留2位小数 - ✅ 需代收金额:前端计算属性自动计算(`amount - linked_pay_paid_total`),无需后端处理 - ✅ 按钮位置:放在金额显示区域旁边(在显示总金额的卡片内) ## Requirements (final) ### 功能需求 1. 在业务订单详情页面的金额显示卡片内增加"修改金额"按钮 2. 点击按钮弹出修改金额对话框,显示当前金额,允许输入新金额 3. 已完成(`fulfillment_status = 3`)和已取消(`fulfillment_status = 4`)状态的订单隐藏修改金额按钮 4. 修改金额需要权限控制(`v-perms="['tcm.prescriptionOrder/updateAmount']"`) 5. 金额校验: - 必须大于 0 - 保留2位小数 - 最大值无限制 6. 修改成功后,在操作日志中记录: - 操作人姓名 - 原金额 - 新金额 - 操作时间 - 日志格式:`将订单金额从 ¥{原金额} 修改为 ¥{新金额}` 7. 修改成功后立即刷新订单详情数据,需代收金额自动重新计算 ### 技术需求 - 前端:在金额显示卡片内增加修改按钮和对话框 - 前端:新增API接口 `prescriptionOrderUpdateAmount(params: { id: number; amount: number })` - 后端:新增控制器方法 `PrescriptionOrderController::updateAmount()` - 后端:新增验证规则 `PrescriptionOrderValidate::updateAmount` - 后端:新增逻辑层方法 `PrescriptionOrderLogic::updateAmount()` - 后端:记录操作日志(action: `update_amount`) - SQL:新增菜单权限记录(`server/sql/1.9.20260508/add_update_amount_menu.sql`) ## Acceptance Criteria (final) - [ ] 已完成和已取消状态的订单不显示"修改金额"按钮 - [ ] 无权限的管理员不显示"修改金额"按钮 - [ ] 修改金额对话框正确显示当前金额 - [ ] 输入金额 ≤ 0 时提示错误 - [ ] 输入金额精度超过2位小数时自动截断或提示 - [ ] 提交成功后,订单 `amount` 字段更新为新金额 - [ ] 操作日志中正确记录:`{操作人} 将订单金额从 ¥{原金额} 修改为 ¥{新金额}` - [ ] 修改后详情页面数据自动刷新,需代收金额正确显示 - [ ] 后端返回错误时前端正确提示 ## Definition of Done - 前后端代码实现完成 - 新增菜单权限SQL脚本 - 金额修改功能测试通过(正常流程、权限控制、状态限制) - 操作日志记录正确 - 代码通过 lint/typecheck - 无 console.log 残留 ## Out of Scope (explicit) - 批量修改金额 - 修改金额审批流程 - 金额修改历史版本对比 - 修改其他订单字段(如运费、优惠等) ## Technical Approach ### 实现流程 #### 1. 后端实现(优先) **SQL 菜单权限**(`server/sql/1.9.20260508/add_update_amount_menu.sql`) ```sql INSERT INTO `zyt_system_menu` (`pid`, `type`, `name`, `icon`, `sort`, `perms`, `paths`, `component`, `selected`, `params`, `is_cache`, `is_show`, `is_disable`) VALUES (处方订单菜单ID, 'A', '修改订单金额', '', 0, 'tcm.prescriptionOrder/updateAmount', '', '', '', '', 0, 0, 0); ``` **验证规则**(`PrescriptionOrderValidate.php`) ```php public function updateAmount(): PrescriptionOrderValidate { return $this->only(['id', 'amount']) ->append('id', 'require|number') ->append('amount', 'require|float|gt:0'); } ``` **逻辑层**(`PrescriptionOrderLogic.php`) ```php public static function updateAmount(array $params, int $adminId, array $adminInfo): bool { $id = (int) $params['id']; $newAmount = round((float) $params['amount'], 2); // 权限检查 $order = PrescriptionOrder::find($id); if (!$order) { self::setError('订单不存在'); return false; } // 状态检查:已完成(3)和已取消(4)不允许修改 if (in_array($order->fulfillment_status, [3, 4], true)) { self::setError('已完成或已取消的订单不允许修改金额'); return false; } $oldAmount = round((float) $order->amount, 2); // 更新金额 $order->amount = $newAmount; $order->save(); // 记录日志 $summary = sprintf('将订单金额从 ¥%.2f 修改为 ¥%.2f', $oldAmount, $newAmount); self::writeLog($id, $adminId, $adminInfo, 'update_amount', $summary); return true; } ``` **控制器**(`PrescriptionOrderController.php`) ```php public function updateAmount() { $params = (new PrescriptionOrderValidate())->post()->goCheck('updateAmount'); $result = PrescriptionOrderLogic::updateAmount($params, $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('修改成功'); } ``` #### 2. 前端实现 **API 接口**(`admin/src/api/tcm.ts`) ```typescript export function prescriptionOrderUpdateAmount(params: { id: number; amount: number }) { return request.post({ url: '/tcm.prescriptionOrder/updateAmount', params }) } ``` **页面实现**(`admin/src/views/consumer/prescription/order_list.vue`) - 在金额显示卡片内增加"修改金额"按钮(带权限和状态判断) - 新增修改金额对话框(el-dialog + el-input-number) - 提交后调用 API,成功后刷新详情数据 ### 关键判断逻辑 ```typescript // 是否可以修改金额 const canUpdateAmount = (row: any) => { // 已完成(3)或已取消(4)不允许修改 return row.fulfillment_status !== 3 && row.fulfillment_status !== 4 } ``` ## Implementation Plan ### PR1: 后端实现(优先) - [ ] 创建 SQL 菜单权限文件 - [ ] 添加验证规则 `updateAmount` - [ ] 实现逻辑层方法 `PrescriptionOrderLogic::updateAmount()` - [ ] 实现控制器方法 `PrescriptionOrderController::updateAmount()` - [ ] 测试后端接口(Postman/curl) ### PR2: 前端实现 - [ ] 添加 API 接口 `prescriptionOrderUpdateAmount` - [ ] 在金额卡片内添加"修改金额"按钮(带权限和状态判断) - [ ] 实现修改金额对话框 - [ ] 实现提交逻辑和数据刷新 - [ ] 测试完整流程(权限、状态、校验、日志) ### PR3: 测试和优化 - [ ] 测试各种边界情况(0、负数、超大金额、精度) - [ ] 测试权限控制 - [ ] 测试状态限制 - [ ] 验证操作日志记录 - [ ] 代码 lint/typecheck - [ ] 清理 console.log ## Technical Notes ### 文件清单 - 前端页面:`admin/src/views/consumer/prescription/order_list.vue` - 前端API:`admin/src/api/tcm.ts` - 后端控制器:`server/app/adminapi/controller/tcm/PrescriptionOrderController.php` - 后端逻辑:`server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php` - 后端验证:`server/app/adminapi/validate/tcm/PrescriptionOrderValidate.php` - SQL脚本:`server/sql/1.9.20260508/add_update_amount_menu.sql`(待创建) ### 参考实现 - 操作日志写入:`PrescriptionOrderLogic::writeLog()` (line 2638) - 操作日志读取:`PrescriptionOrderLogic::getLogs()` (line 1913) - 状态判断逻辑:`order_list.vue` line 3025 ### 约束 - 日志 action 字段最多32字符 - 日志 summary 字段最多500字符 - 遵循 likeadmin 分层架构:Controller → Logic → Model - 权限通过菜单节点 + `v-perms` 指令控制