Files
2026-08-08 18:27:38 +08:00

178 lines
4.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
'is_admin',
'role',
'permissions',
'points',
'real_name',
'phone',
'company',
'industry',
];
protected $hidden = [
'password',
'remember_token',
];
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'is_admin' => 'boolean',
'role' => 'string',
'permissions' => 'array',
'points' => 'integer',
];
}
/**
* 等级阈值(积分下限),键名即等级 L1..L5
*/
public const LEVELS = [
1 => 0,
2 => 50,
3 => 200,
4 => 600,
5 => 1500,
];
public const LEVEL_NAMES = [
1 => '新芯用户',
2 => '活跃用户',
3 => '资深用户',
4 => '核心用户',
5 => '云创芯达人',
];
/**
* 兼容旧逻辑:有后台角色即视为「管理员」(用于前台「后台」入口判断)。
* 新逻辑请使用 role() / canPerm()。
*/
public function isAdmin(): bool
{
return $this->role !== 'user';
}
/**
* 角色等级(1-5),用于层级判断。
*/
public function roleLevel(): int
{
return (int) config("permissions.roles.{$this->role}.level", 1);
}
public function roleLabel(): string
{
return config("permissions.roles.{$this->role}.label", '注册用户');
}
public function isSuperAdmin(): bool
{
return $this->role === 'super_admin';
}
public function isStaff(): bool
{
return $this->role === 'staff';
}
/**
* 细粒度权限判定。
* - 超级管理员:恒 true
* - 内部员工:查 users.permissions(管理员勾选分配)
* - 其他角色:查 config/permissions.php 中该角色的默认权限集
*/
public function canPerm(string $key): bool
{
if ($this->role === 'super_admin') {
return true;
}
if ($this->role === 'staff') {
$perms = is_array($this->permissions) ? $this->permissions : [];
return in_array($key, $perms, true);
}
$def = config("permissions.roles.{$this->role}.permissions", []);
if (in_array('*', $def, true)) {
return true;
}
return in_array($key, $def, true);
}
public function threads()
{
return $this->hasMany(ForumThread::class);
}
public function replies()
{
return $this->hasMany(ForumReply::class);
}
/**
* 增加积分(用于注册、发帖、回帖等动作)。
*/
public function awardPoints(int $amount): void
{
$this->increment('points', max(0, $amount));
}
/**
* 当前等级(1-5)。
*/
public function level(): int
{
$points = $this->points ?? 0;
$level = 1;
foreach (self::LEVELS as $lv => $threshold) {
if ($points >= $threshold) {
$level = $lv;
}
}
return $level;
}
public function levelName(): string
{
return self::LEVEL_NAMES[$this->level()] ?? '用户';
}
/**
* 当前等级进度(用于前台进度条展示)。
*/
public function levelProgress(): array
{
$level = $this->level();
$current = self::LEVELS[$level] ?? 0;
$next = self::LEVELS[$level + 1] ?? null;
if ($next === null) {
return ['level' => $level, 'current' => $this->points, 'next' => null, 'percent' => 100];
}
$span = $next - $current;
$done = $this->points - $current;
$percent = $span > 0 ? (int) min(100, round($done / $span * 100)) : 100;
return ['level' => $level, 'current' => $this->points, 'next' => $next, 'percent' => $percent];
}
}