更新
This commit is contained in:
@@ -799,6 +799,31 @@ class PrescriptionOrderLogic
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 收款关联增删共用订单行锁,失败时连同金额和日志一起回滚。 */
|
||||
private static function mutatePayOrderLinks(int $id, callable $mutation)
|
||||
{
|
||||
self::$error = '';
|
||||
try {
|
||||
return Db::transaction(static function () use ($id, $mutation) {
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->lock(true)->find();
|
||||
if (!$order) {
|
||||
throw new \DomainException('订单不存在');
|
||||
}
|
||||
$result = $mutation();
|
||||
if ($result === false) {
|
||||
throw new \RuntimeException(self::$error ?: '收款关联变更失败');
|
||||
}
|
||||
|
||||
return $result;
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
if (self::$error === '') {
|
||||
self::$error = $e->getMessage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $payOrderIds
|
||||
*/
|
||||
@@ -2729,6 +2754,14 @@ class PrescriptionOrderLogic
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function addPayOrder(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
return self::mutatePayOrderLinks(
|
||||
(int) ($params['id'] ?? 0),
|
||||
static fn () => self::addPayOrderLocked($params, $adminId, $adminInfo)
|
||||
);
|
||||
}
|
||||
|
||||
private static function addPayOrderLocked(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$id = (int) $params['id'];
|
||||
@@ -2833,6 +2866,14 @@ class PrescriptionOrderLogic
|
||||
* @return array<string,mixed>|false
|
||||
*/
|
||||
public static function linkPayOrder(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
return self::mutatePayOrderLinks(
|
||||
(int) ($params['id'] ?? 0),
|
||||
static fn () => self::linkPayOrderLocked($params, $adminId, $adminInfo)
|
||||
);
|
||||
}
|
||||
|
||||
private static function linkPayOrderLocked(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
$id = (int) $params['id'];
|
||||
@@ -2938,6 +2979,88 @@ class PrescriptionOrderLogic
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除单笔收款关联:保留原支付单、总金额与履约/审核状态,同步已付及代收金额。
|
||||
* 普通订单 paid 按剩余有效收款重算;退款订单的 paid 保留退款后的余额口径。
|
||||
*/
|
||||
public static function unlinkPayOrder(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
self::$error = '';
|
||||
// 显式校验独立权限,菜单迁移未执行时也不能绕过鉴权中间件的默认放行逻辑。
|
||||
if ((int) ($adminInfo['root'] ?? 0) !== 1
|
||||
&& !in_array('tcm.prescriptionOrder/unlinkPayOrder', AuthLogic::getAuthByAdminId($adminId), true)) {
|
||||
self::$error = '无权限移除收款关联';
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::mutatePayOrderLinks(
|
||||
(int) ($params['id'] ?? 0),
|
||||
static fn () => self::unlinkPayOrderLocked($params, $adminId, $adminInfo)
|
||||
);
|
||||
}
|
||||
|
||||
private static function unlinkPayOrderLocked(array $params, int $adminId, array $adminInfo)
|
||||
{
|
||||
$id = (int) $params['id'];
|
||||
$payOrderId = (int) ($params['pay_order_id'] ?? 0);
|
||||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||||
if (!self::canAccessOrder($order, $adminId, $adminInfo)) {
|
||||
self::$error = '无权限操作此订单';
|
||||
return false;
|
||||
}
|
||||
if (in_array((int) $order->fulfillment_status, [3, 4], true)) {
|
||||
self::$error = '已完成或已取消的订单不允许移除收款关联';
|
||||
return false;
|
||||
}
|
||||
if (!in_array($payOrderId, self::linkedPayOrderIdList($id), true)) {
|
||||
self::$error = '该收款记录未关联当前订单,请刷新后重试';
|
||||
return false;
|
||||
}
|
||||
$payOrder = Order::where('id', $payOrderId)->whereNull('delete_time')->lock(true)->find();
|
||||
if (!$payOrder || !in_array((int) $payOrder->status, [2, 5], true)) {
|
||||
self::$error = '仅已支付或待审核的收款记录可移除,已退款记录不可移除';
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldPaidCents = (int) round((float) $order->paid * 100);
|
||||
$removedCents = (int) round((float) $payOrder->amount * 100);
|
||||
if ($removedCents < 0) {
|
||||
self::$error = '收款金额异常,请先核对金额';
|
||||
return false;
|
||||
}
|
||||
$deleted = PrescriptionOrderPayOrder::where('prescription_order_id', $id)
|
||||
->where('pay_order_id', $payOrderId)->delete();
|
||||
if ($deleted !== 1) {
|
||||
throw new \RuntimeException('收款关联已变化,请刷新后重试');
|
||||
}
|
||||
$remainingIds = self::linkedPayOrderIdList($id);
|
||||
$remainingPaidCents = $remainingIds === [] ? 0 : (int) round((float) Order::whereIn('id', $remainingIds)
|
||||
->whereNull('delete_time')->whereIn('status', [2, 5])->sum('amount') * 100);
|
||||
$order->linked_pay_order_id = $remainingIds[0] ?? null;
|
||||
// 部分退款可能未拆分收款单金额,不能用剩余收款原额覆盖退款后的 paid 余额。
|
||||
$hasRefund = (float) ($order->refund_amount ?? 0) > 0 || (int) $order->fulfillment_status === 10;
|
||||
$newPaidCents = $hasRefund
|
||||
? min($remainingPaidCents, max(0, $oldPaidCents - $removedCents))
|
||||
: $remainingPaidCents;
|
||||
$order->paid = $newPaidCents / 100;
|
||||
// 与详情的关联已付总额口径一致;订单 amount 不变。
|
||||
$order->agency_collect_amount = round((float) $order->amount - $remainingPaidCents / 100, 2);
|
||||
$order->save();
|
||||
|
||||
self::writeLog($id, $adminId, $adminInfo, 'unlink_pay_order', sprintf(
|
||||
'移除收款关联 #%d(%s,¥%.2f),订单总金额 ¥%.2f 不变;已付金额(paid)¥%.2f → ¥%.2f;原收款记录保留',
|
||||
$payOrderId, (string) $payOrder->order_no, $removedCents / 100,
|
||||
(float) $order->amount, $oldPaidCents / 100, $newPaidCents / 100
|
||||
), true);
|
||||
|
||||
$out = PrescriptionOrder::where('id', $id)->find()->toArray();
|
||||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||||
self::maskRemarkExtraIfNeeded($out, $adminInfo);
|
||||
self::attachLinkedPayOrders($out);
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已发货/已签收订单:不新增/关联支付单,仅提交完单申请并将支付审核置为待审核。
|
||||
*
|
||||
@@ -5484,7 +5607,7 @@ class PrescriptionOrderLogic
|
||||
$log->save();
|
||||
} catch (\Throwable $e) {
|
||||
if ($strict) {
|
||||
throw new \RuntimeException('操作日志写入失败,快递信息未保存', 0, $e);
|
||||
throw new \RuntimeException('操作日志写入失败,变更未保存', 0, $e);
|
||||
}
|
||||
// 非关键日志沿用历史容错行为
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user