Files
chatroom/app/Models/UserPosition.php

134 lines
2.8 KiB
PHP
Raw Normal View History

<?php
/**
* 文件功能:用户职务关联模型(职务履历核心表)
* 对应 user_positions 表,记录用户当前在职职务及全部历史任职记录
* is_active=true 表示当前在职false 为历史存档(永久保留)
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class UserPosition extends Model
{
/**
* 允许批量赋值的字段
*
* @var list<string>
*/
protected $fillable = [
'user_id',
'position_id',
'appointed_by_user_id',
'appointed_at',
'remark',
'revoked_at',
'revoked_by_user_id',
'is_active',
];
/**
* 字段类型转换
*/
public function casts(): array
{
return [
'appointed_at' => 'datetime',
'revoked_at' => 'datetime',
'is_active' => 'boolean',
];
}
/**
* 在职用户
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* 所任职务
*/
public function position(): BelongsTo
{
return $this->belongsTo(Position::class);
}
/**
* 任命人
*/
public function appointedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'appointed_by_user_id');
}
/**
* 撤销人
*/
public function revokedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'revoked_by_user_id');
}
/**
* 该任职期间的登录记录
*/
public function dutyLogs(): HasMany
{
return $this->hasMany(PositionDutyLog::class);
}
/**
* 该任职期间的权限使用记录
*/
public function authorityLogs(): HasMany
{
return $this->hasMany(PositionAuthorityLog::class);
}
/**
* 查询范围:仅当前在职
*/
public function scopeActive(Builder $query): Builder
{
return $query->where('is_active', true);
}
/**
* 获取任职时长(天数);在职则计算至今
*/
public function getDurationDaysAttribute(): int
{
$end = $this->revoked_at ?? now();
return (int) $this->appointed_at->diffInDays($end);
}
/**
* 任职期间累计在线时长(秒)
*/
public function getTotalOnlineSecondsAttribute(): int
{
return (int) $this->dutyLogs()->sum('duration_seconds');
}
/**
* 任职期间累计发放金币总量
*/
public function getTotalRewardedCoinsAttribute(): int
{
return (int) $this->authorityLogs()
->where('action_type', 'reward')
->sum('amount');
}
}