Skip to content

用户管理

1. 功能概述

用户管理模块是后台管理的重要功能,主要负责系统用户的管理和操作日志的记录,包含以下主要功能:

  • 用户管理:用户的增删改查、锁定/解锁、属性修改
  • 操作日志管理:记录用户操作行为、查询操作日志

1.1 用户管理功能流程

mermaid
flowchart TD
    A[用户管理] --> B[用户列表]
    A --> C[用户详情]
    A --> D[新增用户]
    A --> E[编辑用户]
    A --> F[锁定/解锁用户]
    A --> G[删除用户]
    A --> H[修改用户属性]
    A --> I[操作日志管理]

    subgraph 用户操作
        B --> B1[分页查询]
        B --> B2[条件筛选]
        B --> B3[排序功能]
        C --> C1[基本信息]
        C --> C2[角色权限]
        C --> C3[部门岗位]
        D --> D1[数据验证]
        D --> D2[创建账号]
        D --> D3[分配角色]
        E --> E1[修改信息]
        E --> E2[更新权限]
        E --> E3[调整部门]
        F --> F1[锁定账号]
        F --> F2[解锁账号]
        G --> G1[软删除]
        G --> G2[清理数据]
        H --> H1[修改属性]
        H --> H2[验证合法性]
    end

    subgraph 日志管理
        I --> I1[日志列表]
        I --> I2[日志详情]
        I --> I3[日志删除]
        I1 --> I11[分页查询]
        I1 --> I12[条件筛选]
        I2 --> I21[操作信息]
        I2 --> I22[数据变化]
        I2 --> I23[时间IP]
    end

2. 路由配置

用户管理相关的路由配置位于 backend/app/adminapi/route/user.php 文件中,主要包含以下路由组:

2.1 用户管理

  • GET /user:用户列表
  • GET /user/user_all:全部用户列表
  • GET /user/:uid:用户详情
  • POST /user:新增用户
  • PUT /user/lock/:uid:用户锁定
  • PUT /user/unlock/:uid:用户解锁
  • PUT /user/:uid:编辑用户
  • PUT /user/:uid/:field:修改用户属性
  • DELETE /user/:uid:删除用户

2.2 操作日志管理

  • GET /user/userlog:操作日志列表
  • GET /user/userlog/:id:操作日志详情
  • DELETE /user/userlog/destroy:删除操作日志

3. 核心功能实现

3.1 用户管理

3.1.1 用户列表

  • 支持分页查询
  • 支持条件筛选(用户名、角色、状态等)
  • 支持排序功能

3.1.2 实现逻辑

php
// 用户列表示例
public function lists() {
    $data = $this->request->params([
        ['username', ''],
        ['realname', ''],
        ['role', ''],
        ['create_time', []],
    ]);

    $list = (new UserService())->getPage($data);
    return success($list);
}

// 服务层实现
public function getPage(array $where) {
    $field = 'uid,username,head_img,real_name,last_ip,last_time,login_count,status, role_ids, is_admin, dept_id, position_id';
    $search = [
        'username' => $where[ 'username' ],
        'real_name' => $where[ 'realname' ],
        'create_time' => $where[ 'create_time' ]
    ];
    if (!empty($where[ 'role' ])) {
        $search[ 'role_ids' ] = $where[ 'role' ];
    }
    $search_model = ( new SysUser() )->withSearch([ 'username', 'realname', 'create_time', 'role_ids' ], $search)->with(['dept', 'position'])->field($field)->order('uid desc')->append([ 'status_name' ]);
    return $this->pageQuery($search_model, function ($item, $key) {
        $role_ids = $item[ 'role_ids' ] ?? [];
        $item->role_data = $this->getRoleByUserRoleIds($role_ids);
    });
}

3.1.3 用户详情

  • 获取用户基本信息
  • 获取用户所属角色和权限
  • 获取用户部门和岗位信息

3.1.4 实现逻辑

php
// 用户详情示例
public function info($uid) {
    return success((new UserService())->getInfo($uid));
}

// 服务层实现
public function getInfo(int $uid) {
    $where = array(
        [ 'uid', '=', $uid ],
    );
    $field = 'uid, username, head_img, real_name, last_ip, last_time, create_time, login_count, status, delete_time, update_time, role_ids, is_admin, dept_id, position_id';
    $user = ( new SysUser() )->where($where)->with(['dept', 'position'])->field($field)->findOrEmpty();
    if ($user->isEmpty())
        return [];

    if (!empty($user?->userrole)) {
        $user->userrole->appendData([ 'role_array' => $this->getRoleByUserRoleIds($user->role_ids ?? []) ]);
    }

    return $user->append([ 'status_name' ])->toArray();
}

3.1.5 用户新增

  • 验证用户输入数据
  • 创建用户账号
  • 分配角色和权限
  • 设置初始密码

3.1.6 实现逻辑

php
// 添加用户示例
public function add() {
    $data = $this->request->params([
        ['username', ''],
        ['password', ''],
        ['mobile', ''],
        ['real_name', ''],
        ['head_img', ''],
        ['status', UserDict::ON],
        ['role_ids', []],
        ['dept_id', 0],
        ['position_id', 0]
    ]);
    (new UserService())->add($data);
    return success();
}

// 服务层实现
public function add(array $data) {
    $user_data = [
        'username' => $data[ 'username' ],
        'head_img' => $data[ 'head_img' ],
        'status' => $data[ 'status' ],
        'real_name' => $data[ 'real_name' ],
        'password' => create_password($data[ 'password' ]),
        'is_admin' => $data[ 'is_admin' ]??0,
        'role_ids' => $data[ 'role_ids' ],
        'dept_id' => $data[ 'dept_id' ] ?? 0,
        'position_id' => $data[ 'position_id' ] ?? 0,
    ];
    $user = ( new SysUser() )->create($user_data);
    return $user?->uid;
}

3.1.7 用户编辑

  • 修改用户基本信息
  • 更新用户角色和权限
  • 调整用户部门和岗位

3.1.8 实现逻辑

php
// 编辑用户示例
public function edit($uid) {
    $data = $this->request->params([
        ['password', ''],
        ['mobile', ''],
        ['real_name', ''],
        ['head_img', ''],
        ['dept_id', 0],
        ['position_id', 0]
    ]);
    (new UserService())->edit($uid, $data);
    return success();
}

// 服务层实现
public function edit(int $uid, array $data) {
    $user = $this->find($uid);
    $user_data = [];
    $is_off_status = false;
    if (isset($data[ 'status' ])) {
        $user_data[ 'status' ] = $data[ 'status' ];
        if ($data[ 'status' ] == UserDict::OFF)
            $is_off_status = true;
    }
    if (isset($data[ 'head_img' ])) {
        $user_data[ 'head_img' ] = $data[ 'head_img' ];
    }
    if (isset($data[ 'real_name' ])) {
        $user_data[ 'real_name' ] = $data[ 'real_name' ];
    }

    $password = $data[ 'password' ] ?? '';
    $is_change_password = false;
    if (!empty($password) && !check_password($password, $user->password)) {
        $user_data[ 'password' ] = create_password($password);
        $is_change_password = true;
    }

    if (isset($data[ 'role_ids' ])) {
        $user_data[ 'role_ids' ] = $data[ 'role_ids' ];
    }

    if (isset($data[ 'dept_id' ])) {
        $user_data[ 'dept_id' ] = $data[ 'dept_id' ];
    }

    if (isset($data[ 'position_id' ])) {
        $user_data[ 'position_id' ] = $data[ 'position_id' ];
    }

    if (empty($user_data))
        return true;
    //更新用户信息
    $user->save($user_data);
    //更新权限  禁用用户  修改密码 都会清理token
    if ($is_off_status || $is_change_password) {
        LoginService::clearToken($uid);
    }
    //清除用户缓存
    $cache_name = 'user_role_' . $uid;
    Cache::delete($cache_name);
    return true;
}

