refactor:用 AdminApiList 统一后台列表类接口的响应格式
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1\Admin\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Lottery\ErrorCode;
|
||||
use App\Models\AdminUser;
|
||||
use App\Services\AuditLogger;
|
||||
use App\Support\AdminUserApiPresenter;
|
||||
use App\Support\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/** DELETE /api/v1/admin/admin-users/{admin_user} */
|
||||
final class AdminUserDestroyController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request, AdminUser $admin_user): JsonResponse
|
||||
{
|
||||
/** @var AdminUser $actor */
|
||||
$actor = $request->lotteryAdmin();
|
||||
|
||||
if ((int) $actor->getKey() === (int) $admin_user->getKey()) {
|
||||
return ApiResponse::error(
|
||||
'不能删除当前登录账号',
|
||||
ErrorCode::ValidationFailed->value,
|
||||
null,
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$admin_user->load('roles');
|
||||
if ($admin_user->isSuperAdmin()) {
|
||||
$hasOther = AdminUser::query()
|
||||
->whereKeyNot($admin_user->getKey())
|
||||
->whereHas('roles', static fn ($q) => $q->where('admin_roles.slug', AdminUser::ROLE_SUPER_ADMIN))
|
||||
->exists();
|
||||
if (! $hasOther) {
|
||||
return ApiResponse::error(
|
||||
'不能删除最后一个超级管理员',
|
||||
ErrorCode::ValidationFailed->value,
|
||||
null,
|
||||
422,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$before = AdminUserApiPresenter::listItem($admin_user);
|
||||
$id = (int) $admin_user->id;
|
||||
$admin_user->delete();
|
||||
|
||||
AuditLogger::recordForAdmin(
|
||||
$actor,
|
||||
$request,
|
||||
'system',
|
||||
'admin_user.delete',
|
||||
'admin_user',
|
||||
(string) $id,
|
||||
$before,
|
||||
null,
|
||||
);
|
||||
|
||||
return ApiResponse::success(['deleted' => true, 'id' => $id]);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@ namespace App\Http\Controllers\Api\V1\Admin\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AdminUser;
|
||||
use App\Support\ApiResponse;
|
||||
use App\Support\AdminApiList;
|
||||
use App\Support\AdminUserApiPresenter;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -13,8 +14,7 @@ final class AdminUserIndexController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): JsonResponse
|
||||
{
|
||||
$perPage = min(max((int) $request->integer('per_page', 25), 1), 100);
|
||||
$page = max((int) $request->integer('page', 1), 1);
|
||||
$p = AdminApiList::readPaging($request);
|
||||
$keyword = trim((string) $request->query('keyword', ''));
|
||||
|
||||
$q = AdminUser::query()
|
||||
@@ -29,33 +29,8 @@ final class AdminUserIndexController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
$paginator = $q->paginate($perPage, ['*'], 'page', $page);
|
||||
$paginator = $q->paginate($p['perPage'], ['*'], 'page', $p['page']);
|
||||
|
||||
return ApiResponse::success([
|
||||
'items' => collect($paginator->items())->map(
|
||||
fn (AdminUser $user): array => $this->row($user)
|
||||
)->all(),
|
||||
'meta' => [
|
||||
'current_page' => $paginator->currentPage(),
|
||||
'per_page' => $paginator->perPage(),
|
||||
'total' => $paginator->total(),
|
||||
'last_page' => $paginator->lastPage(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
private function row(AdminUser $user): array
|
||||
{
|
||||
return [
|
||||
'id' => (int) $user->id,
|
||||
'username' => $user->username,
|
||||
'nickname' => $user->name,
|
||||
'email' => $user->email,
|
||||
'status' => (int) $user->status,
|
||||
'roles' => $user->adminRoleSlugs(),
|
||||
'direct_permissions' => $user->directLegacyPermissionSlugs(),
|
||||
'effective_permissions' => $user->adminPermissionSlugs(),
|
||||
];
|
||||
return AdminApiList::json($paginator, fn (AdminUser $user): array => AdminUserApiPresenter::listItem($user));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ use App\Models\AdminUser;
|
||||
use App\Support\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
/** PUT /api/v1/admin/admin-users/{admin_user}/roles */
|
||||
@@ -22,29 +21,7 @@ final class AdminUserRoleSyncController extends Controller
|
||||
])->validate();
|
||||
|
||||
$slugs = array_values(array_unique($data['role_slugs']));
|
||||
$siteId = AdminUser::defaultAdminSiteId();
|
||||
|
||||
$roleIds = DB::table('admin_roles')
|
||||
->whereIn('slug', $slugs)
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
DB::transaction(function () use ($admin_user, $siteId, $roleIds): void {
|
||||
DB::table('admin_user_site_roles')
|
||||
->where('admin_user_id', $admin_user->id)
|
||||
->where('site_id', $siteId)
|
||||
->delete();
|
||||
|
||||
$now = now();
|
||||
foreach ($roleIds as $rid) {
|
||||
DB::table('admin_user_site_roles')->insert([
|
||||
'admin_user_id' => $admin_user->id,
|
||||
'site_id' => $siteId,
|
||||
'role_id' => (int) $rid,
|
||||
'granted_at' => $now,
|
||||
]);
|
||||
}
|
||||
});
|
||||
$admin_user->syncRoleSlugsForDefaultSite($slugs);
|
||||
|
||||
$admin_user->load('roles');
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1\Admin\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AdminUser;
|
||||
use App\Support\AdminUserApiPresenter;
|
||||
use App\Support\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/** GET /api/v1/admin/admin-users/{admin_user} */
|
||||
final class AdminUserShowController extends Controller
|
||||
{
|
||||
public function __invoke(AdminUser $admin_user): JsonResponse
|
||||
{
|
||||
$admin_user->load('roles');
|
||||
|
||||
return ApiResponse::success(AdminUserApiPresenter::listItem($admin_user));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1\Admin\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AdminUser;
|
||||
use App\Services\AuditLogger;
|
||||
use App\Support\AdminUserApiPresenter;
|
||||
use App\Support\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/** POST /api/v1/admin/admin-users */
|
||||
final class AdminUserStoreController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): JsonResponse
|
||||
{
|
||||
/** @var AdminUser $actor */
|
||||
$actor = $request->lotteryAdmin();
|
||||
|
||||
$payload = $request->all();
|
||||
if (isset($payload['username']) && is_string($payload['username'])) {
|
||||
$payload['username'] = Str::lower(trim($payload['username']));
|
||||
}
|
||||
if (array_key_exists('email', $payload) && $payload['email'] === '') {
|
||||
$payload['email'] = null;
|
||||
}
|
||||
|
||||
$data = validator($payload, [
|
||||
'username' => ['required', 'string', 'min:2', 'max:64', 'regex:/^[a-zA-Z0-9._-]+$/u', 'unique:admin_users,username'],
|
||||
'nickname' => ['required', 'string', 'max:128'],
|
||||
'email' => ['nullable', 'string', 'email', 'max:255'],
|
||||
'password' => ['required', 'string', 'min:8', 'max:256'],
|
||||
'status' => ['sometimes', 'integer', 'in:0,1'],
|
||||
'role_slugs' => ['required', 'array', 'min:1'],
|
||||
'role_slugs.*' => ['string', 'max:64', 'distinct', 'exists:admin_roles,slug'],
|
||||
])->validate();
|
||||
|
||||
$email = is_string($data['email'] ?? null) && trim($data['email']) !== ''
|
||||
? trim($data['email'])
|
||||
: null;
|
||||
|
||||
$roleSlugs = array_values(array_unique($data['role_slugs']));
|
||||
|
||||
$user = DB::transaction(function () use ($data, $email, $roleSlugs): AdminUser {
|
||||
$created = AdminUser::query()->create([
|
||||
'username' => $data['username'],
|
||||
'name' => $data['nickname'],
|
||||
'email' => $email,
|
||||
'password' => $data['password'],
|
||||
'status' => array_key_exists('status', $data) ? (int) $data['status'] : 0,
|
||||
]);
|
||||
$created->syncRoleSlugsForDefaultSite($roleSlugs);
|
||||
|
||||
return $created;
|
||||
});
|
||||
|
||||
$user->load('roles');
|
||||
|
||||
AuditLogger::recordForAdmin(
|
||||
$actor,
|
||||
$request,
|
||||
'system',
|
||||
'admin_user.create',
|
||||
'admin_user',
|
||||
(string) $user->getKey(),
|
||||
null,
|
||||
AdminUserApiPresenter::listItem($user),
|
||||
);
|
||||
|
||||
return ApiResponse::success(AdminUserApiPresenter::listItem($user));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1\Admin\User;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AdminUser;
|
||||
use App\Services\AuditLogger;
|
||||
use App\Support\AdminUserApiPresenter;
|
||||
use App\Support\ApiResponse;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
/** PUT /api/v1/admin/admin-users/{admin_user} */
|
||||
final class AdminUserUpdateController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request, AdminUser $admin_user): JsonResponse
|
||||
{
|
||||
/** @var AdminUser $actor */
|
||||
$actor = $request->lotteryAdmin();
|
||||
|
||||
$admin_user->load('roles');
|
||||
$before = AdminUserApiPresenter::listItem($admin_user);
|
||||
|
||||
$payload = $request->all();
|
||||
if (array_key_exists('email', $payload) && $payload['email'] === '') {
|
||||
$payload['email'] = null;
|
||||
}
|
||||
|
||||
/** @var array{nickname?:string,email?:?string,password?:?string,status?:int} $data */
|
||||
$data = validator($payload, [
|
||||
'nickname' => ['sometimes', 'string', 'max:128'],
|
||||
'email' => ['sometimes', 'nullable', 'string', 'email', 'max:255', Rule::unique('admin_users', 'email')->ignore($admin_user->id)],
|
||||
'password' => ['sometimes', 'nullable', 'string', 'min:8', 'max:256'],
|
||||
'status' => ['sometimes', 'integer', Rule::in([0, 1])],
|
||||
])->validate();
|
||||
|
||||
$updates = [];
|
||||
if (array_key_exists('nickname', $data)) {
|
||||
$updates['name'] = $data['nickname'];
|
||||
}
|
||||
if (array_key_exists('email', $data)) {
|
||||
$updates['email'] = ($data['email'] !== null && trim((string) $data['email']) !== '')
|
||||
? trim((string) $data['email'])
|
||||
: null;
|
||||
}
|
||||
if (array_key_exists('status', $data)) {
|
||||
$updates['status'] = (int) $data['status'];
|
||||
}
|
||||
if (array_key_exists('password', $data) && is_string($data['password']) && $data['password'] !== '') {
|
||||
$updates['password'] = $data['password'];
|
||||
}
|
||||
|
||||
if ($updates === []) {
|
||||
return ApiResponse::success($before);
|
||||
}
|
||||
|
||||
$admin_user->fill($updates);
|
||||
$admin_user->save();
|
||||
$admin_user->load('roles');
|
||||
|
||||
$after = AdminUserApiPresenter::listItem($admin_user);
|
||||
|
||||
AuditLogger::recordForAdmin(
|
||||
$actor,
|
||||
$request,
|
||||
'system',
|
||||
'admin_user.update',
|
||||
'admin_user',
|
||||
(string) $admin_user->getKey(),
|
||||
$before,
|
||||
$after,
|
||||
);
|
||||
|
||||
return ApiResponse::success($after);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user