DiamondRechargeHandler.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. namespace App\Module\OpenAPI\Handlers\Fund;
  3. use App\Module\OpenAPI\Handlers\BaseHandler;
  4. use App\Module\OpenAPI\Services\ScopeService;
  5. use App\Module\OpenAPI\Services\DeveloperAccountService;
  6. use App\Module\OpenAPI\Enums\SCOPE_TYPE;
  7. use App\Module\OpenAPI\Validations\DiamondRechargeValidation;
  8. use App\Module\Fund\Services\FundService;
  9. use App\Module\Fund\Enums\FUND_TYPE;
  10. use App\Module\Fund\Enums\FUND_CURRENCY_TYPE;
  11. use Illuminate\Http\JsonResponse;
  12. use Illuminate\Support\Facades\DB;
  13. use Illuminate\Support\Facades\Log;
  14. /**
  15. * 钻石充值Handler
  16. *
  17. * 处理开发者为用户充值钻石的业务逻辑
  18. * 资金流向:开发者充值账户 -> 用户钻石账户
  19. */
  20. class DiamondRechargeHandler extends BaseHandler
  21. {
  22. public function __construct(ScopeService $scopeService)
  23. {
  24. parent::__construct($scopeService);
  25. }
  26. /**
  27. * 获取所需的权限范围
  28. *
  29. * @return SCOPE_TYPE[]
  30. */
  31. public function getRequiredScopes(): array
  32. {
  33. return [SCOPE_TYPE::FUND_RECHARGE];
  34. }
  35. /**
  36. * 处理钻石充值请求
  37. *
  38. * @param array $data 请求数据
  39. * @param array $context 上下文信息
  40. * @return JsonResponse
  41. */
  42. protected function process(array $data, array $context = []): JsonResponse
  43. {
  44. // 使用验证类进行数据验证
  45. $validation = new DiamondRechargeValidation($data);
  46. $validation->validate();
  47. if ($validation->isFail()) {
  48. return $this->errorResponse('参数验证失败', $validation->getErrors(), 422);
  49. }
  50. // 获取验证后的数据
  51. $safeData = $validation->getSafeData();
  52. $targetUserId = $safeData['user_id'];
  53. $amount = $safeData['amount'];
  54. $remark = $safeData['remark'] ?? '开发者充值钻石';
  55. $orderId = $safeData['order_id'] ?? null;
  56. // 获取应用信息
  57. $app = $this->getApp($context);
  58. if (!$app) {
  59. return $this->errorResponse('无法获取应用信息', null, 400);
  60. }
  61. try {
  62. DB::beginTransaction();
  63. // 检查开发者账户是否存在
  64. $accountCheck = DeveloperAccountService::checkDeveloperAccounts($app);
  65. if (!$accountCheck['recharge_account_exists']) {
  66. // 自动创建开发者账户
  67. $createResult = DeveloperAccountService::createDeveloperAccounts($app);
  68. if (!$createResult['success']) {
  69. DB::rollBack();
  70. return $this->errorResponse('创建开发者账户失败', $createResult['message'], 500);
  71. }
  72. }
  73. // 获取开发者充值账户用户ID
  74. $rechargeUserId = DeveloperAccountService::getRechargeUserId($app->id);
  75. // 检查开发者充值账户余额
  76. $rechargeFundService = new FundService($rechargeUserId, FUND_TYPE::FUND2->value);
  77. $rechargeBalance = $rechargeFundService->balance();
  78. if ($rechargeBalance < $amount) {
  79. DB::rollBack();
  80. return $this->errorResponse('开发者充值账户余额不足', [
  81. 'required' => $amount,
  82. 'available' => $rechargeBalance
  83. ], 400);
  84. }
  85. // 检查目标用户是否存在钻石账户,如果不存在则创建
  86. $targetFundService = new FundService($targetUserId, FUND_TYPE::FUND2->value);
  87. $targetAccount = $targetFundService->getAccount();
  88. if (!$targetAccount) {
  89. // 初始化用户钻石账户
  90. $initResult = $targetFundService->admin(FUND_TYPE::FUND2, 0, 1, '初始化钻石账户');
  91. if (is_string($initResult)) {
  92. DB::rollBack();
  93. return $this->errorResponse('初始化用户账户失败', $initResult, 500);
  94. }
  95. }
  96. // 执行转账:从开发者充值账户转到用户钻石账户
  97. $transferResult = $rechargeFundService->transfer(
  98. $targetUserId,
  99. $amount,
  100. $remark . ($orderId ? " (订单号: {$orderId})" : '')
  101. );
  102. if (is_string($transferResult)) {
  103. DB::rollBack();
  104. return $this->errorResponse('充值转账失败', $transferResult, 500);
  105. }
  106. DB::commit();
  107. // 记录操作日志
  108. $this->logAction('diamond.recharge', [
  109. 'app_id' => $app->id,
  110. 'recharge_user_id' => $rechargeUserId,
  111. 'target_user_id' => $targetUserId,
  112. 'amount' => $amount,
  113. 'order_id' => $orderId,
  114. 'transfer_id' => $transferResult->transferId,
  115. ], $context);
  116. // 获取充值后的账户信息
  117. $rechargeAccountInfo = $rechargeFundService->getAccount();
  118. $targetAccountInfo = $targetFundService->getAccount();
  119. $responseData = [
  120. 'transfer_id' => $transferResult->transferId,
  121. 'order_id' => $orderId,
  122. 'amount' => $amount,
  123. 'currency_type' => FUND_CURRENCY_TYPE::ZUANSHI->value,
  124. 'currency_name' => FUND_CURRENCY_TYPE::ZUANSHI->getCurrencyName(),
  125. 'from_account' => [
  126. 'user_id' => $rechargeUserId,
  127. 'account_type' => '开发者充值账户',
  128. 'balance_after' => $rechargeAccountInfo ? $rechargeAccountInfo->balance : 0,
  129. ],
  130. 'to_account' => [
  131. 'user_id' => $targetUserId,
  132. 'account_type' => '用户钻石账户',
  133. 'balance_after' => $targetAccountInfo ? $targetAccountInfo->balance : 0,
  134. ],
  135. 'remark' => $remark,
  136. 'created_at' => $transferResult->createdAt,
  137. ];
  138. return $this->successResponse('钻石充值成功', $responseData);
  139. } catch (\Exception $e) {
  140. DB::rollBack();
  141. Log::error('钻石充值失败', [
  142. 'app_id' => $app->id,
  143. 'target_user_id' => $targetUserId,
  144. 'amount' => $amount,
  145. 'error' => $e->getMessage(),
  146. 'trace' => $e->getTraceAsString()
  147. ]);
  148. return $this->errorResponse('充值处理失败', $e->getMessage(), 500);
  149. }
  150. }
  151. /**
  152. * 获取开发者账户余额信息
  153. *
  154. * @param array $data 请求数据
  155. * @param array $context 上下文信息
  156. * @return JsonResponse
  157. */
  158. public function getRechargeAccountBalance(array $data, array $context = []): JsonResponse
  159. {
  160. // 获取应用信息
  161. $app = $this->getApp($context);
  162. if (!$app) {
  163. return $this->errorResponse('无法获取应用信息', null, 400);
  164. }
  165. try {
  166. // 获取开发者账户信息
  167. $accountInfo = DeveloperAccountService::getDeveloperAccountInfo($app);
  168. $responseData = [
  169. 'app_id' => $app->id,
  170. 'app_name' => $app->name,
  171. 'recharge_account' => $accountInfo['recharge_account'],
  172. 'currency_type' => FUND_CURRENCY_TYPE::ZUANSHI->value,
  173. 'currency_name' => FUND_CURRENCY_TYPE::ZUANSHI->getCurrencyName(),
  174. 'precision' => FUND_CURRENCY_TYPE::ZUANSHI->getPrecision(),
  175. ];
  176. return $this->successResponse('获取充值账户余额成功', $responseData);
  177. } catch (\Exception $e) {
  178. Log::error('获取充值账户余额失败', [
  179. 'app_id' => $app->id,
  180. 'error' => $e->getMessage(),
  181. ]);
  182. return $this->errorResponse('获取账户信息失败', $e->getMessage(), 500);
  183. }
  184. }
  185. }