Files
chatroom/app/Http/Controllers/Admin/ChangelogController.php
lkddi 5f30220609 feat: 任命/撤销通知系统 + 用户名片UI优化
- 任命/撤销事件增加 type 字段区分类型
- 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息
- 撤销:灰色弹窗 + 灰色系统消息,无礼花
- 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏
- 系统消息加随机鼓励语(各5条轮换)
- ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds)
- 用户名片折叠优化:管理员视野、职务履历均可折叠
- 管理操作 + 职务操作合并为「🔧 管理操作」折叠区
- 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
2026-02-28 23:44:38 +08:00

192 lines
6.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 文件功能:后台开发日志管理控制器(仅 id=1 超级管理员可访问)
* 提供开发日志的 CRUD 功能,发布时可选择向 Room 1 大厅广播通知
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Http\Controllers\Admin;
use App\Events\ChangelogPublished;
use App\Http\Controllers\Controller;
use App\Jobs\SaveMessageJob;
use App\Models\DevChangelog;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\View\View;
class ChangelogController extends Controller
{
/**
* 后台日志列表(含草稿)
*/
public function index(): View
{
$logs = DevChangelog::orderByDesc('created_at')->paginate(20);
return view('admin.changelog.index', compact('logs'));
}
/**
* 新增日志表单页(预填今日日期)
*/
public function create(): View
{
// 预填今日日期为版本号
$todayVersion = now()->format('Y-m-d');
return view('admin.changelog.form', [
'log' => null,
'todayVersion' => $todayVersion,
'typeOptions' => DevChangelog::TYPE_CONFIG,
'isCreate' => true,
]);
}
/**
* 保存新日志
* 若勾选"立即发布",则记录 published_at 并可选向大厅广播通知
*/
public function store(Request $request): RedirectResponse
{
$data = $request->validate([
'version' => 'required|string|max:30',
'title' => 'required|string|max:200',
'type' => 'required|in:feature,fix,improve,other',
'content' => 'required|string',
'is_published' => 'nullable|boolean',
'notify_chat' => 'nullable|boolean',
]);
$isPublished = (bool) ($data['is_published'] ?? false);
$notifyChat = (bool) ($data['notify_chat'] ?? false);
/** @var DevChangelog $log */
$log = DevChangelog::create([
'version' => $data['version'],
'title' => $data['title'],
'type' => $data['type'],
'content' => $data['content'],
'is_published' => $isPublished,
// 只有同时勾选"通知"才记录 notify_chat否则置 false
'notify_chat' => $isPublished && $notifyChat,
// 首次发布时记录发布时间
'published_at' => $isPublished ? Carbon::now() : null,
]);
// 如果发布且勾选了"通知大厅用户",则触发 WebSocket 广播 + 持久化到消息库
if ($isPublished && $notifyChat) {
event(new ChangelogPublished($log));
$this->saveChangelogNotification($log);
}
return redirect()->route('admin.changelogs.index')
->with('success', '开发日志创建成功!'.($isPublished ? '(已发布)' : '(草稿已保存)'));
}
/**
* 编辑日志表单页
*
* @param DevChangelog $changelog 路由模型自动注入
*/
public function edit(DevChangelog $changelog): View
{
return view('admin.changelog.form', [
'log' => $changelog,
'todayVersion' => $changelog->version,
'typeOptions' => DevChangelog::TYPE_CONFIG,
'isCreate' => false,
]);
}
/**
* 更新日志内容(编辑操作不更新 published_at不触发通知
*
* @param DevChangelog $changelog 路由模型自动注入
*/
public function update(Request $request, DevChangelog $changelog): RedirectResponse
{
$log = $changelog;
$data = $request->validate([
'version' => 'required|string|max:30',
'title' => 'required|string|max:200',
'type' => 'required|in:feature,fix,improve,other',
'content' => 'required|string',
'is_published' => 'nullable|boolean',
'notify_chat' => 'nullable|boolean',
]);
$isPublished = (bool) ($data['is_published'] ?? false);
// 如果从草稿切换为发布,记录首次发布时间
$publishedAt = $log->published_at;
if ($isPublished && ! $log->is_published) {
$publishedAt = Carbon::now();
} elseif (! $isPublished) {
// 从发布退回草稿,清除发布时间
$publishedAt = null;
}
$log->update([
'version' => $data['version'],
'title' => $data['title'],
'type' => $data['type'],
'content' => $data['content'],
'is_published' => $isPublished,
'published_at' => $publishedAt,
]);
// 若勾选了「通知大厅用户」且当前已发布,则广播通知 + 持久化到消息库
$notifyChat = (bool) ($data['notify_chat'] ?? false);
if ($notifyChat && $isPublished) {
event(new ChangelogPublished($log));
$this->saveChangelogNotification($log);
}
return redirect()->route('admin.changelogs.index')
->with('success', '开发日志已更新!');
}
/**
* 删除日志
*
* @param DevChangelog $changelog 路由模型自动注入
*/
public function destroy(DevChangelog $changelog): RedirectResponse
{
$changelog->delete();
return redirect()->route('admin.changelogs.index')
->with('success', '日志已删除。');
}
/**
* 将版本更新通知持久化为 Room 1 系统消息
* 确保用户重进聊天室时仍能在历史消息中看到该通知
*
* @param DevChangelog $log 已发布的日志
*/
private function saveChangelogNotification(DevChangelog $log): void
{
$typeLabel = DevChangelog::TYPE_CONFIG[$log->type]['label'] ?? '更新';
$url = url('/changelog').'#v'.$log->version;
SaveMessageJob::dispatch([
'room_id' => 1,
'from_user' => '系统公告',
'to_user' => '大家',
'content' => "📢 【版本更新 {$typeLabel}】v{$log->version}{$log->title}》— <a href=\"{$url}\" target=\"_blank\" class=\"underline\">点击查看详情</a>",
'is_secret' => false,
'font_color' => '#7c3aed',
'action' => '',
'sent_at' => now()->toIso8601String(),
]);
}
}