|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Support;
|
|
|
|
|
|
|
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据后台 API 路径与请求体生成简短中文「操作项」说明。
|
|
|
|
|
|
*/
|
|
|
|
|
|
final class AdminAuditOperationDescriber
|
|
|
|
|
|
{
|
|
|
|
|
|
public static function describe(Request $request, array $payload, int $statusCode): string
|
|
|
|
|
|
{
|
|
|
|
|
|
$method = strtoupper($request->method());
|
|
|
|
|
|
$path = self::normalizeApiPath($request);
|
|
|
|
|
|
$fail = $statusCode >= 400 ? '(失败)' : '';
|
|
|
|
|
|
|
|
|
|
|
|
$name = static fn (?string $s): ?string => $s !== null && trim($s) !== '' ? trim($s) : null;
|
|
|
|
|
|
|
|
|
|
|
|
if ($path === 'auth/logout' && $method === 'POST') {
|
|
|
|
|
|
return '退出登录'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 场馆 ---
|
|
|
|
|
|
if ($path === 'venues' && $method === 'POST') {
|
|
|
|
|
|
$t = $name($payload['name'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '新增场馆「'.$t.'」'.$fail : '新增场馆'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^venues/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
$t = $name($payload['name'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '编辑场馆「'.$t.'」'.$fail : '编辑场馆(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除场馆(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^venues/(\d+)/audit/approve$#', $path, $m)) {
|
|
|
|
|
|
return '审核通过场馆(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^venues/(\d+)/audit/reject$#', $path, $m)) {
|
|
|
|
|
|
return '驳回场馆审核(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'venues/import/preview' && $method === 'POST') {
|
|
|
|
|
|
return '导入场馆·预览'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'venues/import/confirm' && $method === 'POST') {
|
|
|
|
|
|
return '导入场馆·确认入库'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 活动 ---
|
|
|
|
|
|
if ($path === 'activities' && $method === 'POST') {
|
|
|
|
|
|
$t = $name($payload['title'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '新增活动「'.$t.'」'.$fail : '新增活动'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activities/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
$t = $name($payload['title'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '编辑活动「'.$t.'」'.$fail : '编辑活动(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除活动(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activities/(\d+)/audit/approve$#', $path, $m)) {
|
|
|
|
|
|
return '审核通过活动(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activities/(\d+)/audit/reject$#', $path, $m)) {
|
|
|
|
|
|
return '驳回活动审核(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activities/(\d+)/toggle$#', $path, $m)) {
|
|
|
|
|
|
return '切换活动启停(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activities/(\d+)/restore$#', $path, $m)) {
|
|
|
|
|
|
return '恢复活动(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 抢票活动 ---
|
|
|
|
|
|
if ($path === 'ticket-grab-events' && $method === 'POST') {
|
|
|
|
|
|
$t = $name($payload['title'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '新增抢票活动「'.$t.'」'.$fail : '新增抢票活动'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^ticket-grab-events/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
$t = $name($payload['title'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '编辑抢票活动「'.$t.'」'.$fail : '编辑抢票活动(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除抢票活动(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^ticket-grab-events/(\d+)/toggle$#', $path, $m)) {
|
|
|
|
|
|
return '切换抢票活动启停(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 管理员与权限 ---
|
|
|
|
|
|
if ($path === 'admin-users' && $method === 'POST') {
|
|
|
|
|
|
$u = $name($payload['username'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $u !== null ? '新增管理员「'.$u.'」'.$fail : '新增管理员'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^admin-users/(\d+)$#', $path, $m) && ($method === 'PUT' || $method === 'PATCH')) {
|
|
|
|
|
|
return '编辑管理员(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'admin-roles' && $method === 'POST') {
|
|
|
|
|
|
$slug = $name($payload['slug'] ?? null);
|
|
|
|
|
|
$rn = $name($payload['name'] ?? null);
|
|
|
|
|
|
if ($slug !== null && $rn !== null) {
|
|
|
|
|
|
return '新增角色「'.$rn.'」('.$slug.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return '新增角色'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^admin-roles/([a-z0-9_]+)$#', $path, $m) && ($method === 'PUT' || $method === 'PATCH')) {
|
|
|
|
|
|
return '编辑角色('.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^admin-roles/([a-z0-9_]+)$#', $path, $m) && $method === 'DELETE') {
|
|
|
|
|
|
return '删除角色('.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($path === 'admin-menus' && $method === 'POST') {
|
|
|
|
|
|
$t = $name($payload['name'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '新增菜单「'.$t.'」'.$fail : '新增菜单'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^admin-menus/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
$t = $name($payload['name'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '编辑菜单「'.$t.'」'.$fail : '编辑菜单(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除菜单(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (preg_match('#^role-menu-permissions/(.+)$#', $path, $m) && ($method === 'PUT' || $method === 'PATCH')) {
|
|
|
|
|
|
return '保存角色菜单权限('.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($path === 'role-permissions/batch-update' && $method === 'POST') {
|
|
|
|
|
|
return '批量更新功能权限'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^role-permissions/(\d+)$#', $path, $m) && ($method === 'PUT' || $method === 'PATCH')) {
|
|
|
|
|
|
return '更新功能权限(ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 上传 ---
|
|
|
|
|
|
if ($path === 'upload' && $method === 'POST') {
|
|
|
|
|
|
return '上传文件'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'upload/delete' && $method === 'POST') {
|
|
|
|
|
|
return '删除已上传文件'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 核销 ---
|
|
|
|
|
|
if ($path === 'reservations/verify' && $method === 'POST') {
|
|
|
|
|
|
return '核销预约'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'activity-registrations/quick-blacklist/batch' && $method === 'POST') {
|
|
|
|
|
|
return '批量列入灰名单(报名)'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^activity-registrations/(\d+)/quick-blacklist$#', $path, $m) && $method === 'POST') {
|
|
|
|
|
|
return '一键列入灰名单(报名 ID:'.$m[1].')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 灰名单 ---
|
|
|
|
|
|
if ($path === 'blacklists' && $method === 'POST') {
|
|
|
|
|
|
return '新增灰名单记录'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^blacklists/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
return '编辑灰名单(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除灰名单(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'blacklists/batch-import' && $method === 'POST') {
|
|
|
|
|
|
return '批量导入灰名单'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'user-management/blacklist' && $method === 'POST') {
|
|
|
|
|
|
return '批量列入灰名单用户'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($path === 'user-management/unblacklist' && $method === 'POST') {
|
|
|
|
|
|
return '批量移出灰名单'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --- 研学 / 字典 ---
|
|
|
|
|
|
if ($path === 'study-tours' && $method === 'POST') {
|
|
|
|
|
|
$t = $name($payload['title'] ?? null);
|
|
|
|
|
|
|
|
|
|
|
|
return $t !== null ? '新增研学路线「'.$t.'」'.$fail : '新增研学路线'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^study-tours/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
return '编辑研学路线(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除研学路线(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($path === 'dict-items' && $method === 'POST') {
|
|
|
|
|
|
return '新增字典项'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (preg_match('#^dict-items/(\d+)$#', $path, $m)) {
|
|
|
|
|
|
$id = $m[1];
|
|
|
|
|
|
if ($method === 'PUT' || $method === 'PATCH') {
|
|
|
|
|
|
return '编辑字典项(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($method === 'DELETE') {
|
|
|
|
|
|
return '删除字典项(ID:'.$id.')'.$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// fallback
|
|
|
|
|
|
return self::fallbackLabel($method, $path).$fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function normalizeApiPath(Request $request): string
|
|
|
|
|
|
{
|
|
|
|
|
|
$p = trim($request->path(), '/');
|
|
|
|
|
|
if (str_starts_with($p, 'api/')) {
|
|
|
|
|
|
return substr($p, strlen('api/'));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $p;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static function fallbackLabel(string $method, string $path): string
|
|
|
|
|
|
{
|
|
|
|
|
|
return $method.' '.$path;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|