User.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. namespace App\Module\Point\Logic;
  3. use App\Module\Point\Enums\LOG_TYPE;
  4. use App\Module\Point\Models\PointLogModel;
  5. use App\Module\Point\Models\PointModel;
  6. /**
  7. * 用户积分操作逻辑类
  8. *
  9. * 处理用户积分的增减操作,专注于整数积分处理
  10. * 包括积分变更和日志记录
  11. */
  12. class User
  13. {
  14. /**
  15. * 处理用户积分操作
  16. *
  17. * @param int $userId 用户ID
  18. * @param int $pointId 积分类型ID
  19. * @param int $amount 积分数量(正数为增加,负数为减少)
  20. * @param LOG_TYPE $logType 日志类型
  21. * @param string $operateId 操作ID
  22. * @param string $remark 备注
  23. * @return bool|string 成功返回true,失败返回错误信息
  24. */
  25. public static function handle(int $userId, int $pointId, int $amount, LOG_TYPE $logType, string $operateId, string $remark)
  26. {
  27. if ($amount == 0) {
  28. return '积分数量不能为0';
  29. }
  30. # 获取当前积分余额
  31. $beforeBalance = PointModel::getBalance($userId, $pointId);
  32. # 计算操作后余额
  33. $laterBalance = $beforeBalance + $amount;
  34. # 检查余额是否足够(减少积分时)
  35. if ($amount < 0 && $beforeBalance < abs($amount)) {
  36. return '积分余额不足';
  37. }
  38. # 检查操作后余额不能为负数
  39. if ($laterBalance < 0) {
  40. return '操作后积分余额不能为负数';
  41. }
  42. # 执行积分变更
  43. if ($amount > 0) {
  44. # 增加积分
  45. $result = PointModel::inc($userId, $pointId, $amount);
  46. } else {
  47. # 减少积分
  48. $result = PointModel::dec($userId, $pointId, abs($amount));
  49. }
  50. if ($result !== true) {
  51. return is_string($result) ? $result : '积分操作失败';
  52. }
  53. # 记录日志
  54. $logResult = PointLogModel::createLog(
  55. $userId,
  56. $pointId,
  57. $amount,
  58. $logType,
  59. $operateId,
  60. $remark,
  61. $beforeBalance,
  62. $laterBalance
  63. );
  64. if (!$logResult) {
  65. return '积分日志记录失败';
  66. }
  67. return true;
  68. }
  69. /**
  70. * 批量处理用户积分操作
  71. *
  72. * @param array $operations 操作数组,每个元素包含用户ID、积分类型ID、数量等信息
  73. * @param LOG_TYPE $logType 日志类型
  74. * @param string $operateId 操作ID
  75. * @param string $remark 备注
  76. * @return array 处理结果数组
  77. */
  78. public static function batchHandle(array $operations, LOG_TYPE $logType, string $operateId, string $remark): array
  79. {
  80. $results = [];
  81. foreach ($operations as $index => $operation) {
  82. if (!isset($operation['user_id'], $operation['point_id'], $operation['amount'])) {
  83. $results[$index] = '操作参数不完整';
  84. continue;
  85. }
  86. $result = self::handle(
  87. $operation['user_id'],
  88. $operation['point_id'],
  89. $operation['amount'],
  90. $logType,
  91. $operateId,
  92. $remark
  93. );
  94. $results[$index] = $result;
  95. }
  96. return $results;
  97. }
  98. /**
  99. * 检查用户积分余额
  100. *
  101. * @param int $userId 用户ID
  102. * @param int $pointId 积分类型ID
  103. * @param int $amount 需要检查的积分数量
  104. * @return bool|string 余额足够返回true,不足返回错误信息
  105. */
  106. public static function checkBalance(int $userId, int $pointId, int $amount): bool|string
  107. {
  108. if ($amount <= 0) {
  109. return '检查数量必须大于0';
  110. }
  111. $balance = PointModel::getBalance($userId, $pointId);
  112. if ($balance < $amount) {
  113. return "积分余额不足,当前余额:{$balance},需要:{$amount}";
  114. }
  115. return true;
  116. }
  117. /**
  118. * 获取用户积分账户信息
  119. *
  120. * @param int $userId 用户ID
  121. * @param int|null $pointId 积分类型ID(可选,为空则获取所有)
  122. * @return array 积分账户信息数组
  123. */
  124. public static function getAccountInfo(int $userId, ?int $pointId = null): array
  125. {
  126. if ($pointId !== null) {
  127. $account = PointModel::getAccount($userId, $pointId);
  128. return $account ? [
  129. 'user_id' => $account->user_id,
  130. 'point_id' => $account->point_id,
  131. 'balance' => $account->balance,
  132. 'create_time' => $account->create_time,
  133. 'update_time' => $account->update_time,
  134. ] : [];
  135. }
  136. $accounts = PointModel::userAccount($userId);
  137. $result = [];
  138. foreach ($accounts as $account) {
  139. $result[] = [
  140. 'user_id' => $account->user_id,
  141. 'point_id' => $account->point_id,
  142. 'balance' => $account->balance,
  143. 'create_time' => $account->create_time,
  144. 'update_time' => $account->update_time,
  145. ];
  146. }
  147. return $result;
  148. }
  149. /**
  150. * 冻结用户积分
  151. *
  152. * @param int $userId 用户ID
  153. * @param int $pointId 积分类型ID
  154. * @param int $amount 冻结积分数量
  155. * @param string $operateId 操作ID
  156. * @param string $remark 备注
  157. * @return bool|string 成功返回true,失败返回错误信息
  158. */
  159. public static function freeze(int $userId, int $pointId, int $amount, string $operateId, string $remark)
  160. {
  161. return self::handle($userId, $pointId, -$amount, LOG_TYPE::FREEZE, $operateId, $remark);
  162. }
  163. /**
  164. * 解冻用户积分
  165. *
  166. * @param int $userId 用户ID
  167. * @param int $pointId 积分类型ID
  168. * @param int $amount 解冻积分数量
  169. * @param string $operateId 操作ID
  170. * @param string $remark 备注
  171. * @return bool|string 成功返回true,失败返回错误信息
  172. */
  173. public static function unfreeze(int $userId, int $pointId, int $amount, string $operateId, string $remark)
  174. {
  175. return self::handle($userId, $pointId, $amount, LOG_TYPE::UNFREEZE, $operateId, $remark);
  176. }
  177. /**
  178. * 退还用户积分
  179. *
  180. * @param int $userId 用户ID
  181. * @param int $pointId 积分类型ID
  182. * @param int $amount 退还积分数量
  183. * @param string $operateId 操作ID
  184. * @param string $remark 备注
  185. * @return bool|string 成功返回true,失败返回错误信息
  186. */
  187. public static function refund(int $userId, int $pointId, int $amount, string $operateId, string $remark)
  188. {
  189. return self::handle($userId, $pointId, $amount, LOG_TYPE::REFUND, $operateId, $remark);
  190. }
  191. /**
  192. * 扣除用户积分
  193. *
  194. * @param int $userId 用户ID
  195. * @param int $pointId 积分类型ID
  196. * @param int $amount 扣除积分数量
  197. * @param string $operateId 操作ID
  198. * @param string $remark 备注
  199. * @return bool|string 成功返回true,失败返回错误信息
  200. */
  201. public static function deduct(int $userId, int $pointId, int $amount, string $operateId, string $remark)
  202. {
  203. return self::handle($userId, $pointId, -$amount, LOG_TYPE::DEDUCT, $operateId, $remark);
  204. }
  205. }