Files
chatroom/app/Models/User.php

204 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 文件功能:主用户模型
*
* 对应原 ASP 文件user 表
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'username',
'password',
'email',
'sex',
'sign',
'user_level',
'inviter_id',
'room_id',
'first_ip',
'previous_ip',
'last_ip',
'usersf',
'vip_level_id',
'hy_time',
'question',
'answer',
'has_received_new_gift',
'in_time', // 进房时间(用于勤务日志 login_at 基准)
'out_time', // 离房时间
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
'temppass',
'ppass',
'userpassword',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'log_time' => 'datetime',
'in_time' => 'datetime',
'out_time' => 'datetime',
'hy_time' => 'datetime',
'xr_time' => 'datetime',
'yx_time' => 'datetime',
'sj' => 'datetime',
'q3_time' => 'datetime',
'has_received_new_gift' => 'boolean',
];
}
/**
* 头像文件名访问器
*
* 原 ASP 系统的头像文件名存储在 usersf 字段中(如 "75.gif"
* 但项目中各处通过 $user->headface 来引用头像。
* 此 accessor 将 headface 属性映射到 usersf 字段,保持代码一致性。
*/
protected function headface(): Attribute
{
return Attribute::make(
// 自动将后缀转小写,兼容数据库中的 .GIF 大写存量
get: fn () => strtolower($this->usersf ?: '1.gif'),
set: fn (string $value) => ['usersf' => strtolower($value)],
);
}
/**
* 关联:用户所属的 VIP 会员等级
*/
public function vipLevel(): BelongsTo
{
return $this->belongsTo(VipLevel::class, 'vip_level_id');
}
/**
* 判断用户是否为有效 VIP有等级且未过期
*/
public function isVip(): bool
{
if (! $this->vip_level_id) {
return false;
}
// hy_time 为 null 表示永久会员
if (! $this->hy_time) {
return true;
}
return $this->hy_time->isFuture();
}
/**
* 获取 VIP 会员名称(无效则返回空字符串)
*/
public function vipName(): string
{
if (! $this->isVip()) {
return '';
}
return $this->vipLevel?->name ?? '';
}
/**
* 获取 VIP 会员图标(无效则返回空字符串)
*/
public function vipIcon(): string
{
if (! $this->isVip()) {
return '';
}
return $this->vipLevel?->icon ?? '';
}
// ── 职务相关关联 ──────────────────────────────────────────────────────
/**
* 全部猎务履历(包括历史记录)
*/
public function positions(): HasMany
{
return $this->hasMany(UserPosition::class)->with(['position.department'])->orderByDesc('appointed_at');
}
/**
* 当前在职职务记录HasOne最多一条
*/
public function activePosition(): HasOne
{
return $this->hasOne(UserPosition::class)->where('is_active', true)->with(['position.department']);
}
/**
* 该用户在职期间的权限操作日志
*/
public function authorityLogs(): HasMany
{
return $this->hasMany(PositionAuthorityLog::class)->orderByDesc('created_at');
}
/**
* 判断用户是否有当前在职职务
*/
public function hasActivePosition(): bool
{
return $this->activePosition()->exists();
}
/**
* 关联:邀请当前用户的人
*/
public function inviter(): BelongsTo
{
return $this->belongsTo(self::class, 'inviter_id');
}
/**
* 关联:当前用户邀请的所有人
*/
public function invitees(): HasMany
{
return $this->hasMany(self::class, 'inviter_id');
}
}