| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <?php
- namespace App\Module\GameItems\Models;
- use Illuminate\Database\Eloquent\Relations\BelongsTo;
- use Illuminate\Database\Eloquent\Relations\HasMany;
- use UCore\ModelCore;
- /**
- * 物品产出限制
- *
- * field start
- * @property int $id 记录ID,主键
- * @property int $item_id 物品ID,外键关联kku_item_items表
- * @property int $limit_type 限制类型(1:全局总量, 2:单个用户, 3:单日全局, 4:单日用户)
- * @property int $max_quantity 最大产出数量
- * @property int $current_quantity 当前已产出数量(全局限制时使用)
- * @property int $reset_type 重置类型(0:不重置, 1:每日, 2:每周, 3:每月)
- * @property string $last_reset_time 上次重置时间
- * @property object|array $related_items 关联物品ID列表,这些物品共享同一个限制额度
- * @property \Carbon\Carbon $created_at 创建时间
- * @property \Carbon\Carbon $updated_at 更新时间
- * field end
- */
- class ItemOutputLimit extends ModelCore
- {
- /**
- * 与模型关联的表名
- *
- * @var string
- */
- protected $table = 'item_output_limits';
- // attrlist start
- protected $fillable = [
- 'id',
- 'item_id',
- 'limit_type',
- 'max_quantity',
- 'current_quantity',
- 'reset_type',
- 'last_reset_time',
- 'related_items',
- ];
- // attrlist end
- /**
- * 应该被转换为日期的属性
- *
- * @var array
- */
- protected $dates = [
- 'reset_time',
- 'created_at',
- 'updated_at',
- ];
- /**
- * 应该被转换为原生类型的属性
- *
- * @var array
- */
- protected $casts = [
- 'max_quantity' => 'integer',
- 'period_type' => 'integer',
- 'period_value' => 'integer',
- 'is_active' => 'boolean',
- ];
- /**
- * 限制类型常量
- */
- const LIMIT_TYPE_GLOBAL = 1; // 全局限制
- const LIMIT_TYPE_USER = 2; // 用户限制
- const LIMIT_TYPE_DAILY = 3; // 每日限制
- const LIMIT_TYPE_WEEKLY = 4; // 每周限制
- const LIMIT_TYPE_MONTHLY = 5; // 每月限制
- /**
- * 获取关联的物品
- *
- * @return BelongsTo
- */
- public function item(): BelongsTo
- {
- return $this->belongsTo(Item::class, 'item_id');
- }
- /**
- * 获取用户产出限制计数
- *
- * @return HasMany
- */
- public function userCounters(): HasMany
- {
- return $this->hasMany(ItemUserOutputCounter::class, 'limit_id');
- }
- /**
- * 检查是否达到全局限制
- *
- * @return bool
- */
- public function isGlobalLimitReached(): bool
- {
- if ($this->limit_type != self::LIMIT_TYPE_GLOBAL) {
- return false;
- }
- $totalCount = ItemUserOutputCounter::where('limit_id', $this->id)
- ->sum('current_count');
- return $totalCount >= $this->max_quantity;
- }
- /**
- * 检查用户是否达到限制
- *
- * @param int $userId 用户ID
- * @return bool
- */
- public function isUserLimitReached(int $userId): bool
- {
- if ($this->limit_type == self::LIMIT_TYPE_GLOBAL) {
- return $this->isGlobalLimitReached();
- }
- $counter = ItemUserOutputCounter::where('limit_id', $this->id)
- ->where('user_id', $userId)
- ->first();
- if (!$counter) {
- return false;
- }
- return $counter->current_count >= $this->max_quantity;
- }
- /**
- * 增加计数
- *
- * @param int $userId 用户ID
- * @param int $count 增加的数量
- * @return bool
- */
- public function incrementCount(int $userId, int $count = 1): bool
- {
- $counter = ItemUserOutputCounter::firstOrCreate(
- [
- 'limit_id' => $this->id,
- 'user_id' => $userId,
- ],
- [
- 'current_count' => 0,
- 'last_reset_time' => now(),
- ]
- );
- // 检查是否需要重置计数
- if ($this->shouldResetCounter($counter)) {
- $counter->current_count = 0;
- $counter->last_reset_time = now();
- }
- $counter->current_count += $count;
- return $counter->save();
- }
- /**
- * 检查是否应该重置计数器
- *
- * @param ItemUserOutputCounter $counter 计数器
- * @return bool
- */
- protected function shouldResetCounter(ItemUserOutputCounter $counter): bool
- {
- if (empty($counter->last_reset_time)) {
- return true;
- }
- switch ($this->limit_type) {
- case self::LIMIT_TYPE_DAILY:
- return $counter->last_reset_time->diffInDays(now()) >= 1;
- case self::LIMIT_TYPE_WEEKLY:
- return $counter->last_reset_time->diffInWeeks(now()) >= 1;
- case self::LIMIT_TYPE_MONTHLY:
- return $counter->last_reset_time->diffInMonths(now()) >= 1;
- default:
- return false;
- }
- }
- }
|