Files
chatroom/app/Models/UserPosition.php
lkddi 5f30220609 feat: 任命/撤销通知系统 + 用户名片UI优化
- 任命/撤销事件增加 type 字段区分类型
- 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息
- 撤销:灰色弹窗 + 灰色系统消息,无礼花
- 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏
- 系统消息加随机鼓励语(各5条轮换)
- ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds)
- 用户名片折叠优化:管理员视野、职务履历均可折叠
- 管理操作 + 职务操作合并为「🔧 管理操作」折叠区
- 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
2026-02-28 23:44:38 +08:00

134 lines
2.8 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
/**
* 文件功能:用户职务关联模型(职务履历核心表)
* 对应 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');
}
}