406 lines
12 KiB
PHP
406 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Role;
|
|
use App\Models\User;
|
|
use App\Models\UserDevice;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
/**
|
|
* 用户列表
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$query = User::query();
|
|
|
|
// 关键词搜索
|
|
if ($request->filled('keyword')) {
|
|
$keyword = $request->keyword;
|
|
$query->where(function ($q) use ($keyword) {
|
|
$q->where('name', 'like', "%{$keyword}%")
|
|
->orWhere('email', 'like', "%{$keyword}%")
|
|
->orWhere('phone', 'like', "%{$keyword}%");
|
|
});
|
|
}
|
|
|
|
// 状态筛选
|
|
if ($request->filled('status')) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
// 角色筛选
|
|
if ($request->filled('roleCode')) {
|
|
$role = Role::findBySlug($request->roleCode);
|
|
if ($role) {
|
|
$query->whereHas('roles', function ($q) use ($role) {
|
|
$q->where('roles.id', $role->id);
|
|
});
|
|
}
|
|
}
|
|
|
|
$perPage = $request->input('pageSize', 20);
|
|
$users = $query->with('roles')->orderBy('id', 'desc')->paginate($perPage);
|
|
|
|
$list = $users->map(function ($user) {
|
|
$roles = $user->roles;
|
|
return [
|
|
'id' => $user->id,
|
|
'username' => $user->email,
|
|
'name' => $user->name,
|
|
'phone' => $user->phone,
|
|
'roleCode' => $roles->first()?->slug,
|
|
'roleName' => $roles->first()?->name,
|
|
'roles' => $roles->map(fn($r) => ['id' => $r->id, 'name' => $r->name, 'slug' => $r->slug])->toArray(),
|
|
'warehouseIds' => $user->warehouse_ids ?? [],
|
|
'status' => $user->status,
|
|
'lastLoginTime' => $user->last_login_at?->format('Y-m-d H:i:s'),
|
|
'createdAt' => $user->created_at?->format('Y-m-d H:i:s'),
|
|
'isSuperAdmin' => $roles->contains('slug', 'super_admin'),
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => [
|
|
'list' => $list,
|
|
'total' => $users->total(),
|
|
'current_page' => $users->currentPage(),
|
|
'last_page' => $users->lastPage(),
|
|
],
|
|
'message' => 'success',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 创建用户
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$validator = Validator::make($request->all(), [
|
|
'username' => 'required_without:phone|email|unique:users,email',
|
|
'phone' => 'required_without:username|regex:/^1[3-9]\d{9}$/|unique:users,phone',
|
|
'name' => 'required|string|max:255',
|
|
'password' => 'required|string|min:8',
|
|
'roleCode' => 'required|string|exists:roles,slug',
|
|
'warehouseIds' => 'array',
|
|
'warehouseIds.*' => 'integer',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json(['code' => 422, 'message' => '验证失败', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
$user = User::create([
|
|
'email' => $request->username,
|
|
'phone' => $request->phone,
|
|
'name' => $request->name,
|
|
'password' => Hash::make($request->password),
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
// 分配角色
|
|
$role = Role::findBySlug($request->roleCode);
|
|
if ($role) {
|
|
$user->roles()->attach($role->id);
|
|
}
|
|
|
|
// 仓库权限
|
|
if ($request->warehouseIds) {
|
|
$user->warehouse_ids = $request->warehouseIds;
|
|
$user->save();
|
|
}
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $user,
|
|
'message' => '用户创建成功',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 更新用户
|
|
*/
|
|
public function update(Request $request, string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'name' => 'sometimes|string|max:255',
|
|
'phone' => ['sometimes', 'regex:/^1[3-9]\d{9}$/', 'unique:users,phone,' . $id],
|
|
'roleCode' => 'sometimes|string|exists:roles,slug',
|
|
'warehouseIds' => 'array',
|
|
'warehouseIds.*' => 'integer',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json(['code' => 422, 'message' => '验证失败', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
$updateData = $request->only(['name', 'phone']);
|
|
if (!empty($updateData)) {
|
|
$user->update($updateData);
|
|
}
|
|
|
|
// 更新角色
|
|
if ($request->filled('roleCode')) {
|
|
$role = Role::findBySlug($request->roleCode);
|
|
$user->roles()->sync([$role?->id]);
|
|
}
|
|
|
|
// 更新仓库权限
|
|
if ($request->has('warehouseIds')) {
|
|
$user->warehouse_ids = $request->warehouseIds;
|
|
$user->save();
|
|
}
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $user,
|
|
'message' => '更新成功',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 删除用户
|
|
*/
|
|
public function destroy(string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
if ($user->roles->contains('slug', 'super_admin')) {
|
|
return response()->json(['code' => 403, 'message' => '不能删除超级管理员'], 403);
|
|
}
|
|
|
|
$user->roles()->detach();
|
|
$user->delete();
|
|
|
|
return response()->json(['code' => 200, 'message' => '删除成功']);
|
|
}
|
|
|
|
/**
|
|
* 禁用用户
|
|
*/
|
|
public function disable(string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
if ($user->roles->contains('slug', 'super_admin')) {
|
|
return response()->json(['code' => 403, 'message' => '不能禁用超级管理员'], 403);
|
|
}
|
|
|
|
$user->disable();
|
|
|
|
return response()->json(['code' => 200, 'message' => '已禁用']);
|
|
}
|
|
|
|
/**
|
|
* 启用用户
|
|
*/
|
|
public function enable(string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$user->unlock();
|
|
$user->update(['status' => 'active']);
|
|
|
|
return response()->json(['code' => 200, 'message' => '已启用']);
|
|
}
|
|
|
|
/**
|
|
* 重置密码
|
|
*/
|
|
public function resetPassword(string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$newPassword = substr(md5(uniqid()), 0, 8) . 'A1';
|
|
$user->password = Hash::make($newPassword);
|
|
$user->status = 'pending';
|
|
$user->save();
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => ['password' => $newPassword],
|
|
'message' => '密码已重置为: ' . $newPassword,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 设置用户权限
|
|
*/
|
|
public function setPermissions(Request $request, string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'permissions' => 'array',
|
|
'permissions.*' => 'string',
|
|
'warehouseIds' => 'array',
|
|
'warehouseIds.*' => 'integer',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json(['code' => 422, 'message' => '验证失败', 'errors' => $validator->errors()], 422);
|
|
}
|
|
|
|
// 更新仓库权限
|
|
$user->warehouse_ids = $request->warehouseIds ?? [];
|
|
$user->save();
|
|
|
|
return response()->json(['code' => 200, 'message' => '权限已更新']);
|
|
}
|
|
|
|
/**
|
|
* 获取用户权限
|
|
*/
|
|
public function getPermissions(string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$permissions = $user->roles->flatMap->permissions->pluck('slug')->unique()->toArray();
|
|
$warehouseIds = $user->warehouse_ids ?? [];
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => [
|
|
'permissions' => $permissions,
|
|
'warehouseIds' => $warehouseIds,
|
|
],
|
|
'message' => 'success',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 获取用户登录日志
|
|
*/
|
|
public function loginLogs(Request $request, string $id)
|
|
{
|
|
$user = User::find($id);
|
|
if (!$user) {
|
|
return response()->json(['code' => 404, 'message' => '用户不存在'], 404);
|
|
}
|
|
|
|
$logs = \App\Models\LoginLog::where('user_id', $user->id)
|
|
->orderBy('created_at', 'desc')
|
|
->limit(50)
|
|
->get()
|
|
->map(fn($log) => [
|
|
'loginTime' => $log->created_at?->format('Y-m-d H:i:s'),
|
|
'deviceType' => $log->device_id ?? 'Unknown',
|
|
'deviceId' => $log->device_id,
|
|
'ip' => $log->ip,
|
|
'location' => $log->ip ?? 'Unknown',
|
|
'status' => $log->status,
|
|
]);
|
|
|
|
return response()->json([
|
|
'code' => 200,
|
|
'data' => $logs,
|
|
'message' => 'success',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 授信设备列表
|
|
*/
|
|
public function devices(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
$devices = UserDevice::where('user_id', $user->id)
|
|
->orderBy('last_login_at', 'desc')
|
|
->get()
|
|
->map(fn($d) => [
|
|
'id' => $d->id,
|
|
'deviceName' => $d->device_name,
|
|
'deviceType' => $d->device_type,
|
|
'os' => $d->os,
|
|
'browser' => $d->browser,
|
|
'ip' => $d->ip,
|
|
'location' => $d->location,
|
|
'firstLoginAt' => $d->first_login_at?->format('Y-m-d H:i:s'),
|
|
'lastLoginAt' => $d->last_login_at?->format('Y-m-d H:i:s'),
|
|
'isTrusted' => $d->is_trusted,
|
|
'trustedAt' => $d->trusted_at?->format('Y-m-d H:i:s'),
|
|
]);
|
|
|
|
return response()->json(['code' => 200, 'data' => $devices, 'message' => 'success']);
|
|
}
|
|
|
|
/**
|
|
* 取消设备授信
|
|
*/
|
|
public function revokeDevice(Request $request, string $deviceId)
|
|
{
|
|
$user = $request->user();
|
|
$device = UserDevice::where('id', $deviceId)->where('user_id', $user->id)->first();
|
|
|
|
if (!$device) {
|
|
return response()->json(['code' => 404, 'message' => '设备不存在'], 404);
|
|
}
|
|
|
|
$device->revoke();
|
|
|
|
return response()->json(['code' => 200, 'message' => '已取消授信']);
|
|
}
|
|
|
|
/**
|
|
* 批准设备申请
|
|
*/
|
|
public function approveDevice(Request $request, string $deviceId)
|
|
{
|
|
$user = $request->user();
|
|
$device = UserDevice::where('id', $deviceId)->where('user_id', $user->id)->first();
|
|
|
|
if (!$device) {
|
|
return response()->json(['code' => 404, 'message' => '设备不存在'], 404);
|
|
}
|
|
|
|
$device->trust();
|
|
|
|
return response()->json(['code' => 200, 'message' => '已授信']);
|
|
}
|
|
|
|
/**
|
|
* 拒绝设备申请
|
|
*/
|
|
public function rejectDevice(Request $request, string $deviceId)
|
|
{
|
|
$user = $request->user();
|
|
$device = UserDevice::where('id', $deviceId)->where('user_id', $user->id)->first();
|
|
|
|
if (!$device) {
|
|
return response()->json(['code' => 404, 'message' => '设备不存在'], 404);
|
|
}
|
|
|
|
$device->revoke();
|
|
|
|
return response()->json(['code' => 200, 'message' => '已拒绝']);
|
|
}
|
|
}
|