- 任命/撤销事件增加 type 字段区分类型 - 任命:全屏礼花 + 紫色弹窗 + 紫色系统消息 - 撤销:灰色弹窗 + 灰色系统消息,无礼花 - 消息分发:操作者/被操作者显示在私聊面板,其他人显示在公屏 - 系统消息加随机鼓励语(各5条轮换) - ChatStateService 修复 Redis key 前缀扫描问题(getAllActiveRoomIds) - 用户名片折叠优化:管理员视野、职务履历均可折叠 - 管理操作 + 职务操作合并为「🔧 管理操作」折叠区 - 悄悄话改为「🎁 送礼物」按钮,礼物面板内联展开
186 lines
10 KiB
PHP
186 lines
10 KiB
PHP
{{--
|
||
文件功能:后台部门管理页面
|
||
提供部门的新增、编辑、删除功能,展示每个部门的职务数量
|
||
|
||
@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">×</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
|