refactor: 更新权限管理与请求验证逻辑
- 在多个控制器中将权限检查从 hasAdminPermission 更新为 hasPermissionCode,以增强权限管理的灵活性。 - 引入 AdminScopePolicy,优化基于代理节点的权限和数据过滤逻辑,确保管理员能够更精确地控制访问权限。 - 在请求验证中添加 agent_node_id 字段,确保 API 接口支持代理节点的相关操作。 - 更新 AdminUser 模型,新增 hasPermissionCode 方法,以支持更细粒度的权限检查。 - 优化审计日志记录逻辑,确保在处理请求时能够准确记录管理员的操作。
This commit is contained in:
@@ -37,7 +37,7 @@ final class LotteryTransferService
|
||||
/** PRD §12:对账后冲正 */
|
||||
private const ST_REVERSED = 'reversed';
|
||||
|
||||
/** PRD §12:对账后人工处理 */
|
||||
/** PRD §12:对账后标记结案(仅改状态,不动钱包) */
|
||||
private const ST_MANUALLY_PROCESSED = 'manually_processed';
|
||||
|
||||
private const BIZ_TRANSFER_IN = 'transfer_in';
|
||||
@@ -326,10 +326,10 @@ final class LotteryTransferService
|
||||
}
|
||||
|
||||
/**
|
||||
* 对账操作:冲正 / 人工处理。
|
||||
* 对账操作:冲正 / 补入账 / 标记结案。
|
||||
*
|
||||
* 冲正(reverse):主站确认未成功,对已扣彩票余额的转出单做反向操作(加回余额),标记为已冲正。
|
||||
* 人工处理(manually_process):管理员确认该订单已通过其它途径解决,仅标记状态,不动钱包。
|
||||
* 标记结案(manually_process):确认已在系统外处理完毕,仅改订单状态,不动钱包。
|
||||
*
|
||||
* @param 'reverse'|'manually_process' $action
|
||||
* @throws WalletOperationException
|
||||
@@ -402,6 +402,30 @@ final class LotteryTransferService
|
||||
deltaSign: 1,
|
||||
);
|
||||
}
|
||||
} elseif ($this->isEligibleForTransferInReverse($locked)) {
|
||||
$player = Player::query()->whereKey($locked->player_id)->firstOrFail();
|
||||
$refund = $this->mainSite->refundMainForFailedLotteryDeposit(
|
||||
$player,
|
||||
(string) $locked->currency_code,
|
||||
(int) $locked->amount,
|
||||
'refund:'.$locked->transfer_no,
|
||||
);
|
||||
|
||||
if (! $refund->ok) {
|
||||
throw new WalletOperationException(
|
||||
$refund->errorMessage ?? 'main_site_refund_failed',
|
||||
$refund->uncertain
|
||||
? ErrorCode::WalletTransferPending->value
|
||||
: ErrorCode::WalletExternalRejected->value,
|
||||
$refund->uncertain ? 409 : 422,
|
||||
);
|
||||
}
|
||||
|
||||
$locked->forceFill([
|
||||
'external_request_payload' => $refund->requestPayload,
|
||||
'external_response_payload' => $refund->responsePayload,
|
||||
'external_ref_no' => $refund->externalRefNo ?? $locked->external_ref_no,
|
||||
])->save();
|
||||
}
|
||||
|
||||
$locked->forceFill([
|
||||
@@ -510,6 +534,14 @@ final class LotteryTransferService
|
||||
);
|
||||
}
|
||||
|
||||
if (! $this->isEligibleForManualProcess($locked)) {
|
||||
throw new WalletOperationException(
|
||||
'manually_process_not_eligible',
|
||||
ErrorCode::WalletExternalRejected->value,
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$locked->forceFill([
|
||||
'status' => self::ST_MANUALLY_PROCESSED,
|
||||
'fail_reason' => 'manually_processed: '.($remark ?: 'admin_manual'),
|
||||
@@ -518,12 +550,32 @@ final class LotteryTransferService
|
||||
}
|
||||
|
||||
/** 仅主站已扣款(有 external_ref_no)且彩票入账失败时可补完成转入。 */
|
||||
private function isEligibleForCompleteCredit(TransferOrder $order): bool
|
||||
public function isEligibleForCompleteCredit(TransferOrder $order): bool
|
||||
{
|
||||
return $order->fail_reason === 'lottery_credit_failed'
|
||||
&& trim((string) $order->external_ref_no) !== '';
|
||||
}
|
||||
|
||||
public function isEligibleForTransferInReverse(TransferOrder $order): bool
|
||||
{
|
||||
return $order->direction === self::DIR_IN
|
||||
&& $order->status === self::ST_PENDING_RECONCILE
|
||||
&& $this->isEligibleForCompleteCredit($order);
|
||||
}
|
||||
|
||||
public function isEligibleForManualProcess(TransferOrder $order): bool
|
||||
{
|
||||
if (! in_array($order->status, [self::ST_PROCESSING, self::ST_FAILED, self::ST_PENDING_RECONCILE], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($order->direction === self::DIR_OUT && $order->status === self::ST_PENDING_RECONCILE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $order->fail_reason !== 'lottery_credit_failed';
|
||||
}
|
||||
|
||||
private function lockLotteryWalletById(int $playerId, string $currencyCode): PlayerWallet
|
||||
{
|
||||
$wallet = PlayerWallet::query()
|
||||
|
||||
Reference in New Issue
Block a user