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

186 lines
10 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.
{{--
文件功能:后台部门管理页面
提供部门的新增、编辑、删除功能,展示每个部门的职务数量
@author ChatRoom Laravel
@version 1.0.0
--}}
@extends('admin.layouts.app')
@section('title', '部门管理')
@section('content')
<div x-data="{
showForm: false,
editing: null,
form: { name: '', rank: 80, color: '#1a5276', sort_order: 0, description: '' },
openCreate() {
this.editing = null;
this.form = { name: '', rank: 80, color: '#1a5276', sort_order: 0, description: '' };
this.showForm = true;
},
openEdit(dept) {
this.editing = dept;
this.form = { name: dept.name, rank: dept.rank, color: dept.color, sort_order: dept.sort_order, description: dept.description };
this.showForm = true;
}
}">
{{-- 头部 --}}
<div class="flex justify-between items-center mb-6">
<div>
<h2 class="text-lg font-bold text-gray-800">部门管理</h2>
<p class="text-sm text-gray-500">管理聊天室部门架构,设置位阶、颜色与描述</p>
</div>
<div class="flex space-x-2">
<a href="{{ route('admin.positions.index') }}"
style="background-color:#16a34a;color:#fff;padding:0.5rem 1rem;border-radius:0.5rem;font-weight:700;font-size:0.875rem;display:inline-flex;align-items:center;text-decoration:none;box-shadow:0 1px 2px rgba(0,0,0,.1);"
onmouseover="this.style.backgroundColor='#15803d'" onmouseout="this.style.backgroundColor='#16a34a'">
📋 职务管理
</a>
@if (Auth::id() === 1)
<button @click="openCreate()"
style="background-color:#4f46e5;color:#fff;padding:0.5rem 1.25rem;border-radius:0.5rem;font-weight:700;border:none;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.1);"
onmouseover="this.style.backgroundColor='#4338ca'"
onmouseout="this.style.backgroundColor='#4f46e5'">
+ 新增部门
</button>
@endif
</div>
</div>
@if (session('success'))
<div class="mb-4 px-4 py-3 bg-green-50 border border-green-200 text-green-700 rounded-lg text-sm">
{{ session('success') }}
</div>
@endif
@if (session('error'))
<div class="mb-4 px-4 py-3 bg-red-50 border border-red-200 text-red-700 rounded-lg text-sm">
{{ session('error') }}
</div>
@endif
{{-- 部门卡片列表 --}}
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
@foreach ($departments as $dept)
<div class="bg-white rounded-xl shadow-sm border overflow-hidden hover:shadow-md transition">
<div class="h-2" style="background-color: {{ $dept->color }}"></div>
<div class="p-5">
<div class="flex items-center justify-between mb-3">
<span class="font-bold text-lg" style="color: {{ $dept->color }}">{{ $dept->name }}</span>
<span class="text-xs bg-gray-100 px-2 py-0.5 rounded text-gray-500">位阶
{{ $dept->rank }}</span>
</div>
<div class="space-y-1.5 text-sm">
<div class="flex justify-between">
<span class="text-gray-500">职务数量</span>
<span class="font-bold text-indigo-600">{{ $dept->positions_count }} </span>
</div>
<div class="flex justify-between">
<span class="text-gray-500">排序</span>
<span class="font-bold">{{ $dept->sort_order }}</span>
</div>
@if ($dept->description)
<p class="text-gray-400 text-xs pt-1">{{ $dept->description }}</p>
@endif
</div>
</div>
@php $superLvl = (int) \App\Models\Sysparam::getValue('superlevel', '100'); @endphp
@if (Auth::user()->user_level >= $superLvl)
<div class="border-t bg-gray-50 px-5 py-3 flex justify-end space-x-2">
<button
@click="openEdit({
id: {{ $dept->id }},
name: '{{ addslashes($dept->name) }}',
rank: {{ $dept->rank }},
color: '{{ $dept->color }}',
sort_order: {{ $dept->sort_order }},
description: '{{ addslashes($dept->description ?? '') }}',
requestUrl: '{{ route('admin.departments.update', $dept->id) }}'
})"
class="text-xs bg-indigo-50 text-indigo-600 font-bold px-3 py-1.5 rounded hover:bg-indigo-600 hover:text-white transition">
编辑
</button>
@if (Auth::id() === 1)
<form action="{{ route('admin.departments.destroy', $dept->id) }}" method="POST"
onsubmit="return confirm('确定删除部门【{{ $dept->name }}】?该操作会同时删除该部门所有职务(有在职人员时拒绝删除)。')">
@csrf @method('DELETE')
<button type="submit"
class="text-xs bg-red-50 text-red-600 font-bold px-3 py-1.5 rounded hover:bg-red-600 hover:text-white transition">
删除
</button>
</form>
@endif
</div>
@endif
</div>
@endforeach
</div>
@if ($departments->isEmpty())
<div class="text-center py-16 text-gray-400">
<p class="text-lg">暂无部门,点击右上角「新增部门」创建</p>
</div>
@endif
{{-- 新增/编辑弹窗 --}}
<div x-show="showForm" style="display: none;"
class="fixed inset-0 z-50 bg-black/60 flex items-center justify-center p-4">
<div @click.away="showForm = false" class="bg-white rounded-xl shadow-2xl w-full max-w-md" x-transition>
<div class="bg-indigo-900 px-6 py-4 flex justify-between items-center rounded-t-xl text-white">
<h3 class="font-bold text-lg" x-text="editing ? '编辑部门:' + editing.name : '新增部门'"></h3>
<button @click="showForm = false" class="text-gray-400 hover:text-white text-xl">&times;</button>
</div>
<div class="p-6">
<form :action="editing ? editing.requestUrl : '{{ route('admin.departments.store') }}'" method="POST">
@csrf
<template x-if="editing"><input type="hidden" name="_method" value="PUT"></template>
<div class="grid grid-cols-2 gap-4">
<div class="col-span-2">
<label class="block text-xs font-bold text-gray-600 mb-1">部门名称</label>
<input type="text" name="name" x-model="form.name" required maxlength="50"
class="w-full border rounded-md p-2 text-sm">
</div>
<div>
<label class="block text-xs font-bold text-gray-600 mb-1">位阶0~99,越大越高)</label>
<input type="number" name="rank" x-model="form.rank" required min="0"
max="99" class="w-full border rounded-md p-2 text-sm">
</div>
<div>
<label class="block text-xs font-bold text-gray-600 mb-1">排序</label>
<input type="number" name="sort_order" x-model="form.sort_order" required min="0"
class="w-full border rounded-md p-2 text-sm">
</div>
<div class="col-span-2">
<label class="block text-xs font-bold text-gray-600 mb-1">展示颜色</label>
<div class="flex items-center space-x-2">
<input type="color" name="color" x-model="form.color"
class="w-10 h-8 border rounded cursor-pointer">
<input type="text" x-model="form.color" maxlength="10"
class="flex-1 border rounded-md p-2 text-sm font-mono">
</div>
</div>
<div class="col-span-2">
<label class="block text-xs font-bold text-gray-600 mb-1">部门描述(可选)</label>
<input type="text" name="description" x-model="form.description" maxlength="255"
class="w-full border rounded-md p-2 text-sm">
</div>
</div>
<div class="flex justify-end space-x-3 pt-4 mt-4 border-t">
<button type="button" @click="showForm = false"
class="px-4 py-2 border rounded font-medium text-gray-600 hover:bg-gray-50">取消</button>
<button type="submit"
class="px-4 py-2 bg-indigo-600 text-white rounded font-bold hover:bg-indigo-700 shadow-sm"
x-text="editing ? '保存修改' : '创建部门'"></button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection