|
|
<?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('头像上传失败');
|
|
|
}
|
|
|
}
|
|
|
}
|