feat: 增加自定义头像上传、自动压缩与自动清理功能,统一全站头像路径读取逻辑

This commit is contained in:
2026-03-12 15:26:54 +08:00
parent ec95d69e92
commit 78564e2a1d
57 changed files with 569 additions and 350 deletions
+6 -6
View File
@@ -42,11 +42,11 @@ class FishingEvent extends Model
protected function casts(): array
{
return [
'exp' => 'integer',
'jjb' => 'integer',
'weight' => 'integer',
'exp' => 'integer',
'jjb' => 'integer',
'weight' => 'integer',
'is_active' => 'boolean',
'sort' => 'integer',
'sort' => 'integer',
];
}
@@ -73,8 +73,8 @@ class FishingEvent extends Model
// 计算总权重后加权随机
$totalWeight = $events->sum('weight');
$roll = random_int(1, max($totalWeight, 1));
$cumulative = 0;
$roll = random_int(1, max($totalWeight, 1));
$cumulative = 0;
foreach ($events as $event) {
$cumulative += $event->weight;
+7 -6
View File
@@ -7,6 +7,7 @@
* 对应表:mystery_boxes
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
@@ -81,9 +82,9 @@ class MysteryBox extends Model
{
return match ($this->box_type) {
'normal' => '📦',
'rare' => '💎',
'trap' => '☠️',
default => '📦',
'rare' => '💎',
'trap' => '☠️',
default => '📦',
};
}
@@ -94,9 +95,9 @@ class MysteryBox extends Model
{
return match ($this->box_type) {
'normal' => '普通箱',
'rare' => '稀有箱',
'trap' => '黑化箱',
default => '神秘箱',
'rare' => '稀有箱',
'trap' => '黑化箱',
default => '神秘箱',
};
}
+1
View File
@@ -7,6 +7,7 @@
* 对应表:mystery_box_claims
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
+1
View File
@@ -7,6 +7,7 @@
* envelope_id + user_id 联合唯一约束保证幂等性。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
+1
View File
@@ -7,6 +7,7 @@
* 先到先得,领完或超时后自动关闭。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
+5 -6
View File
@@ -5,8 +5,8 @@
* 对应原版 ASP 聊天室的 sysparam 配置表
* 管理员可在后台修改等级经验阈值等系统参数
*
* @package App\Models
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
@@ -27,9 +27,8 @@ class Sysparam extends Model
* 获取指定参数的值
* 带缓存,避免频繁查库
*
* @param string $alias 参数别名
* @param string $default 默认值
* @return string
* @param string $alias 参数别名
* @param string $default 默认值
*/
public static function getValue(string $alias, string $default = ''): string
{
@@ -56,7 +55,7 @@ class Sysparam extends Model
/**
* 根据经验值计算应该达到的等级
*
* @param int $expNum 当前经验值
* @param int $expNum 当前经验值
* @return int 对应的等级
*/
public static function calculateLevel(int $expNum): int
@@ -81,7 +80,7 @@ class Sysparam extends Model
/**
* 清除指定参数的缓存
*
* @param string $alias 参数别名
* @param string $alias 参数别名
*/
public static function clearCache(string $alias): void
{
+48 -5
View File
@@ -90,18 +90,61 @@ class User extends Authenticatable
* 头像文件名访问器
*
* ASP 系统的头像文件名存储在 usersf 字段中(如 "75.gif"),
* 但项目中各处通过 $user->headface 来引用头像
* accessor headface 属性映射到 usersf 字段,保持代码一致性
* 同时也支持用户自定义上传的头像,保存在 Laravel Storage public 磁盘下
* accessor headface 属性映射到 usersf 字段,如果包含 storage/ 则当作独立路径,自动转换旧版后缀小写
*/
protected function headface(): Attribute
{
return Attribute::make(
// 自动将后缀转小写,兼容数据库中的 .GIF 大写存量
get: fn () => strtolower($this->usersf ?: '1.gif'),
set: fn (string $value) => ['usersf' => strtolower($value)],
get: function () {
$val = $this->usersf ?: '1.gif';
if (str_starts_with($val, 'storage/')) {
return $val;
}
// 仅对非 storage 下的旧头像做小写处理,兼容旧库数据
return strtolower($val);
},
set: function ($value) {
if (str_starts_with($value, 'storage/')) {
return tap($value, fn () => $this->attributes['usersf'] = $value);
}
return tap(strtolower($value), fn () => $this->attributes['usersf'] = strtolower($value));
}
);
}
/**
* 获取带前缀的完整头像 URL
* 避免前端多处硬编码 '/images/headface/'
*/
protected function headfaceUrl(): Attribute
{
return Attribute::make(
get: function () {
$hf = $this->headface;
if (str_starts_with((string) $hf, 'storage/')) {
return '/'.$hf;
}
return '/images/headface/'.$hf;
}
);
}
/**
* 如果当前头像是自定义上传的图片,则从本地存储中删除此文件
*/
public function deleteCustomAvatar(): void
{
$hf = (string) $this->usersf;
if (str_starts_with($hf, 'storage/')) {
$path = substr($hf, 8); // 去除 'storage/' 前缀
\Illuminate\Support\Facades\Storage::disk('public')->delete($path);
}
}
/**
* 关联:用户所属的 VIP 会员等级
*/
+5 -4
View File
@@ -6,6 +6,7 @@
* 只读写,不允许 update(流水记录不可更改)
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
@@ -40,10 +41,10 @@ class UserCurrencyLog extends Model
* 字段类型转换
*/
protected $casts = [
'amount' => 'integer',
'balance_after'=> 'integer',
'room_id' => 'integer',
'created_at' => 'datetime',
'amount' => 'integer',
'balance_after' => 'integer',
'room_id' => 'integer',
'created_at' => 'datetime',
];
// ─── 关联 ─────────────────────────────────────────────────