3.1.9 用户锁定/解锁

  • 锁定用户账号,禁止登录
  • 解锁用户账号,恢复登录权限
  • 记录锁定/解锁操作原因

3.1.10 实现逻辑

php
// 锁定用户示例
public function lock($uid) {
    (new UserService())->lock($uid);
    return success();
}

// 解锁用户示例
public function unlock($uid) {
    (new UserService())->unlock($uid);
    return success();
}

// 服务层实现
public function lock(int $uid) {
    return $this->edit($uid, [ 'status' => UserDict::OFF ]);
}

public function unlock(int $uid) {
    return $this->edit($uid, [ 'status' => UserDict::ON ]);
}

3.1.11 用户删除

  • 软删除用户账号
  • 清理用户相关数据
  • 记录删除操作日志

3.1.12 实现逻辑

php
// 删除用户示例
public function del($uid) {
    (new UserService())->del($uid);
    return success("DELETE_SUCCESS");
}

// 服务层实现
public function del(int $uid) {
    $where = [
        [ 'uid', '=', $uid ]
    ];
    $user = ( new SysUser() )->where($where)->findOrEmpty();
    if ($user->isEmpty()) throw new AdminException('USER_NOT_EXIST');
    if ($user->is_admin) throw new AdminException("SUPER_ADMIN_NOT_ALLOW_DEL");
    $user->delete();
    LoginService::clearToken($uid);
    Cache::delete('user_role_' . $uid);
    return true;
}

3.1.13 用户属性修改

  • 单独修改用户的某个属性
  • 验证属性值的合法性
  • 记录属性修改日志

3.1.14 实现逻辑

php
// 修改用户属性示例
public function modify($uid, $field) {
    $data = $this->request->param('value');
    (new UserService())->modify($uid, $field, $data);
    return success();
}

// 服务层实现
public function modify(int $uid, string $field, $data) {
    $field_name = match ( $field ) {
        'password' => 'password',
        'real_name' => 'real_name',
        'head_img' => 'head_img',
    };
    return $this->edit($uid, [ $field_name => $data ]);
}

3.2 操作日志管理

3.2.1 操作日志列表

  • 支持分页查询
  • 支持按用户、操作类型、时间等条件筛选
  • 支持排序功能

3.2.2 实现逻辑

php
// 操作日志列表示例
public function lists() {
    $params = $this->request->params([
        [ 'page', 1 ],
        [ 'limit', 10 ],
        [ 'username', '' ],
        [ 'action', '' ],
        [ 'create_time', [] ],
    ]);
    $userLogModel = new SysUserLog();
    $list = $userLogModel->where(function($query) use ($params) {
        if (!empty($params['username'])) {
            $query->where('username', 'like', '%' . $params['username'] . '%');
        }
        if (!empty($params['action'])) {
            $query->where('action', $params['action']);
        }
        if (!empty($params['create_time'])) {
            $query->whereBetween('create_time', $params['create_time']);
        }
    })->paginate([
        'page' => $params['page'],
        'list_rows' => $params['limit']
    ]);
    return success($list);
}

3.2.3 操作日志详情

  • 获取操作的详细信息
  • 查看操作前后的数据变化
  • 了解操作的具体时间和IP地址

3.2.4 实现逻辑

php
// 操作日志详情示例
public function info($id) {
    $userLogModel = new SysUserLog();
    $info = $userLogModel->find($id);
    return success($info);
}

3.2.5 操作日志删除

  • 批量删除操作日志
  • 清理过期的操作日志
  • 保持系统性能

3.2.6 实现逻辑

