- 任命/撤销事件增加 type 字段区分类型 - 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息 - 撤销:灰色弹窗 + 灰色系统消息,无礼花 - 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏 - 系统消息加随机鼓励语(各5条轮换) - ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds) - 用户名片折叠优化:管理员视野、职务履历均可折叠 - 管理操作 + 职务操作合并为「🔧 管理操作」折叠区 - 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
111 lines
3.8 KiB
PHP
111 lines
3.8 KiB
PHP
<?php
|
||
|
||
/**
|
||
* 文件功能:后台职务管理控制器
|
||
* 提供职务的 CRUD 功能,包含任命权限白名单(多选 position_appoint_limits)的同步
|
||
* 职务属于部门,包含等级、图标、人数上限、奖励上限等配置
|
||
*
|
||
* @author ChatRoom Laravel
|
||
*
|
||
* @version 1.0.0
|
||
*/
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\Department;
|
||
use App\Models\Position;
|
||
use Illuminate\Http\RedirectResponse;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\View\View;
|
||
|
||
class PositionController extends Controller
|
||
{
|
||
/**
|
||
* 职务列表页
|
||
*/
|
||
public function index(): View
|
||
{
|
||
// 按部门分组展示
|
||
$departments = Department::with([
|
||
'positions' => fn ($q) => $q->withCount(['activeUserPositions'])->ordered(),
|
||
])->ordered()->get();
|
||
|
||
// 全部职务(供任命白名单多选框使用)
|
||
$allPositions = Position::with('department')->orderByDesc('rank')->get();
|
||
|
||
return view('admin.positions.index', compact('departments', 'allPositions'));
|
||
}
|
||
|
||
/**
|
||
* 创建职务(同时同步任命白名单)
|
||
*/
|
||
public function store(Request $request): RedirectResponse
|
||
{
|
||
$data = $request->validate([
|
||
'department_id' => 'required|exists:departments,id',
|
||
'name' => 'required|string|max:50',
|
||
'icon' => 'nullable|string|max:10',
|
||
'rank' => 'required|integer|min:0|max:99',
|
||
'level' => 'required|integer|min:1|max:100',
|
||
'max_persons' => 'nullable|integer|min:1',
|
||
'max_reward' => 'nullable|integer|min:0',
|
||
'sort_order' => 'required|integer|min:0',
|
||
'appointable_ids' => 'nullable|array',
|
||
'appointable_ids.*' => 'exists:positions,id',
|
||
]);
|
||
|
||
$appointableIds = $data['appointable_ids'] ?? [];
|
||
unset($data['appointable_ids']);
|
||
|
||
$position = Position::create($data);
|
||
|
||
// 同步任命白名单(有选则写,没选则清空=无任命权)
|
||
$position->appointablePositions()->sync($appointableIds);
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$data['name']}】创建成功!");
|
||
}
|
||
|
||
/**
|
||
* 更新职务(含任命白名单同步)
|
||
*/
|
||
public function update(Request $request, Position $position): RedirectResponse
|
||
{
|
||
$data = $request->validate([
|
||
'department_id' => 'required|exists:departments,id',
|
||
'name' => 'required|string|max:50',
|
||
'icon' => 'nullable|string|max:10',
|
||
'rank' => 'required|integer|min:0|max:99',
|
||
'level' => 'required|integer|min:1|max:100',
|
||
'max_persons' => 'nullable|integer|min:1',
|
||
'max_reward' => 'nullable|integer|min:0',
|
||
'sort_order' => 'required|integer|min:0',
|
||
'appointable_ids' => 'nullable|array',
|
||
'appointable_ids.*' => 'exists:positions,id',
|
||
]);
|
||
|
||
$appointableIds = $data['appointable_ids'] ?? [];
|
||
unset($data['appointable_ids']);
|
||
|
||
$position->update($data);
|
||
$position->appointablePositions()->sync($appointableIds);
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$data['name']}】更新成功!");
|
||
}
|
||
|
||
/**
|
||
* 删除职务(有在职人员时拒绝)
|
||
*/
|
||
public function destroy(Position $position): RedirectResponse
|
||
{
|
||
if ($position->isFull() || $position->activeUserPositions()->exists()) {
|
||
return redirect()->route('admin.positions.index')
|
||
->with('error', "职务【{$position->name}】尚有在职人员,请先撤销后再删除。");
|
||
}
|
||
|
||
$position->delete();
|
||
|
||
return redirect()->route('admin.positions.index')->with('success', "职务【{$position->name}】已删除!");
|
||
}
|
||
}
|