@@ -0,0 +1,244 @@
# 业务订单详情-修改总金额功能
## 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` 指令控制