功能:VIP 赞助会员系统

- 新建 vip_levels 表(名称、图标、颜色、经验/金币倍率、专属进入/离开模板)
- 默认4个等级种子:白银🥈(×1.5)、黄金🥇(×2.0)、钻石💎(×3.0)、至尊👑(×5.0)
- 后台 VIP 等级 CRUD 管理(新增/编辑/删除,配置模板和倍率)
- 后台用户编辑弹窗支持设置 VIP 等级和到期时间
- ChatController 心跳经验按 VIP 倍率加成
- FishingController 正向奖励按 VIP 倍率加成(负面惩罚不变)
- 在线名单显示 VIP 图标和管理员🛡️标识
- VIP 用户进入/离开使用专属颜色和标题
- 后台侧栏新增「👑 VIP 会员等级」入口
This commit is contained in:
2026-02-26 21:30:07 +08:00
parent ea06328885
commit fd3214eaff
22 changed files with 2293 additions and 19 deletions

View File

@@ -0,0 +1,129 @@
<?php
/**
* 文件功能:创建 vip_levels 会员等级配置表
* 存储会员等级名称、图标、颜色、倍率、专属模板等配置
* 后台可完整 CRUD 管理
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* 创建 vip_levels 表并填充默认数据
*/
public function up(): void
{
Schema::create('vip_levels', function (Blueprint $table) {
$table->id();
$table->string('name', 50)->comment('会员名称(如:白银会员)');
$table->string('icon', 20)->default('⭐')->comment('等级图标/emoji');
$table->string('color', 10)->default('#f59e0b')->comment('等级颜色hex');
$table->decimal('exp_multiplier', 3, 1)->default(1.0)->comment('经验倍率');
$table->decimal('jjb_multiplier', 3, 1)->default(1.0)->comment('金币倍率');
$table->text('join_templates')->nullable()->comment('进入聊天室专属欢迎语 JSON 数组');
$table->text('leave_templates')->nullable()->comment('离开聊天室专属提示语 JSON 数组');
$table->tinyInteger('sort_order')->default(0)->comment('排序(越大越高级)');
$table->integer('price')->default(0)->comment('赞助金额(元,供展示参考)');
$table->integer('duration_days')->default(30)->comment('有效天数0=永久)');
$table->timestamps();
});
// 默认种子数据(后台可随时修改/删除/新增)
$now = now();
DB::table('vip_levels')->insert([
[
'name' => '白银会员',
'icon' => '🥈',
'color' => '#94a3b8',
'exp_multiplier' => 1.5,
'jjb_multiplier' => 1.2,
'join_templates' => json_encode([
'白银贵宾{username}乘坐银色马车缓缓驶入,气质不凡!',
'白银贵宾{username}手持银色令牌,大步流星走了进来!',
], JSON_UNESCAPED_UNICODE),
'leave_templates' => json_encode([
'白银贵宾{username}挥了挥手,潇洒离去',
'白银贵宾{username}骑着银色骏马飘然而去',
], JSON_UNESCAPED_UNICODE),
'sort_order' => 1,
'price' => 10,
'duration_days' => 30,
'created_at' => $now,
'updated_at' => $now,
],
[
'name' => '黄金会员',
'icon' => '🥇',
'color' => '#f59e0b',
'exp_multiplier' => 2.0,
'jjb_multiplier' => 1.5,
'join_templates' => json_encode([
'黄金贵宾{username}踩着金光闪闪的地毯,王者归来!',
'黄金贵宾{username}开着金色豪车呼啸而至,全场瞩目!',
], JSON_UNESCAPED_UNICODE),
'leave_templates' => json_encode([
'黄金贵宾{username}乘金色祥云腾空而去,霸气侧漏!',
'黄金贵宾{username}微微拱手,金光一闪消失不见',
], JSON_UNESCAPED_UNICODE),
'sort_order' => 2,
'price' => 30,
'duration_days' => 30,
'created_at' => $now,
'updated_at' => $now,
],
[
'name' => '钻石会员',
'icon' => '💎',
'color' => '#3b82f6',
'exp_multiplier' => 3.0,
'jjb_multiplier' => 2.0,
'join_templates' => json_encode([
'钻石贵宾{username}踏着星辰大海从天而降,万众敬仰!',
'钻石贵宾{username}驾驭钻石巨龙破空而来,威震四方!',
], JSON_UNESCAPED_UNICODE),
'leave_templates' => json_encode([
'钻石贵宾{username}化作一道星光冲天而去,令人叹服!',
'钻石贵宾{username}乘坐钻石飞船消失在银河尽头',
], JSON_UNESCAPED_UNICODE),
'sort_order' => 3,
'price' => 50,
'duration_days' => 30,
'created_at' => $now,
'updated_at' => $now,
],
[
'name' => '至尊会员',
'icon' => '👑',
'color' => '#a855f7',
'exp_multiplier' => 5.0,
'jjb_multiplier' => 3.0,
'join_templates' => json_encode([
'👑至尊{username}御驾亲临!九天雷鸣,万物俯首!众卿接驾!',
'👑至尊{username}脚踏七彩祥云,身披紫金龙袍,驾临此地!天地为之变色!',
], JSON_UNESCAPED_UNICODE),
'leave_templates' => json_encode([
'👑至尊{username}龙袍一甩,紫气东来,瞬间消失在九天之上!',
'👑至尊{username}御驾回宫,百鸟齐鸣相送!',
], JSON_UNESCAPED_UNICODE),
'sort_order' => 4,
'price' => 100,
'duration_days' => 30,
'created_at' => $now,
'updated_at' => $now,
],
]);
}
/**
* 回滚:删除 vip_levels
*/
public function down(): void
{
Schema::dropIfExists('vip_levels');
}
};

