'user']), new OA\Property(property: 'refresh_token_expires_at', type: 'string', format: 'date-time', nullable: true), new OA\Property(property: 'created_at', type: 'string', format: 'date-time'), new OA\Property(property: 'updated_at', type: 'string', format: 'date-time'), ] )] class User extends Model implements Authenticatable { /** * The table associated with the model. */ protected ?string $table = 'users'; /** * The attributes that are mass assignable. */ protected array $fillable = [ 'username', 'password', 'email', 'status', 'role_id', 'api_key_enabled', 'ext', 'refresh_token', 'refresh_token_expires_at', ]; /** * The attributes that should be hidden for serialization. */ protected array $hidden = [ 'password', 'refresh_token', ]; /** * The attributes that should be cast to native types. */ protected array $casts = [ 'id' => 'integer', 'status' => 'integer', 'role_id' => 'integer', 'api_key_enabled' => 'boolean', 'ext' => 'array', 'refresh_token_expires_at' => 'datetime', 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; /** * Get the name of the unique identifier for the user. */ public function getId() { return $this->id; } /** * Retrieve a user by their unique identifier. */ public static function retrieveById($key): ?Authenticatable { return static::query()->find($key); } /** * Set the user's password (auto-hash). */ public function setPasswordAttribute($value): void { $this->attributes['password'] = password_hash($value, PASSWORD_DEFAULT); } /** * Verify the user's password. */ public function verifyPassword(string $password): bool { return password_verify($password, $this->password); } /** * 角色关联 */ public function role(): BelongsTo { return $this->belongsTo(Role::class, 'role_id'); } /** * 用户的 API Keys */ public function apiKeys(): HasMany { return $this->hasMany(ApiKey::class, 'user_id'); } public function isAdministrator(): bool { return $this->role?->name === 'administrator'; } public function isDeveloper(): bool { return $this->role?->name === 'developer'; } public function isAccessor(): bool { return $this->role?->name === 'accessor'; } public function developedPlatforms(): HasMany { return $this->hasMany(Platform::class, 'developer_id'); } /** * 用户的数据访问范围 */ public function dataScopes(): HasMany { return $this->hasMany(UserDataScope::class, 'user_id'); } // @TODO 重新实现删除用户时平台归属转移逻辑(Hyperf 不支持 static::deleting 事件绑定) /** * Check if refresh token is valid. */ public function isRefreshTokenValid(): bool { if (!$this->refresh_token || !$this->refresh_token_expires_at) { return false; } return $this->refresh_token_expires_at->isFuture(); } }