php
// 删除操作日志示例
public function destroy() {
    $ids = $this->request->param('ids');
    $userLogModel = new SysUserLog();
    $result = $userLogModel->whereIn('id', $ids)->delete();
    return success($result);
}

4. 数据模型

4.1 用户模型

  • 表名:sys_user
  • 主要字段:
    • uid:用户ID
    • username:用户名
    • password:密码(加密存储)
    • nickname:昵称
    • avatar:头像
    • email:邮箱
    • phone:手机号
    • role_id:角色ID
    • dept_id:部门ID
    • position_id:岗位ID
    • status:状态(0:禁用,1:启用)
    • login_time:最后登录时间
    • login_ip:最后登录IP
    • create_time:创建时间
    • update_time:更新时间

4.2 操作日志模型

  • 表名:sys_user_log
  • 主要字段:
    • id:日志ID
    • uid:用户ID
    • username:用户名
    • action:操作类型
    • content:操作内容
    • ip:操作IP
    • create_time:操作时间

5. 开发规范

5.1 代码结构

  • 控制器:位于 backend/app/adminapi/controller/user/ 目录
  • 模型:位于 backend/app/model/sys/ 目录(SysUser、SysUserLog)
  • 验证器:位于 backend/app/validate/sys/ 目录
  • 字典:位于 backend/app/dict/sys/ 目录
  • 服务层:位于 backend/app/service/admin/user/ 目录

5.2 权限控制

  • 使用中间件 AdminCheckRole 进行权限验证
  • 基于角色的权限控制
  • 不同角色拥有不同的用户管理权限

5.3 数据验证

  • 使用 validate 进行数据验证
  • 确保用户输入的合法性
  • 防止恶意输入和SQL注入

5.4 密码安全

  • 使用bcrypt等安全算法加密存储密码
  • 密码强度验证
  • 密码修改记录

5.5 日志记录

  • 使用中间件 AdminLog 记录操作日志
  • 记录用户的关键操作
  • 便于审计和追溯

6. 注意事项

  1. 权限管理:用户管理模块涉及敏感操作,需要严格控制权限
  2. 数据安全:用户密码必须加密存储,敏感信息需要保护
  3. 操作日志:重要操作必须记录详细的操作日志
  4. 性能优化:用户列表查询需要考虑性能,特别是在用户数量较多时
  5. 用户体验:操作流程要简洁明了,错误提示要友好

7. 开发流程

  1. 需求分析:明确用户管理的具体需求
  2. 功能设计:设计用户管理的功能模块和流程
  3. 数据库设计:设计用户和操作日志的数据表结构
  4. 代码实现:按照编码规范实现功能
  5. 测试验证:测试用户管理的各项功能
  6. 部署上线:将用户管理功能部署到生产环境

8. 示例代码

8.1 用户控制器示例

php
<?php
namespace app\adminapi\controller\user;

use app\dict\sys\UserDict;
use app\service\admin\user\UserService;
use core\base\BaseAdminController;
use think\Response;

/**
 * 用户管理
 */
class User extends BaseAdminController {
    /**
     * 用户列表
     * @description 用户列表
     * @return Response
     */
    public function lists() {
        $data = $this->request->params([
            ['username', ''],
            ['realname', ''],
            ['role', ''],
            ['create_time', []],
        ]);

        $list = (new UserService())->getPage($data);
        return success($list);
    }

    /**
     * 用户详情
     * @description 用户详情
     * @param $uid
     * @return Response
     */
    public function info($uid) {
        return success((new UserService())->getInfo($uid));
    }

    /**
     * 添加用户
     * @description 添加用户
     * @return Response
     * @throws \Exception
     */
    public function add() {
        $data = $this->request->params([
            ['username', ''],
            ['password', ''],
            ['mobile', ''],
            ['real_name', ''],
            ['head_img', ''],
            ['status', UserDict::ON],
            ['role_ids', []],
            ['dept_id', 0],
            ['position_id', 0]
        ]);
        (new UserService())->add($data);
        return success();
    }

