| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- namespace ThirdParty\Urs\Webhook;
- use App\Module\ThirdParty\Models\ThirdPartyService as ServiceModel;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Log;
- /**
- * URS转出 检查Webhook处理器
- *
- * 专门处理余额检查相关的Webhook通知
- */
- class UrsCheckWebhook extends WebhookReceiver
- {
- /**
- * 构造函数
- *
- * @param string $serviceCode 服务代码
- * @param Request $request 请求对象
- * @param ServiceModel $service 服务配置对象
- */
- public function __construct(string $serviceCode, Request $request, ServiceModel $service)
- {
- parent::__construct($serviceCode, $request, $service);
- }
- /**
- * 处理余额检查通知
- *
- * @param string $action 操作类型(固定为check)
- * @param Request $request 请求对象
- * @return array
- * @throws \Exception
- */
- protected function handler(string $action, Request $request): array
- {
- // 验证操作类型
- if ($action !== 'check') {
- throw new \Exception("此处理器只能处理check操作,当前操作: {$action}");
- }
- // 验证必需字段
- $this->validateCheckRequest($request);
- // 处理余额检查通知
- return $this->processCheck($request);
- }
- /**
- * 验证余额检查请求
- *
- * @param Request $request 请求对象
- * @throws \Exception
- */
- protected function validateCheckRequest(Request $request): void
- {
- $requiredFields = [ 'user_id', 'amount' ];
- foreach ($requiredFields as $field) {
- if (!$request->has($field)) {
- throw new \Exception("缺少必需字段: {$field}");
- }
- }
- // 验证用户ID
- $userId = $request->input('user_id');
- if (!is_numeric($userId) || $userId <= 0) {
- throw new \Exception('用户ID格式无效');
- }
- // 验证金额
- $amount = $request->input('amount');
- if (!is_numeric($amount) || $amount < 0) {
- throw new \Exception('提取金额不能为负数');
- }
- }
- /**
- * 处理余额检查的核心逻辑
- *
- * @param Request $request 请求对象
- * @return array
- * @throws \Exception
- */
- protected function processCheck(Request $request): array
- {
- try {
- // 获取请求参数
- $userId = $request->input('user_id');
- $amount = $request->input('amount');
- /**
- * 三方应用ID
- *
- * @var int $thirdPartyAppId
- */
- $thirdPartyAppId = $this->service->id;
- // 1. 根据URS用户ID获取农场用户ID
- $farmUserId = \App\Module\UrsPromotion\Services\UrsUserMappingService::getFarmUserId($userId);
- if (!$farmUserId) {
- Log::warning("URS余额检查失败:未找到用户映射关系", [
- 'urs_user_id' => $userId,
- 'amount' => $amount,
- ]);
- return [
- 'check' => false,
- 'diamond_balance' => '0.0000',
- 'principal_total' => $amount,
- 'fee_total' => '0.0000',
- 'required_total' => $amount,
- 'message' => '用户未进入农场系统'
- ];
- }
- // 2. 获取用户钻石余额
- $userFundService = new \App\Module\Fund\Services\FundService($farmUserId, 2); // 2是钻石的fund_id
- $diamondBalance = $userFundService->balance();
- $diamondBalanceFormatted = number_format($diamondBalance, 4); // 直接格式化,无需转换
- // 3. 特殊处理:如果金额为0,只返回余额信息,不计算手续费
- if (bccomp($amount, '0', 4) === 0) {
- Log::info("URS余额查询(金额为0)", [
- 'urs_user_id' => $userId,
- 'farm_user_id' => $farmUserId,
- 'diamond_balance' => $diamondBalanceFormatted,
- ]);
- return [
- 'check' => true,
- 'diamond_balance' => $diamondBalanceFormatted,
- 'principal_total' => '0.0000',
- 'fee_total' => '0.0000',
- 'required_total' => '0.0000',
- 'message' => '余额查询成功'
- ];
- }
- // 6. 使用TransferThirdPartyService计算提取费用,传递用户ID以便URS推广模块计算正确的手续费率
- $feeDto = \App\Module\Transfer\Services\TransferThirdPartyService::calculateWithdrawFeeWithContext(
- $thirdPartyAppId,
- $amount,
- [ 'user_id' => $farmUserId ] // 传递农场用户ID,让URS推广模块能够根据房屋等级和达人等级计算手续费
- );
- if ($feeDto->hasError) {
- Log::warning("URS余额检查失败:无法计算手续费", [
- 'urs_user_id' => $userId,
- 'farm_user_id' => $farmUserId,
- 'amount' => $amount,
- 'internal_amount' => $feeDto->feeRate,
- 'error' => $feeDto->errorMessage
- ]);
- return [
- 'check' => false,
- 'diamond_balance' => $diamondBalanceFormatted,
- 'principal_total' => $feeDto->actualAmount,
- 'fee_total' => '0.0000',
- 'required_total' => $feeDto->totleAmount,
- 'message' => $feeDto->errorMessage
- ];
- }
- // 6. 检查余额是否足够(直接比较小数值)
- $isAllowed = bccomp($diamondBalance, $feeDto->totleAmount, 10) >= 0;
- Log::info("URS余额检查完成", [
- 'urs_user_id' => $userId,
- 'farm_user_id' => $farmUserId,
- 'amount' => $amount,
- 'diamond_balance' => $diamondBalanceFormatted,
- 'fee_amount' => $feeDto->feeAmount,
- 'required_total' => $feeDto->totleAmount,
- 'is_allowed' => $isAllowed
- ]);
- return [
- 'check' => $isAllowed,
- 'diamond_balance' => $diamondBalanceFormatted,
- 'principal_total' => $feeDto->actualAmount,
- 'fee_total' => $feeDto->feeAmount,
- 'required_total' => $feeDto->totleAmount,
- 'message' => $isAllowed ? '余额充足,允许提取' : '余额不足,无法提取'
- ];
- } catch (\Exception $e) {
- Log::error("URS余额检查处理异常", [
- 'urs_user_id' => $userId ?? 'unknown',
- 'amount' => $amount ?? 'unknown',
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- throw $e;
- }
- }
- }
|