You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

624 lines
19 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\API\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Lib\Rs;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class SysUserController extends Controller
{
/**
* 获取用户列表
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function list(Request $request)
{
// 获取查询参数
$username = $request->input('username', '');
$nickname = $request->input('nickname', '');
$status = $request->input('status', null);
$page = $request->input('page', 1);
$pageSize = $request->input('page_size', 10);
// 构建查询
$query = DB::table('sys_user')
->where('deleted', 0);
// 添加查询条件
if (!empty($username)) {
$query->where('username', 'like', '%' . $username . '%');
}
if (!empty($nickname)) {
$query->where('nickname', 'like', '%' . $nickname . '%');
}
if ($status !== null) {
$query->where('status', $status);
}
// 计算总数
$total = $query->count();
// 分页查询
$users = $query->orderBy('id', 'asc')
->skip(($page - 1) * $pageSize)
->take($pageSize)
->get();
// 获取用户角色信息
$users = $users->map(function($user) {
// 获取用户角色ID
$roleIds = DB::table('sys_user_role')
->where('user_id', $user->id)
->pluck('role_id')
->toArray();
// 获取角色名称
$roles = [];
if (!empty($roleIds)) {
$roles = DB::table('sys_role')
->whereIn('id', $roleIds)
->pluck('role_name')
->toArray();
}
// 添加角色信息到用户对象
$user->roles = $roles;
$user->role_names = implode(', ', $roles);
// 获取用户所属科室名称
$deptName = null;
if (!empty($user->dept_id)) {
$dept = DB::table('department')->where('id', $user->dept_id)->where('deleted', 0)->first();
if ($dept) {
$deptName = $dept->name;
}
}
$user->dept_name = $deptName;
return $user;
});
// 构造返回数据
$data = [
'list' => $users,
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_pages' => ceil($total / $pageSize)
];
return Rs::success($data);
}
/**
* 保存用户信息
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function Save(Request $request)
{
$data = $request->validate([
'id' => 'required|integer',
'username' => [
'required',
'string',
'max:50',
Rule::unique('sys_user', 'username')->ignore($request->id, 'id'),
],
'password' => 'sometimes|string|min:6',
'nickname' => 'required|string|max:50',
'email' => 'sometimes|string|email|max:100',
'phone' => 'sometimes|string|max:20',
'status' => 'required|integer|in:0,1',
'dept_id' => 'nullable|integer',
'his_code' => 'nullable|string|max:50',
]);
$conditions = ['id' => $data['id']];
$values = [
'username' => $data['username'],
'nickname' => $data['nickname'],
'email' => $data['email'] ?? '',
'phone' => $data['phone'] ?? '',
'status' => $data['status'],
'dept_id' => $data['dept_id'] ?? null,
'his_code' => $data['his_code'] ?? null,
];
// 如果提供了密码,进行哈希处理
if (isset($data['password']) && !empty($data['password'])) {
$values['password'] = bcrypt($data['password']);
}
$updated = DB::table('sys_user')->updateOrInsert($conditions, $values);
if ($updated) {
return Rs::success();
}
return Rs::error('操作失败');
}
/**
* 删除用户
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function Delete(Request $request)
{
$data = $request->validate([
'id' => 'required|integer',
]);
// 不能删除admin用户
$user = DB::table('sys_user')->where('id', $data['id'])->first();
if ($user && $user->username === 'admin') {
return Rs::error('不能删除超级管理员');
}
$deleted = DB::table('sys_user')->where('id', $data['id'])->update(['deleted' => 1]);
if ($deleted) {
// 同时删除用户角色关联
DB::table('sys_user_role')->where('user_id', $data['id'])->delete();
return Rs::success();
}
return Rs::error('删除失败');
}
/**
* 获取用户已绑定的角色
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function getUserRoles(Request $request)
{
$data = $request->validate([
'user_id' => 'required|integer',
]);
$roleIds = DB::table('sys_user_role')
->where('user_id', $data['user_id'])
->pluck('role_id')
->toArray();
return Rs::success($roleIds);
}
/**
* 绑定角色到用户
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function bindRoles(Request $request)
{
$data = $request->validate([
'user_id' => 'required|integer',
'role_ids' => 'required|array',
]);
try {
// 开启事务
DB::beginTransaction();
// 删除用户原有角色
DB::table('sys_user_role')->where('user_id', $data['user_id'])->delete();
// 添加新的角色关联
$insertData = [];
foreach ($data['role_ids'] as $roleId) {
$insertData[] = [
'user_id' => $data['user_id'],
'role_id' => $roleId,
'create_time' => now(),
];
}
if (!empty($insertData)) {
DB::table('sys_user_role')->insert($insertData);
}
// 提交事务
DB::commit();
return Rs::success();
} catch (\Exception $e) {
// 回滚事务
DB::rollBack();
return Rs::error('绑定角色失败:' . $e->getMessage());
}
}
/**
* 重置用户密码
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function resetPassword(Request $request)
{
$data = $request->validate([
'id' => 'required|integer',
]);
// 生成6位随机纯数字密码
$newPassword = mt_rand(100000, 999999);
// 哈希处理密码
$hashedPassword = bcrypt($newPassword);
// 更新用户密码
$updated = DB::table('sys_user')
->where('id', $data['id'])
->update(['password' => $hashedPassword]);
if ($updated) {
// 返回重置后的原始密码
return Rs::success($newPassword);
} else {
return Rs::error('密码重置失败');
}
}
public function getUserAuth(Request $request)
{
// 从请求属性中获取CheckToken中间件传递的用户信息
$user = $request->attributes->get('payload');
if (!$user) {
return Rs::error('用户信息获取失败');
}
// 获取用户ID
$userId = $user['user_id'] ?? null;
if (!$userId) {
return Rs::error('用户ID获取失败');
}
// 查询用户信息
$sysUser = DB::table('sys_user')
->where('id', $userId)
->where('deleted', 0)
->first();
if (!$sysUser) {
return Rs::error('用户不存在');
}
// 判断是否为超级管理员
$isSuperAdmin = $sysUser->username === 'admin';
// 查询权限
$permissions = [];
if ($isSuperAdmin) {
// 超级管理员获取所有启用的菜单权限
$permissions = DB::table('sys_permission')
->where('type', 1) // 1-菜单类型
->where('status', 1) // 1-启用
->where('deleted', 0) // 0-未删除
->orderBy('sort', 'asc')
->get();
} else {
// 其他用户根据角色获取权限,取角色权限的并集
// 获取用户角色相关的所有权限ID
$permissionIds = DB::table('sys_permission')
->join('sys_role_permission', 'sys_permission.id', '=', 'sys_role_permission.permission_id')
->join('sys_user_role', 'sys_role_permission.role_id', '=', 'sys_user_role.role_id')
->where('sys_user_role.user_id', $userId)
->where('sys_permission.type', 1) // 1-菜单类型
->where('sys_permission.status', 1) // 1-启用
->where('sys_permission.deleted', 0) // 0-未删除
->pluck('sys_permission.id')
->toArray();
if (!empty($permissionIds)) {
// 如果有子权限,获取其所有祖先权限
$allPermissionIds = $permissionIds;
// 获取所有相关权限详情
$permissionDetails = DB::table('sys_permission')
->whereIn('id', $permissionIds)
->get();
// 查找所有祖先权限
foreach ($permissionDetails as $permission) {
$parentId = $permission->parent_id;
while ($parentId != 0) {
$parentPermission = DB::table('sys_permission')
->where('id', $parentId)
->where('type', 1) // 1-菜单类型
->where('status', 1) // 1-启用
->where('deleted', 0) // 0-未删除
->first();
if ($parentPermission && !in_array($parentPermission->id, $allPermissionIds)) {
$allPermissionIds[] = $parentPermission->id;
$parentId = $parentPermission->parent_id;
} else {
break;
}
}
}
// 获取所有权限详情
$permissions = DB::table('sys_permission')
->whereIn('id', $allPermissionIds)
->where('type', 1) // 1-菜单类型
->where('status', 1) // 1-启用
->where('deleted', 0) // 0-未删除
->select('sys_permission.*')
->orderBy('sys_permission.sort', 'asc')
->get();
}
}
// 转换为树形结构
$treePermissions = $this->buildPermissionTree($permissions);
// 构造返回数据
$result = [
'user' => [
'user_id' => $sysUser->id,
'username' => $sysUser->username,
'nickname' => $sysUser->nickname,
'email' => $sysUser->email,
'phone' => $sysUser->phone,
'avatar' => $sysUser->avatar
? config('app.url') . '/storage/' . $sysUser->avatar
: config('app.url') . '/user_logo.jpg',
'is_super_admin' => $isSuperAdmin,
'dept_id'=>$sysUser->dept_id
],
'permissions' => $treePermissions
];
return Rs::success($result);
}
/**
* 构建权限树形结构
* @param array|object $permissions 权限列表
* @return array 树形结构权限
*/
private function buildPermissionTree($permissions)
{
$tree = [];
$permissionMap = [];
// 转换为数组并构建映射
$permissionArray = json_decode(json_encode($permissions), true);
// 第一步构建权限映射初始化children数组
foreach ($permissionArray as $permission) {
$permission['children'] = [];
$permissionMap[$permission['id']] = $permission;
}
// 第二步:构建树形结构
foreach ($permissionMap as $permission) {
if ($permission['parent_id'] == 0) {
// 根节点直接添加到tree
$tree[] = &$permissionMap[$permission['id']];
} else {
if (isset($permissionMap[$permission['parent_id']])) {
// 将子节点添加到父节点的children数组
$permissionMap[$permission['parent_id']]['children'][] = &$permissionMap[$permission['id']];
}
}
}
return $tree;
}
/**
* 获取当前用户信息
* @param Request $request
*/
public function getInfo(Request $request)
{
// 从请求属性中获取CheckToken中间件传递的用户信息
$user = $request->attributes->get('payload');
if (!$user) {
return Rs::error('用户信息获取失败');
}
// 获取用户ID
$userId = $user['user_id'] ?? null;
if (!$userId) {
return Rs::error('用户ID获取失败');
}
// 查询用户信息
$sysUser = DB::table('sys_user')
->where('id', $userId)
->where('deleted', 0)
->first();
if (!$sysUser) {
return Rs::error('用户不存在');
}
// 构造返回数据
$result = [
'id' => $sysUser->id,
'username' => $sysUser->username,
'nickname' => $sysUser->nickname,
'email' => $sysUser->email,
'phone' => $sysUser->phone,
'avatar' => $sysUser->avatar
? config('app.url') . '/storage/' . $sysUser->avatar
: config('app.url') . '/user_logo.jpg',
'created_at' => $sysUser->create_time
];
return Rs::success($result);
}
/**
* 更新用户信息
* @param Request $request
*/
public function updateInfo(Request $request)
{
// 从请求属性中获取CheckToken中间件传递的用户信息
$user = $request->attributes->get('payload');
if (!$user) {
return Rs::error('用户信息获取失败');
}
// 获取用户ID
$userId = $user['user_id'] ?? null;
if (!$userId) {
return Rs::error('用户ID获取失败');
}
// 验证请求数据
$data = $request->validate([
'nickname' => 'required|string|max:50',
'email' => 'sometimes|string|email|max:100',
'phone' => 'sometimes|string|max:20',
]);
// 更新用户信息
$updated = DB::table('sys_user')
->where('id', $userId)
->where('deleted', 0)
->update([
'nickname' => $data['nickname'],
'email' => $data['email'] ?? '',
'phone' => $data['phone'] ?? '',
'update_time' => now()
]);
if ($updated) {
return Rs::success();
} else {
return Rs::error('用户信息更新失败');
}
}
/**
* 更新用户密码
* @param Request $request
*/
public function updatePassword(Request $request)
{
// 从请求属性中获取CheckToken中间件传递的用户信息
$user = $request->attributes->get('payload');
if (!$user) {
return Rs::error('用户信息获取失败');
}
// 获取用户ID
$userId = $user['user_id'] ?? null;
if (!$userId) {
return Rs::error('用户ID获取失败');
}
// 验证请求数据
$data = $request->validate([
'oldPassword' => 'required|string',
'newPassword' => 'required|string|min:6',
]);
// 查询用户信息
$sysUser = DB::table('sys_user')
->where('id', $userId)
->where('deleted', 0)
->first();
if (!$sysUser) {
return Rs::error('用户不存在');
}
// 验证旧密码
if (!password_verify($data['oldPassword'], $sysUser->password)) {
return Rs::error('原密码错误');
}
// 哈希处理新密码
$hashedPassword = bcrypt($data['newPassword']);
// 更新用户密码
$updated = DB::table('sys_user')
->where('id', $userId)
->update(['password' => $hashedPassword]);
if ($updated) {
return Rs::success();
} else {
return Rs::error('密码更新失败');
}
}
/**
* 上传用户头像
* @param Request $request
* @return IlluminateHttpJsonResponse
*/
public function uploadAvatar(Request $request)
{
// 从请求属性中获取CheckToken中间件传递的用户信息
$user = $request->attributes->get('payload');
if (!$user) {
return Rs::error('用户信息获取失败');
}
// 获取用户ID
$userId = $user['user_id'] ?? null;
if (!$userId) {
return Rs::error('用户ID获取失败');
}
// 验证请求数据
if (!$request->hasFile('avatar')) {
return Rs::error('请选择要上传的头像');
}
$file = $request->file('avatar');
// 验证文件类型
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array($file->getMimeType(), $allowedTypes)) {
return Rs::error('只允许上传JPG/PNG格式的图片');
}
// 验证文件大小2MB
$maxSize = 2 * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return Rs::error('图片大小不能超过2MB');
}
// 生成唯一文件名
$filename = 'avatar_' . $userId . '_' . time() . '.' . $file->getClientOriginalExtension();
$path = $file->storeAs('avatars', $filename, 'public');
// 更新用户头像
$updated = DB::table('sys_user')
->where('id', $userId)
->update(['avatar' => $path]);
if ($updated) {
// 构造完整的头像URL
$avatarUrl = asset('storage/' . $path);
return Rs::success(['avatar' => $avatarUrl]);
} else {
return Rs::error('头像上传失败');
}
}
}