    /**
     * 编辑用户
     * @description 编辑用户
     * @return Response
     * @throws \Exception
     */
    public function edit($uid) {
        $data = $this->request->params([
            ['password', ''],
            ['mobile', ''],
            ['real_name', ''],
            ['head_img', ''],
            ['dept_id', 0],
            ['position_id', 0]
        ]);
        (new UserService())->edit($uid, $data);
        return success();
    }

    /**
     * 删除用户
     * @description 删除用户
     * @param $uid
     * @return Response
     */
    public function del($uid) {
        (new UserService())->del($uid);
        return success("DELETE_SUCCESS");
    }

    /**
     * 锁定用户
     * @description 锁定用户
     * @param $uid
     * @return Response
     */
    public function lock($uid) {
        (new UserService())->lock($uid);
        return success();
    }

    /**
     * 解锁用户
     * @description 解锁用户
     * @param $uid
     * @return Response
     */
    public function unlock($uid) {
        (new UserService())->unlock($uid);
        return success();
    }

    /**
     * 修改用户属性
     * @description 修改用户属性
     * @param $uid
     * @param $field
     * @return Response
     */
    public function modify($uid, $field) {
        $data = $this->request->param('value');
        (new UserService())->modify($uid, $field, $data);
        return success();
    }
}

8.2 用户服务层示例

php
<?php
namespace app\service\admin\user;

use app\dict\sys\UserDict;
use app\model\sys\SysRole;
use app\model\sys\SysUser;
use app\service\admin\auth\LoginService;
use app\service\admin\sys\RoleService;
use core\base\BaseAdminService;
use core\exception\AdminException;
use Exception;
use think\db\exception\DbException;
use think\facade\Cache;
use think\Model;

/**
 * 用户服务层
 */
class UserService extends BaseAdminService {
    public static $cache_tag_name = 'user_cache';

    public function __construct() {
        parent::__construct();
    }

    /**
     * 用户列表
     * @param array $where
     * @return array
     */
    public function getPage(array $where) {
        $field = 'uid,username,head_img,real_name,last_ip,last_time,login_count,status, role_ids, is_admin, dept_id, position_id';
        $search = [
            'username' => $where[ 'username' ],
            'real_name' => $where[ 'realname' ],
            'create_time' => $where[ 'create_time' ]
        ];
        if (!empty($where[ 'role' ])) {
            $search[ 'role_ids' ] = $where[ 'role' ];
        }
        $search_model = ( new SysUser() )->withSearch([ 'username', 'realname', 'create_time', 'role_ids' ], $search)->with(['dept', 'position'])->field($field)->order('uid desc')->append([ 'status_name' ]);
        return $this->pageQuery($search_model, function ($item, $key) {
            $role_ids = $item[ 'role_ids' ] ?? [];
            $item->role_data = $this->getRoleByUserRoleIds($role_ids);
        });
    }

    /**
     * 用户详情
     * @param int $uid
     * @return array
     */
    public function getInfo(int $uid) {
        $where = array(
            [ 'uid', '=', $uid ],
        );
        $field = 'uid, username, head_img, real_name, last_ip, last_time, create_time, login_count, status, delete_time, update_time, role_ids, is_admin, dept_id, position_id';
        $user = ( new SysUser() )->where($where)->with(['dept', 'position'])->field($field)->findOrEmpty();
        if ($user->isEmpty())
            return [];

        if (!empty($user?->userrole)) {
            $user->userrole->appendData([ 'role_array' => $this->getRoleByUserRoleIds($user->role_ids ?? []) ]);
        }

        return $user->append([ 'status_name' ])->toArray();
    }

