PointModel.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. namespace App\Module\Point\Models;
  3. use App\Module\Point\Enums\POINT_TYPE;
  4. use UCore\ModelCore;
  5. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  6. /**
  7. * 用户积分表
  8. *
  9. * 存储用户的各种积分账户信息及积分余额。每个用户可以拥有多个不同种类的积分账户,
  10. * 每个积分账户对应一种积分类型(PointConfigModel)。
  11. * 专注于整数型积分处理,不涉及小数运算。
  12. *
  13. * field start
  14. * @property int $id 自增
  15. * @property int $user_id 用户ID
  16. * @property \App\Module\Point\Enums\POINT_TYPE $point_id 积分类型ID
  17. * @property int $balance 积分余额(整数)
  18. * @property int $update_time 更新时间
  19. * @property int $create_time 创建时间
  20. * field end
  21. */
  22. class PointModel extends ModelCore
  23. {
  24. protected $table = 'point';
  25. public $timestamps = false;
  26. // attrlist start
  27. protected $fillable = [
  28. 'id',
  29. 'user_id',
  30. 'point_id',
  31. 'balance',
  32. 'update_time',
  33. 'create_time',
  34. ];
  35. // attrlist end
  36. protected $casts = [
  37. 'point_id' => POINT_TYPE::class
  38. ];
  39. /**
  40. * 获取用户积分账户
  41. *
  42. * @param int $userId 用户ID
  43. * @param int $pointId 积分类型ID
  44. * @return PointModel|null 积分账户模型
  45. */
  46. public static function getAccount(int $userId, int $pointId): ?PointModel
  47. {
  48. return self::where('user_id', $userId)
  49. ->where('point_id', $pointId)
  50. ->first();
  51. }
  52. /**
  53. * 获取用户所有积分账户
  54. *
  55. * @param int $userId 用户ID
  56. * @return \Illuminate\Database\Eloquent\Collection 积分账户集合
  57. */
  58. public static function userAccount(int $userId)
  59. {
  60. return self::where('user_id', $userId)->get();
  61. }
  62. /**
  63. * 创建或获取用户积分账户
  64. *
  65. * @param int $userId 用户ID
  66. * @param int $pointId 积分类型ID
  67. * @return PointModel 积分账户模型
  68. */
  69. public static function createOrGet(int $userId, int $pointId): PointModel
  70. {
  71. $account = self::getAccount($userId, $pointId);
  72. if (!$account) {
  73. $account = new self();
  74. $account->user_id = $userId;
  75. $account->point_id = $pointId;
  76. $account->balance = 0;
  77. $account->create_time = time();
  78. $account->update_time = time();
  79. $account->save();
  80. }
  81. return $account;
  82. }
  83. /**
  84. * 增加积分
  85. *
  86. * @param int $userId 用户ID
  87. * @param int $pointId 积分类型ID
  88. * @param int $amount 积分数量(正整数)
  89. * @return bool 是否成功
  90. */
  91. public static function inc(int $userId, int $pointId, int $amount): bool
  92. {
  93. if ($amount <= 0) {
  94. return false;
  95. }
  96. $account = self::createOrGet($userId, $pointId);
  97. $account->balance += $amount;
  98. $account->update_time = time();
  99. return $account->save();
  100. }
  101. /**
  102. * 减少积分
  103. *
  104. * @param int $userId 用户ID
  105. * @param int $pointId 积分类型ID
  106. * @param int $amount 积分数量(正整数)
  107. * @return bool|string 成功返回true,失败返回错误信息
  108. */
  109. public static function dec(int $userId, int $pointId, int $amount)
  110. {
  111. if ($amount <= 0) {
  112. return '积分数量必须大于0';
  113. }
  114. $account = self::getAccount($userId, $pointId);
  115. if (!$account) {
  116. return '积分账户不存在';
  117. }
  118. if ($account->balance < $amount) {
  119. return '积分余额不足';
  120. }
  121. $account->balance -= $amount;
  122. $account->update_time = time();
  123. return $account->save();
  124. }
  125. /**
  126. * 获取用户积分余额
  127. *
  128. * @param int $userId 用户ID
  129. * @param int $pointId 积分类型ID
  130. * @return int 积分余额
  131. */
  132. public static function getBalance(int $userId, int $pointId): int
  133. {
  134. $account = self::getAccount($userId, $pointId);
  135. return $account ? $account->balance : 0;
  136. }
  137. /**
  138. * 检查积分余额是否足够
  139. *
  140. * @param int $userId 用户ID
  141. * @param int $pointId 积分类型ID
  142. * @param int $amount 需要的积分数量
  143. * @return bool 是否足够
  144. */
  145. public static function checkBalance(int $userId, int $pointId, int $amount): bool
  146. {
  147. $balance = self::getBalance($userId, $pointId);
  148. return $balance >= $amount;
  149. }
  150. /**
  151. * 设置积分余额
  152. *
  153. * @param int $userId 用户ID
  154. * @param int $pointId 积分类型ID
  155. * @param int $balance 新的积分余额
  156. * @return bool 是否成功
  157. */
  158. public static function setBalance(int $userId, int $pointId, int $balance): bool
  159. {
  160. if ($balance < 0) {
  161. return false;
  162. }
  163. $account = self::createOrGet($userId, $pointId);
  164. $account->balance = $balance;
  165. $account->update_time = time();
  166. return $account->save();
  167. }
  168. /**
  169. * 获取积分类型名称
  170. *
  171. * @return string 积分类型名称
  172. */
  173. public function getPointTypeName(): string
  174. {
  175. return $this->point_id->getTypeName();
  176. }
  177. }