feat: 任命/撤销通知系统 + 用户名片UI优化

- 任命/撤销事件增加 type 字段区分类型
- 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息
- 撤销:灰色弹窗 + 灰色系统消息,无礼花
- 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏
- 系统消息加随机鼓励语(各5条轮换)
- ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds)
- 用户名片折叠优化:管理员视野、职务履历均可折叠
- 管理操作 + 职务操作合并为「🔧 管理操作」折叠区
- 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
This commit is contained in:
2026-02-28 23:44:38 +08:00
parent a599047cf0
commit 5f30220609
80 changed files with 8579 additions and 473 deletions
+113 -31
View File
@@ -2,8 +2,10 @@
use App\Http\Controllers\AdminCommandController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ChangelogController;
use App\Http\Controllers\ChatBotController;
use App\Http\Controllers\ChatController;
use App\Http\Controllers\FeedbackController;
use App\Http\Controllers\FishingController;
use App\Http\Controllers\RoomController;
use App\Http\Controllers\UserController;
@@ -46,6 +48,9 @@ Route::middleware(['chat.auth'])->group(function () {
// 用户个人积分流水日志(查询自己的经验/金币/魅力历史)
Route::get('/my/currency-logs', [\App\Http\Controllers\LeaderboardController::class, 'myLogs'])->name('currency.my-logs');
// ---- 勤务台(展示四榜)----
Route::get('/duty-hall', [\App\Http\Controllers\DutyHallController::class, 'index'])->name('duty-hall.index');
// ---- 第十阶段:站内信与留言板系统 ----
Route::get('/guestbook', [\App\Http\Controllers\GuestbookController::class, 'index'])->name('guestbook.index');
Route::post('/guestbook', [\App\Http\Controllers\GuestbookController::class, 'store'])->middleware('throttle:10,1')->name('guestbook.store');
@@ -110,52 +115,122 @@ Route::middleware(['chat.auth'])->group(function () {
Route::get('/shop/items', [\App\Http\Controllers\ShopController::class, 'items'])->name('shop.items');
Route::post('/shop/buy', [\App\Http\Controllers\ShopController::class, 'buy'])->name('shop.buy');
Route::post('/shop/rename', [\App\Http\Controllers\ShopController::class, 'rename'])->name('shop.rename');
// ---- 开发日志(独立前台页面 /changelog----
Route::get('/changelog', [ChangelogController::class, 'index'])->name('changelog.index');
// 懒加载接口:scroll 到底追加更多日志
Route::get('/changelog/more', [ChangelogController::class, 'loadMoreChangelogs'])->name('changelog.more');
// ---- 用户反馈(独立前台页面 /feedback----
// 反馈列表页
Route::get('/feedback', [FeedbackController::class, 'index'])->name('feedback.index');
// 懒加载接口:scroll 到底追加更多反馈
Route::get('/feedback/more', [FeedbackController::class, 'loadMore'])->name('feedback.more');
// 提交新反馈
Route::post('/feedback', [FeedbackController::class, 'store'])->middleware('throttle:5,1')->name('feedback.store');
// 赞同/取消赞同(Toggle
Route::post('/feedback/{id}/vote', [FeedbackController::class, 'vote'])->name('feedback.vote');
// 提交补充评论
Route::post('/feedback/{id}/reply', [FeedbackController::class, 'reply'])->middleware('throttle:10,1')->name('feedback.reply');
// 删除反馈(本人24小时内或管理员)
Route::delete('/feedback/{id}', [FeedbackController::class, 'destroy'])->name('feedback.destroy');
});
// 强力特权层中间件:同时验证 chat.auth 登录态 和 chat.level:super 特权(superlevel 由 sysparam 配置)
Route::middleware(['chat.auth', 'chat.level:super'])->prefix('admin')->name('admin.')->group(function () {
// ═══════════════════════════════════════════════════════════════════
// 后台管理路由(三层权限)
// 层级 1chat.has_position ── 有在职职务即可(id=1 始终通过)
// 层级 2chat.site_owner ── 仅站长(id=1
// 聊天室内快速任命/撤销(需登录 + 有在职职务)
Route::middleware(['chat.auth', 'chat.has_position'])->prefix('chat-appoint')->name('chat.appoint.')->group(function () {
Route::get('/positions', [\App\Http\Controllers\ChatAppointmentController::class, 'positions'])->name('positions');
Route::post('/appoint', [\App\Http\Controllers\ChatAppointmentController::class, 'appoint'])->name('appoint');
Route::post('/revoke', [\App\Http\Controllers\ChatAppointmentController::class, 'revoke'])->name('revoke');
});
// ═══════════════════════════════════════════════════════════════════
Route::middleware(['chat.auth', 'chat.has_position'])->prefix('admin')->name('admin.')->group(function () {
// ──────────────────────────────────────────────────────────────
// 层级 1:有在职职务即可访问
// ──────────────────────────────────────────────────────────────
// 后台首页概览
Route::get('/', [\App\Http\Controllers\Admin\DashboardController::class, 'index'])->name('dashboard');
// 系统参数配置 (替代 VIEWSYS.ASP / SetSYS.ASP)
Route::middleware(['chat.site_owner'])->group(function () {
// 积分流水统计
Route::get('/currency-stats', [\App\Http\Controllers\Admin\CurrencyStatsController::class, 'index'])->name('currency-stats.index');
// 用户管理:有职务的人只能查看(index),update/destroy 仅站长
Route::get('/users', [\App\Http\Controllers\Admin\UserManagerController::class, 'index'])->name('users.index');
// 秘语查看(耳语记录)
Route::get('/whispers', function () {
return view('admin.whispers');
})->name('whispers.index');
// 任命管理(任命权限由 AppointmentService 内部校验)
Route::get('/appointments', [\App\Http\Controllers\Admin\AppointmentController::class, 'index'])->name('appointments.index');
Route::post('/appointments', [\App\Http\Controllers\Admin\AppointmentController::class, 'store'])->name('appointments.store');
Route::delete('/appointments/{userPosition}/revoke', [\App\Http\Controllers\Admin\AppointmentController::class, 'revoke'])->name('appointments.revoke');
Route::get('/appointments/{userPosition}/duty-logs', [\App\Http\Controllers\Admin\AppointmentController::class, 'dutyLogs'])->name('appointments.duty-logs');
Route::get('/appointments/{userPosition}/authority-logs', [\App\Http\Controllers\Admin\AppointmentController::class, 'authorityLogs'])->name('appointments.authority-logs');
Route::get('/appointments/history', [\App\Http\Controllers\Admin\AppointmentController::class, 'history'])->name('appointments.history');
Route::get('/appointments/search-users', [\App\Http\Controllers\Admin\AppointmentController::class, 'searchUsers'])->name('appointments.search-users');
// ── 层级 1.5superlevel 及以上可完整操作以下模块 ──
Route::middleware(['chat.level:super'])->group(function () {
// 部门 / 职务列表 + 编辑(删除仍限 id=1)
Route::get('/departments', [\App\Http\Controllers\Admin\DepartmentController::class, 'index'])->name('departments.index');
Route::get('/positions', [\App\Http\Controllers\Admin\PositionController::class, 'index'])->name('positions.index');
Route::put('/departments/{department}', [\App\Http\Controllers\Admin\DepartmentController::class, 'update'])->name('departments.update');
Route::put('/positions/{position}', [\App\Http\Controllers\Admin\PositionController::class, 'update'])->name('positions.update');
// 聊天室参数(含保存)
Route::get('/system', [\App\Http\Controllers\Admin\SystemController::class, 'edit'])->name('system.edit');
Route::put('/system', [\App\Http\Controllers\Admin\SystemController::class, 'update'])->name('system.update');
// 房间管理(含编辑/删除)
Route::get('/rooms', [\App\Http\Controllers\Admin\RoomManagerController::class, 'index'])->name('rooms.index');
Route::put('/rooms/{room}', [\App\Http\Controllers\Admin\RoomManagerController::class, 'update'])->name('rooms.update');
Route::delete('/rooms/{room}', [\App\Http\Controllers\Admin\RoomManagerController::class, 'destroy'])->name('rooms.destroy');
// 随机事件(含新增/编辑/删除/切换)
Route::get('/autoact', [\App\Http\Controllers\Admin\AutoactController::class, 'index'])->name('autoact.index');
Route::post('/autoact', [\App\Http\Controllers\Admin\AutoactController::class, 'store'])->name('autoact.store');
Route::put('/autoact/{autoact}', [\App\Http\Controllers\Admin\AutoactController::class, 'update'])->name('autoact.update');
Route::delete('/autoact/{autoact}', [\App\Http\Controllers\Admin\AutoactController::class, 'destroy'])->name('autoact.destroy');
Route::post('/autoact/{autoact}/toggle', [\App\Http\Controllers\Admin\AutoactController::class, 'toggle'])->name('autoact.toggle');
// VIP 会员等级(含新增/编辑/删除)
Route::get('/vip', [\App\Http\Controllers\Admin\VipController::class, 'index'])->name('vip.index');
Route::post('/vip', [\App\Http\Controllers\Admin\VipController::class, 'store'])->name('vip.store');
Route::put('/vip/{vip}', [\App\Http\Controllers\Admin\VipController::class, 'update'])->name('vip.update');
Route::delete('/vip/{vip}', [\App\Http\Controllers\Admin\VipController::class, 'destroy'])->name('vip.destroy');
});
// ──────────────────────────────────────────────────────────────
// 层级 2:仅站长(id=1)可进行以下操作
// ──────────────────────────────────────────────────────────────
Route::middleware(['chat.site_owner'])->group(function () {
// 用户编辑 & 删除
Route::put('/users/{user}', [\App\Http\Controllers\Admin\UserManagerController::class, 'update'])->name('users.update');
Route::delete('/users/{user}', [\App\Http\Controllers\Admin\UserManagerController::class, 'destroy'])->name('users.destroy');
// 发信配置管理
Route::get('/smtp', [\App\Http\Controllers\Admin\SmtpController::class, 'edit'])->name('smtp.edit');
Route::put('/smtp', [\App\Http\Controllers\Admin\SmtpController::class, 'update'])->name('smtp.update');
Route::post('/smtp/test', [\App\Http\Controllers\Admin\SmtpController::class, 'test'])->name('smtp.test');
});
// 用户大盘管理 (替代 gl/ 目录下的各种用户管理功能)
Route::get('/users', [\App\Http\Controllers\Admin\UserManagerController::class, 'index'])->name('users.index');
Route::put('/users/{id}', [\App\Http\Controllers\Admin\UserManagerController::class, 'update'])->name('users.update');
Route::delete('/users/{id}', [\App\Http\Controllers\Admin\UserManagerController::class, 'destroy'])->name('users.destroy'); // 物理封杀
// 部门新增/删除(编辑已在 superlevel 层)
Route::post('/departments', [\App\Http\Controllers\Admin\DepartmentController::class, 'store'])->name('departments.store');
Route::delete('/departments/{department}', [\App\Http\Controllers\Admin\DepartmentController::class, 'destroy'])->name('departments.destroy');
// 房间管理
Route::get('/rooms', [\App\Http\Controllers\Admin\RoomManagerController::class, 'index'])->name('rooms.index');
Route::put('/rooms/{id}', [\App\Http\Controllers\Admin\RoomManagerController::class, 'update'])->name('rooms.update');
Route::delete('/rooms/{id}', [\App\Http\Controllers\Admin\RoomManagerController::class, 'destroy'])->name('rooms.destroy');
// 职务新增/删除(编辑已在 superlevel 层)
Route::post('/positions', [\App\Http\Controllers\Admin\PositionController::class, 'store'])->name('positions.store');
Route::delete('/positions/{position}', [\App\Http\Controllers\Admin\PositionController::class, 'destroy'])->name('positions.destroy');
// 随机事件管理(复刻原版 autoact 系统)
Route::get('/autoact', [\App\Http\Controllers\Admin\AutoactController::class, 'index'])->name('autoact.index');
Route::post('/autoact', [\App\Http\Controllers\Admin\AutoactController::class, 'store'])->name('autoact.store');
Route::put('/autoact/{id}', [\App\Http\Controllers\Admin\AutoactController::class, 'update'])->name('autoact.update');
Route::post('/autoact/{id}/toggle', [\App\Http\Controllers\Admin\AutoactController::class, 'toggle'])->name('autoact.toggle');
Route::delete('/autoact/{id}', [\App\Http\Controllers\Admin\AutoactController::class, 'destroy'])->name('autoact.destroy');
// VIP 会员等级管理
Route::get('/vip', [\App\Http\Controllers\Admin\VipController::class, 'index'])->name('vip.index');
Route::post('/vip', [\App\Http\Controllers\Admin\VipController::class, 'store'])->name('vip.store');
Route::put('/vip/{id}', [\App\Http\Controllers\Admin\VipController::class, 'update'])->name('vip.update');
Route::delete('/vip/{id}', [\App\Http\Controllers\Admin\VipController::class, 'destroy'])->name('vip.destroy');
// 积分流水活动统计(管理员查看每日经验/金币产出概况)
Route::get('/currency-stats', [\App\Http\Controllers\Admin\CurrencyStatsController::class, 'index'])->name('currency-stats.index');
// AI 厂商配置管理
Route::middleware(['chat.site_owner'])->group(function () {
// AI 厂商配置管理
Route::get('/ai-providers', [\App\Http\Controllers\Admin\AiProviderController::class, 'index'])->name('ai-providers.index');
Route::post('/ai-providers', [\App\Http\Controllers\Admin\AiProviderController::class, 'store'])->name('ai-providers.store');
Route::put('/ai-providers/{id}', [\App\Http\Controllers\Admin\AiProviderController::class, 'update'])->name('ai-providers.update');
@@ -163,5 +238,12 @@ Route::middleware(['chat.auth', 'chat.level:super'])->prefix('admin')->name('adm
Route::post('/ai-providers/{id}/default', [\App\Http\Controllers\Admin\AiProviderController::class, 'setDefault'])->name('ai-providers.default');
Route::post('/ai-providers/toggle-chatbot', [\App\Http\Controllers\Admin\AiProviderController::class, 'toggleChatBot'])->name('ai-providers.toggle-chatbot');
Route::delete('/ai-providers/{id}', [\App\Http\Controllers\Admin\AiProviderController::class, 'destroy'])->name('ai-providers.destroy');
// 开发日志管理
Route::resource('changelogs', \App\Http\Controllers\Admin\ChangelogController::class)->except(['show']);
// 用户反馈管理
Route::get('/feedback', [\App\Http\Controllers\Admin\FeedbackManagerController::class, 'index'])->name('feedback.index');
Route::put('/feedback/{id}', [\App\Http\Controllers\Admin\FeedbackManagerController::class, 'update'])->name('feedback.update');
});
});