View File

@@ -0,0 +1,38 @@
<?php
/**
* 文件功能:在 users 表添加 vip_level_id 外键
* 关联 vip_levels 表,标识用户的会员等级
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* 添加 vip_level_id 字段(如果不存在)并建立外键
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
// 列可能已在之前失败的迁移中创建,仅在不存在时添加
if (! Schema::hasColumn('users', 'vip_level_id')) {
$table->unsignedBigInteger('vip_level_id')->nullable()->after('huiyuan')->comment('会员等级ID');
}
$table->foreign('vip_level_id')->references('id')->on('vip_levels')->nullOnDelete();
});
}
/**
* 回滚:删除 vip_level_id 字段
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropForeign(['vip_level_id']);
$table->dropColumn('vip_level_id');
});
}
};

View File

@@ -0,0 +1,70 @@
<?php
/**
* 文件功能:创建 AI 厂商配置表和 AI 使用日志表
*
* ai_provider_configs 存储多个 AI 厂商的 API 配置(密钥、端点、模型等)
* ai_usage_logs 记录每次 AI 接口调用的 token 消耗和响应信息
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* 执行迁移:创建 AI 相关的两张数据表
*/
public function up(): void
{
// AI 厂商配置表
Schema::create('ai_provider_configs', function (Blueprint $table) {
$table->id();
$table->string('provider', 50)->index()->comment('厂商标识(如 deepseek, qwen, openai');
$table->string('name', 100)->comment('厂商显示名称');
$table->text('api_key')->comment('API Key加密存储');
$table->string('api_endpoint', 255)->comment('API 端点地址');
$table->string('model', 100)->comment('使用的模型名称');
$table->decimal('temperature', 3, 2)->default(0.30)->comment('温度参数');
$table->integer('max_tokens')->default(2048)->comment('最大 Token 数');
$table->boolean('is_enabled')->default(true)->index()->comment('是否启用');
$table->boolean('is_default')->default(false)->comment('是否为默认厂商');
$table->integer('sort_order')->default(0)->comment('排序(故障转移时按此顺序)');
$table->timestamps();
});
// AI 使用日志表
Schema::create('ai_usage_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete()->comment('使用者');
$table->string('provider', 50)->comment('AI 厂商标识');
$table->string('model', 100)->comment('使用的模型');
$table->string('action', 50)->default('chatbot')->comment('操作类型');
$table->integer('prompt_tokens')->default(0)->comment('输入 Token 数');
$table->integer('completion_tokens')->default(0)->comment('输出 Token 数');
$table->integer('total_tokens')->default(0)->comment('总 Token 数');
$table->decimal('cost', 10, 6)->default(0)->comment('费用');
$table->integer('response_time_ms')->default(0)->comment('响应时间(毫秒)');
$table->boolean('success')->default(true)->comment('是否成功');
$table->text('error_message')->nullable()->comment('错误信息');
$table->timestamps();
// 索引
$table->index(['provider', 'created_at']);
});
}
/**
* 回滚迁移:删除 AI 相关的两张数据表
*/
public function down(): void
{
Schema::dropIfExists('ai_usage_logs');
Schema::dropIfExists('ai_provider_configs');
}
};