    /**
     * 添加用户
     * @param array $data
     * @return bool
     * @throws Exception
     */
    public function add(array $data) {
        $user_data = [
            'username' => $data[ 'username' ],
            'head_img' => $data[ 'head_img' ],
            'status' => $data[ 'status' ],
            'real_name' => $data[ 'real_name' ],
            'password' => create_password($data[ 'password' ]),
            'is_admin' => $data[ 'is_admin' ]??0,
            'role_ids' => $data[ 'role_ids' ],
            'dept_id' => $data[ 'dept_id' ] ?? 0,
            'position_id' => $data[ 'position_id' ] ?? 0,
        ];
        $user = ( new SysUser() )->create($user_data);
        return $user?->uid;
    }

    /**
     * 编辑用户
     * @param int $uid
     * @param array $data
     * @return true
     */
    public function edit(int $uid, array $data) {
        $user = $this->find($uid);
        $user_data = [];
        $is_off_status = false;
        if (isset($data[ 'status' ])) {
            $user_data[ 'status' ] = $data[ 'status' ];
            if ($data[ 'status' ] == UserDict::OFF)
                $is_off_status = true;
        }
        if (isset($data[ 'head_img' ])) {
            $user_data[ 'head_img' ] = $data[ 'head_img' ];
        }
        if (isset($data[ 'real_name' ])) {
            $user_data[ 'real_name' ] = $data[ 'real_name' ];
        }

        $password = $data[ 'password' ] ?? '';
        $is_change_password = false;
        if (!empty($password) && !check_password($password, $user->password)) {
            $user_data[ 'password' ] = create_password($password);
            $is_change_password = true;
        }

        if (isset($data[ 'role_ids' ])) {
            $user_data[ 'role_ids' ] = $data[ 'role_ids' ];
        }

        if (isset($data[ 'dept_id' ])) {
            $user_data[ 'dept_id' ] = $data[ 'dept_id' ];
        }

        if (isset($data[ 'position_id' ])) {
            $user_data[ 'position_id' ] = $data[ 'position_id' ];
        }

        if (empty($user_data))
            return true;
        //更新用户信息
        $user->save($user_data);
        //更新权限  禁用用户  修改密码 都会清理token
        if ($is_off_status || $is_change_password) {
            LoginService::clearToken($uid);
        }
        //清除用户缓存
        $cache_name = 'user_role_' . $uid;
        Cache::delete($cache_name);
        return true;
    }

    /**
     * 锁定
     * @param int $uid
     * @return bool|true
     */
    public function lock(int $uid) {
        return $this->edit($uid, [ 'status' => UserDict::OFF ]);
    }

    /**
     * 解锁
     * @param int $uid
     * @return bool|true
     */
    public function unlock(int $uid) {
        return $this->edit($uid, [ 'status' => UserDict::ON ]);
    }

    /**
     * 修改字段
     * @param int $uid
     * @param string $field
     * @param $data
     * @return bool|true
     */
    public function modify(int $uid, string $field, $data) {
        $field_name = match ( $field ) {
            'password' => 'password',
            'real_name' => 'real_name',
            'head_img' => 'head_img',
        };
        return $this->edit($uid, [ $field_name => $data ]);
    }

    /**
     * 删除
     * @param int $uid
     * @return true
     */
    public function del(int $uid) {
        $where = [
            [ 'uid', '=', $uid ]
        ];
        $user = ( new SysUser() )->where($where)->findOrEmpty();
        if ($user->isEmpty()) throw new AdminException('USER_NOT_EXIST');
        if ($user->is_admin) throw new AdminException("SUPER_ADMIN_NOT_ALLOW_DEL");
        $user->delete();
        LoginService::clearToken($uid);
        Cache::delete('user_role_' . $uid);
        return true;
    }

    /**
     * 用户模型对象
     * @param int $uid
     * @return SysUser|array|mixed|Model
     */
    public function find(int $uid) {
        $user = ( new SysUser() )->findOrEmpty($uid);
        if ($user->isEmpty())
            throw new AdminException('USER_NOT_EXIST');
        return $user;
    }
}