ChatBalanceService.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. declare (strict_types = 1);
  3. namespace app\services\chat;
  4. use app\model\api\ChatBalanceLog;
  5. use app\model\api\ChatOrder;
  6. use app\model\api\Sys;
  7. use app\model\api\User;
  8. use app\model\api\UserScoreDetail;
  9. /**
  10. * 聊天次数余额服务
  11. */
  12. class ChatBalanceService
  13. {
  14. /**
  15. * 获取用户聊天次数
  16. * @param int $userId 用户ID
  17. * @return int
  18. */
  19. public static function getBalance(int $userId): int
  20. {
  21. $user = User::find($userId);
  22. return $user ? (int)($user->chat_num ?? 0) : 0;
  23. }
  24. /**
  25. * 增加聊天次数
  26. * @param int $userId 用户ID
  27. * @param int $num 增加数量
  28. * @param int $type 类型
  29. * @param string $remark 备注
  30. * @param int $relateId 关联ID
  31. * @return bool
  32. */
  33. public static function add(int $userId, int $num, int $type, string $remark = '', int $relateId = 0): bool
  34. {
  35. $user = User::find($userId);
  36. if (!$user) {
  37. return false;
  38. }
  39. $newBalance = (int)$user->chat_num + $num;
  40. $user->chat_num = $newBalance;
  41. $result = $user->save();
  42. if ($result) {
  43. ChatBalanceLog::record($userId, $type, $num, $newBalance, $remark, $relateId);
  44. }
  45. return $result;
  46. }
  47. /**
  48. * 减少聊天次数
  49. * @param int $userId 用户ID
  50. * @param int $num 减少数量
  51. * @param int $type 类型
  52. * @param string $remark 备注
  53. * @param int $relateId 关联ID
  54. * @return bool
  55. */
  56. public static function sub(int $userId, int $num, int $type, string $remark = '', int $relateId = 0): bool
  57. {
  58. $currentBalance = self::getBalance($userId);
  59. if ($currentBalance < $num) {
  60. return false;
  61. }
  62. $user = User::find($userId);
  63. if (!$user) {
  64. return false;
  65. }
  66. $newBalance = $currentBalance - $num;
  67. $user->chat_num = $newBalance;
  68. $result = $user->save();
  69. if ($result) {
  70. ChatBalanceLog::record($userId, $type, -$num, $newBalance, $remark, $relateId);
  71. }
  72. return $result;
  73. }
  74. /**
  75. * 扣除积分增加聊天次数(购买流程)
  76. * @param int $userId 用户ID
  77. * @param int $chatNum 购买次数
  78. * @param ChatOrder $order 订单
  79. * @return bool
  80. */
  81. public static function buyWithScore(int $userId, int $chatNum, ChatOrder $order): bool
  82. {
  83. $price = (int)$order->price;
  84. // 检查用户积分是否足够
  85. $userScore = UserScoreDetail::getUserScore($userId);
  86. if ($userScore < $price) {
  87. return false;
  88. }
  89. // 扣除积分
  90. $scoreResult = UserScoreDetail::scoreChange($userId, -$price, '购买聊天次数', $order->id);
  91. if (!$scoreResult) {
  92. return false;
  93. }
  94. // 增加聊天次数
  95. return self::add($userId, $chatNum, ChatBalanceLog::TYPE_BUY, '积分购买聊天次数', $order->id);
  96. }
  97. /**
  98. * 新用户赠送聊天次数
  99. * @param int $userId 用户ID
  100. * @param int $num 赠送次数
  101. * @return bool
  102. */
  103. public static function giftForNewUser(int $userId, int $num): bool
  104. {
  105. return self::add($userId, $num, ChatBalanceLog::TYPE_GIFT, '新用户赠送');
  106. }
  107. /**
  108. * 检查并扣除首次聊天次数
  109. * @param int $userId 用户ID(发起聊天方)
  110. * @param int $toUserId 对方用户ID
  111. * @return array ['success' => bool, 'message' => string]
  112. */
  113. public static function checkAndDeductFirstChat(int $userId, int $toUserId): array
  114. {
  115. // 检查是否已经扣过次数
  116. if (\app\model\api\ChatUserRelation::isDeducted($userId, $toUserId)) {
  117. return ['success' => true, 'message' => '已扣过次数'];
  118. }
  119. // 检查余额是否足够
  120. $balance = self::getBalance($userId);
  121. if ($balance <= 0) {
  122. return ['success' => false, 'message' => '聊天次数不足'];
  123. }
  124. // 扣除次数
  125. $result = self::sub($userId, 1, ChatBalanceLog::TYPE_FIRST_CHAT, '首次与用户' . $toUserId . '聊天', $toUserId);
  126. if ($result) {
  127. // 标记为已扣次数
  128. \app\model\api\ChatUserRelation::markDeducted($userId, $toUserId);
  129. return ['success' => true, 'message' => '扣除成功'];
  130. }
  131. return ['success' => false, 'message' => '扣除失败'];
  132. }
  133. /**
  134. * 获取购买价格
  135. * @return int 单次购买价格(积分)
  136. */
  137. public static function getBuyPrice(): int
  138. {
  139. $sys = Sys::find(1);
  140. return $sys ? (int)($sys->chat_price ?? 0) : 0;
  141. }
  142. }