- 任命/撤销事件增加 type 字段区分类型 - 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息 - 撤销:灰色弹窗 + 灰色系统消息,无礼花 - 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏 - 系统消息加随机鼓励语(各5条轮换) - ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds) - 用户名片折叠优化:管理员视野、职务履历均可折叠 - 管理操作 + 职务操作合并为「🔧 管理操作」折叠区 - 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
113 lines
3.7 KiB
PHP
113 lines
3.7 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:后台用户反馈管理控制器(仅 id=1 超级管理员可访问)
|
||
* 提供反馈列表查看、处理状态修改、官方回复功能
|
||
* 侧边栏显示待处理数量徽标
|
||
*
|
||
* @author ChatRoom Laravel
|
||
*
|
||
* @version 1.0.0
|
||
*/
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\FeedbackItem;
|
||
use App\Models\FeedbackReply;
|
||
use Illuminate\Http\JsonResponse;
|
||
use Illuminate\Http\RedirectResponse;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\View\View;
|
||
|
||
class FeedbackManagerController extends Controller
|
||
{
|
||
/**
|
||
* 后台反馈列表页(支持类型+状态筛选)
|
||
*
|
||
* @param Request $request 含 type/status 筛选参数
|
||
*/
|
||
public function index(Request $request): View
|
||
{
|
||
$type = $request->input('type');
|
||
$status = $request->input('status');
|
||
|
||
$query = FeedbackItem::with(['replies'])
|
||
->orderByDesc('created_at');
|
||
|
||
// 按类型筛选
|
||
if ($type && in_array($type, ['bug', 'suggestion'])) {
|
||
$query->ofType($type);
|
||
}
|
||
|
||
// 按状态筛选
|
||
if ($status && array_key_exists($status, FeedbackItem::STATUS_CONFIG)) {
|
||
$query->ofStatus($status);
|
||
}
|
||
|
||
$feedbacks = $query->paginate(20)->withQueryString();
|
||
|
||
// 待处理数量(用于侧边栏徽标)
|
||
$pendingCount = FeedbackItem::pending()->count();
|
||
|
||
return view('admin.feedback.index', [
|
||
'feedbacks' => $feedbacks,
|
||
'pendingCount' => $pendingCount,
|
||
'statusConfig' => FeedbackItem::STATUS_CONFIG,
|
||
'typeConfig' => FeedbackItem::TYPE_CONFIG,
|
||
'currentType' => $type,
|
||
'currentStatus' => $status,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 更新反馈处理状态和官方回复(Ajax + 表单双模式)
|
||
* Ajax 返回 JSON,普通表单提交返回重定向
|
||
*
|
||
* @param Request $request 含 status/admin_remark 字段
|
||
* @param int $id 反馈 ID
|
||
*/
|
||
public function update(Request $request, int $id): JsonResponse|RedirectResponse
|
||
{
|
||
$feedback = FeedbackItem::findOrFail($id);
|
||
|
||
$data = $request->validate([
|
||
'status' => 'required|in:'.implode(',', array_keys(FeedbackItem::STATUS_CONFIG)),
|
||
'admin_remark' => 'nullable|string|max:2000',
|
||
]);
|
||
|
||
$feedback->update([
|
||
'status' => $data['status'],
|
||
'admin_remark' => $data['admin_remark'] ?? $feedback->admin_remark,
|
||
]);
|
||
|
||
// 如果有新的官方回复内容,同时写入 feedback_replies(带 is_admin 标记)
|
||
if (! empty($data['admin_remark']) && $data['admin_remark'] !== $feedback->getOriginal('admin_remark')) {
|
||
DB::transaction(function () use ($feedback, $data): void {
|
||
FeedbackReply::create([
|
||
'feedback_id' => $feedback->id,
|
||
'user_id' => 1,
|
||
'username' => '🛡️ 开发者',
|
||
'content' => $data['admin_remark'],
|
||
'is_admin' => true,
|
||
]);
|
||
$feedback->increment('replies_count');
|
||
});
|
||
}
|
||
|
||
// Ajax 请求返回 JSON
|
||
if ($request->expectsJson()) {
|
||
return response()->json([
|
||
'status' => 'success',
|
||
'new_status' => $data['status'],
|
||
'status_label' => FeedbackItem::STATUS_CONFIG[$data['status']]['icon'].' '.FeedbackItem::STATUS_CONFIG[$data['status']]['label'],
|
||
'status_color' => FeedbackItem::STATUS_CONFIG[$data['status']]['color'],
|
||
]);
|
||
}
|
||
|
||
return redirect()->route('admin.feedback.index')
|
||
->with('success', '反馈状态已更新!');
|
||
}
|
||
}
|