9.1 KiB
9.1 KiB
业务订单详情-修改总金额功能
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)
现有日志记录模式
self::writeLog($orderId, $adminId, $adminInfo, 'action_name', '操作摘要');
日志字段:
prescription_order_id:订单IDadmin_id:操作人IDadmin_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)
功能需求
- 在业务订单详情页面的金额显示卡片内增加"修改金额"按钮
- 点击按钮弹出修改金额对话框,显示当前金额,允许输入新金额
- 已完成(
fulfillment_status = 3)和已取消(fulfillment_status = 4)状态的订单隐藏修改金额按钮 - 修改金额需要权限控制(
v-perms="['tcm.prescriptionOrder/updateAmount']") - 金额校验:
- 必须大于 0
- 保留2位小数
- 最大值无限制
- 修改成功后,在操作日志中记录:
- 操作人姓名
- 原金额
- 新金额
- 操作时间
- 日志格式:
将订单金额从 ¥{原金额} 修改为 ¥{新金额}
- 修改成功后立即刷新订单详情数据,需代收金额自动重新计算
技术需求
- 前端:在金额显示卡片内增加修改按钮和对话框
- 前端:新增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)
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)
public function updateAmount(): PrescriptionOrderValidate
{
return $this->only(['id', 'amount'])
->append('id', 'require|number')
->append('amount', 'require|float|gt:0');
}
逻辑层(PrescriptionOrderLogic.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)
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)
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,成功后刷新详情数据
关键判断逻辑
// 是否可以修改金额
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.vueline 3025
约束
- 日志 action 字段最多32字符
- 日志 summary 字段最多500字符
- 遵循 likeadmin 分层架构:Controller → Logic → Model
- 权限通过菜单节点 +
v-perms指令控制