You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.5 KiB
134 lines
4.5 KiB
|
3 months ago
|
<?php
|
||
|
|
|
||
|
|
namespace App\Http\Controllers\Api\Admin;
|
||
|
|
|
||
|
|
use App\Http\Controllers\Controller;
|
||
|
|
use App\Models\AdminUser;
|
||
|
|
use Illuminate\Http\JsonResponse;
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\Support\Facades\Hash;
|
||
|
|
use Illuminate\Validation\Rule;
|
||
|
|
use Illuminate\Validation\ValidationException;
|
||
|
|
|
||
|
|
class AdminUserController extends Controller
|
||
|
|
{
|
||
|
|
public function index(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$data = $request->validate([
|
||
|
|
'page' => ['sometimes', 'integer', 'min:1'],
|
||
|
|
'per_page' => ['sometimes', 'integer', 'min:1', 'max:100'],
|
||
|
|
'keyword' => ['sometimes', 'nullable', 'string', 'max:100'],
|
||
|
|
]);
|
||
|
|
|
||
|
|
$query = AdminUser::query()->orderByDesc('id');
|
||
|
|
$keyword = trim((string) ($data['keyword'] ?? ''));
|
||
|
|
if ($keyword !== '') {
|
||
|
|
$like = '%'.str_replace(['%', '_'], ['\\%', '\\_'], $keyword).'%';
|
||
|
|
$query->where(function ($q) use ($like): void {
|
||
|
|
$q->where('username', 'like', $like)
|
||
|
|
->orWhere('name', 'like', $like)
|
||
|
|
->orWhere('mobile', 'like', $like);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
$perPage = min((int) ($data['per_page'] ?? 15), 100);
|
||
|
|
$paginator = $query->paginate($perPage);
|
||
|
|
$paginator->getCollection()->transform(fn (AdminUser $user) => $this->toRow($user));
|
||
|
|
|
||
|
|
return response()->json($paginator);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function store(Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
$data = $this->validatedPayload($request);
|
||
|
|
|
||
|
|
if (AdminUser::query()->where('username', $data['username'])->exists()) {
|
||
|
|
throw ValidationException::withMessages(['username' => ['该账号已存在']]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$user = AdminUser::query()->create([
|
||
|
|
'username' => $data['username'],
|
||
|
|
'password_hash' => $data['password'],
|
||
|
|
'name' => $data['name'],
|
||
|
|
'mobile' => $data['mobile'] ?? null,
|
||
|
|
'status' => $data['status'] ?? 'active',
|
||
|
|
]);
|
||
|
|
|
||
|
|
return response()->json($this->toRow($user), 201);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function update(Request $request, AdminUser $adminUser): JsonResponse
|
||
|
|
{
|
||
|
|
$data = $this->validatedPayload($request, $adminUser->id);
|
||
|
|
|
||
|
|
if (AdminUser::query()->where('username', $data['username'])->where('id', '!=', $adminUser->id)->exists()) {
|
||
|
|
throw ValidationException::withMessages(['username' => ['该账号已存在']]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$adminUser->fill([
|
||
|
|
'username' => $data['username'],
|
||
|
|
'name' => $data['name'],
|
||
|
|
'mobile' => $data['mobile'] ?? null,
|
||
|
|
'status' => $data['status'] ?? $adminUser->status,
|
||
|
|
]);
|
||
|
|
|
||
|
|
if (! empty($data['password'])) {
|
||
|
|
$adminUser->password_hash = $data['password'];
|
||
|
|
}
|
||
|
|
|
||
|
|
$adminUser->save();
|
||
|
|
|
||
|
|
return response()->json($this->toRow($adminUser->fresh()));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function destroy(AdminUser $adminUser, Request $request): JsonResponse
|
||
|
|
{
|
||
|
|
/** @var AdminUser $current */
|
||
|
|
$current = $request->user();
|
||
|
|
if ((int) $current->id === (int) $adminUser->id) {
|
||
|
|
throw ValidationException::withMessages(['admin_user' => ['不能删除当前登录账号']]);
|
||
|
|
}
|
||
|
|
|
||
|
|
$adminUser->delete();
|
||
|
|
|
||
|
|
return response()->json(['message' => 'deleted']);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return array<string, mixed>
|
||
|
|
*/
|
||
|
|
private function validatedPayload(Request $request, ?int $ignoreId = null): array
|
||
|
|
{
|
||
|
|
return $request->validate([
|
||
|
|
'username' => [
|
||
|
|
'required',
|
||
|
|
'string',
|
||
|
|
'max:64',
|
||
|
|
'regex:/^[A-Za-z0-9._-]+$/',
|
||
|
|
Rule::unique('admin_users', 'username')->ignore($ignoreId),
|
||
|
|
],
|
||
|
|
'name' => ['required', 'string', 'max:64'],
|
||
|
|
'mobile' => ['nullable', 'string', 'max:20'],
|
||
|
|
'password' => [$ignoreId ? 'nullable' : 'required', 'string', 'min:6', 'max:255'],
|
||
|
|
'status' => ['sometimes', 'string', Rule::in(['active', 'disabled'])],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return array<string, mixed>
|
||
|
|
*/
|
||
|
|
private function toRow(AdminUser $user): array
|
||
|
|
{
|
||
|
|
return [
|
||
|
|
'id' => $user->id,
|
||
|
|
'username' => $user->username,
|
||
|
|
'name' => $user->name,
|
||
|
|
'mobile' => $user->mobile,
|
||
|
|
'status' => $user->status,
|
||
|
|
'last_login_at' => $user->last_login_at?->toIso8601String(),
|
||
|
|
'created_at' => $user->created_at?->toIso8601String(),
|
||
|
|
'password_set' => $user->usesPassword(),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
}
|