文档目录
用户管理

简介

本技术文档围绕 DouPHP 后台“用户管理”功能,系统阐述管理员对会员用户的增删改查、状态管理、列表查询与分页、批量操作、权限控制以及数据导入导出等能力。文档从控制器、服务层、模型层、请求校验与中间件等多维度进行剖析,并提供流程图与时序图帮助理解数据流与控制流。同时给出常见问题的定位思路与优化建议。

项目结构

用户管理在后台模块中采用典型的 MVC + Service 分层:

  • 控制器:负责路由调度、取参、视图渲染与跳转
  • 服务层:封装业务逻辑(列表构建、新增/更新/删除、状态变更、批量操作、Excel 导出)
  • 模型层:定义数据表映射、字段白名单、关联与查询作用域
  • 请求校验:集中处理表单参数校验与白名单过滤
  • 中间件:统一认证与权限检查
graph TB
subgraph "后台入口"
A["路由/中间件<br/>认证与权限"]
end
subgraph "控制器层"
B["UserController"]
end
subgraph "服务层"
C["UserService"]
end
subgraph "模型层"
D["User / UserLevel"]
end
subgraph "外部依赖"
E["附件存储"]
F["审计日志"]
G["Excel 导出"]
end
A --> B --> C --> D
C --> E
C --> F
C --> G

核心组件

  • 控制器 UserController:提供用户列表、新增、编辑、删除、批量操作、状态变更、登录参数初始化等接口
  • 服务层 UserService:实现列表数据组装、新增/更新/删除、状态迁移、批量动作、Excel 导出、等级日志记录
  • 模型 User:定义 user 表映射、字段白名单、性别展示、筛选作用域、默认排序、关联 user_level
  • 模型 UserLevel:定义 user_level 表映射与常用查询方法
  • 请求校验 UserFormRequest / UserActionFormRequest:表单字段校验、唯一性、必填规则
  • 中间件 AuthMiddleware / PermissionMiddleware:后台登录态恢复与模块级权限控制

架构总览

后台用户管理的请求链路如下:

  • 请求进入后先经过认证中间件校验登录态,再经权限中间件校验模块访问权限
  • 控制器接收请求并调用服务层完成业务处理
  • 服务层通过模型层读写数据库,必要时调用附件存储、审计日志、Excel 导出等外部能力
  • 最终返回视图或重定向响应
sequenceDiagram
participant Client as "浏览器"
participant MW1 as "认证中间件"
participant MW2 as "权限中间件"
participant Ctrl as "UserController"
participant Svc as "UserService"
participant Model as "User/UserLevel"
participant Ext as "附件/审计/Excel"
Client->>MW1 : 请求 /admin/user/*
MW1-->>Client : 未登录则跳转登录页
MW1->>MW2 : 已登录放行
MW2-->>Client : 无权限则跳转首页
MW2->>Ctrl : 进入控制器
Ctrl->>Svc : 列表/新增/更新/删除/批量/状态
Svc->>Model : 查询/写入
Svc->>Ext : 附件上传/审计日志/Excel导出
Svc-->>Ctrl : 结果
Ctrl-->>Client : 视图/重定向

详细组件分析

控制器:UserController

职责与要点

  • 列表页 index:解析分页与筛选条件,调用服务层构建列表数据,渲染模板
  • 新增 create/store:生成默认表单数据;提交时由请求校验器校验,服务层插入并记录审计日志
  • 编辑 edit/update:加载用户信息;支持头像上传;提交时更新用户信息与联系人快照,记录等级调整日志
  • 删除 destroy:二次确认流程,删除用户及关联 SNS 数据,记录审计日志
  • 批量 action:支持批量删除、导出选中、导出全部
  • 状态 setStatus:封禁/解禁/注销,基于状态机迁移校验并写审计日志
  • set:初始化登录相关参数项

关键路径参考

  • 列表构建与渲染:UserController.php:77-119
  • 新增流程:UserController.php:121-158
  • 编辑流程:UserController.php:160-221
  • 删除流程:UserController.php:223-238
  • 批量操作:UserController.php:240-258
  • 状态变更:UserController.php:260-277

服务层:UserService

职责与要点

  • buildUserListData:按用户名关键字、状态筛选,分页获取用户列表,聚合最后登录时间、积分、余额、消费、推广、VIP 等信息,构造列表数据
  • statusOptions:返回状态选项供前端下拉使用
  • setStatus:状态迁移校验(合法迁移),更新状态并写审计日志
  • insert:新增用户,生成用户编号,密码哈希,创建联系人快照,可选头像上传,记录审计日志
  • update:更新用户基本信息、等级、联系人快照;若修改等级则记录等级日志;可选头像覆盖
  • delete:二次确认删除,清理关联 SNS 数据,记录审计日志
  • action:批量删除、导出选中、导出全部
  • buildExcelUserList:构建 Excel 导出的头部与数据行
  • writeManualUserLevelLog / writeManualDistributionLevelLog:手工调整等级时记录日志

关键路径参考

  • 列表构建:UserService.php:74-177
  • 状态选项:UserService.php:179-192
  • 状态变更:UserService.php:194-229
  • 新增:UserService.php:342-395
  • 更新:UserService.php:397-465
  • 删除:UserService.php:467-501
  • 批量:UserService.php:503-544
  • Excel 导出:UserService.php:567-601
  • 等级日志:UserService.php:603-656

模型层:User / UserLevel

User 模型

  • 表名与主键:user/id
  • 字段类型转换 casts:level_id/login_count/status/created_at
  • 可填充字段 fillable:user_sn、level_id、distribution_level_id、mobile、email、password、token、reset_token、sex、nickname、avatar、defined、pay_code、login_count、status、created_at 等
  • 关联:belongsTo UserLevel(level_id)
  • 访问器:getSexAttribute 将 sex 转为男/女文案
  • 查询作用域:filterByUserId、filterByStatus、withLevelIfAvailable、applyDefaultOrder
  • 静态方法:findByUserId、deleteUserSnsByUserId、getUserIdByEmail、getUserIdByMobile、getAvatarValue、getUserLogList

UserLevel 模型

  • 表名与主键:user_level/id
  • 可填充字段:name、upgrade_type、upgrade_condition、good_discount、icon、created_at
  • 静态方法:selectAllOrdered、getNameById、getLevelIdByName

请求校验:UserFormRequest / UserActionFormRequest

UserFormRequest

  • 场景合并:update 场景自动合并 user_id
  • 规则:
    • level_id/distribution_level_id:整数
    • email/mobile:邮箱/手机号格式,唯一性校验(区分新增/编辑)
    • phone/contact/address 等:非法字符校验
    • sex:枚举 0/1
    • password/password_confirm:新增必填且一致;编辑留空表示不修改 UserActionFormRequest
  • 规则:action 限定为 del_all/excel/excel_all;checkbox 为数组

中间件:认证与权限

认证中间件 AuthMiddleware

  • 从会话恢复管理员登录态,未登录抛异常跳转登录页 权限中间件 PermissionMiddleware
  • 读取当前管理员信息,判断是否可访问当前模块与动作;超级管理员直接放行,普通管理员按白名单判定

类关系图

classDiagram
class UserController {
+index(request) Response
+create() Response
+store(formRequest, request) Response
+edit(request) Response
+update(formRequest, request) Response
+destroy(request) Response
+action(formRequest) Response
+setStatus(formRequest) Response
+set() Response
}
class UserService {
+buildUserListData(username, page, rejectFilter, statusFilter) array
+statusOptions() array
+setStatus(userId, newStatus, adminId) void
+insert(data) int
+update(data, avatar) void
+delete(userId, post) array
+action(data) array|null
+buildExcelUserList(checkbox) array
}
class User {
+table : string
+primary : string
+fillable : array
+level() Relation
+scopeFilterByUserId(query, userId) Builder
+scopeFilterByStatus(query, status) Builder
+scopeWithLevelIfAvailable(query) Builder
+scopeApplyDefaultOrder(query) Builder
+findByUserId(userId) Model|null
+deleteUserSnsByUserId(userId) mixed
+getUserIdByEmail(email) mixed
+getUserIdByMobile(mobile) mixed
+getAvatarValue(userId) mixed
+getUserLogList(userId, page) array
}
class UserLevel {
+table : string
+primary : string
+fillable : array
+selectAllOrdered() array
+getNameById(levelId) mixed
+getLevelIdByName(name) int
}
class UserFormRequest {
+rules() array
}
class UserActionFormRequest {
+rules() array
}
class AuthMiddleware {
+handle(next) mixed
}
class PermissionMiddleware {
+handle(next) mixed
}
UserController --> UserService : "调用"
UserService --> User : "读写"
User --> UserLevel : "关联"
UserController --> UserFormRequest : "校验"
UserController --> UserActionFormRequest : "校验"
AuthMiddleware --> PermissionMiddleware : "前置"

序列图:用户列表查询与分页

sequenceDiagram
participant R as "请求"
participant C as "UserController"
participant S as "UserService"
participant M as "User"
participant Q as "查询聚合"
R->>C : GET /admin/user?page=1&username=&status=
C->>S : buildUserListData(username, page, rejectFilter, statusFilter)
S->>M : withLevelIfAvailable()->filterByUserId()->filterByStatus()->order()->paginate()
S->>Q : 聚合最后登录/积分/余额/消费/推广/VIP
Q-->>S : 映射数据
S-->>C : 列表+分页
C-->>R : 渲染 user.htm

序列图:新增用户

sequenceDiagram
participant R as "请求"
participant C as "UserController"
participant V as "UserFormRequest"
participant S as "UserService"
participant U as "User"
participant A as "附件存储"
participant L as "审计日志"
R->>C : POST /admin/user/store
C->>V : validated()
V-->>C : 校验通过的数据
C->>S : insert(data)
S->>U : create(user_sn, level_id, email/mobile, password_hash, ...)
S->>A : store('user', id, avatar)
S->>L : writeAdminLog(CREATE)
S-->>C : 新ID
C-->>R : 重定向到编辑页

序列图:状态变更(封禁/解禁/注销)

sequenceDiagram
participant R as "请求"
participant C as "UserController"
participant V as "UserStatusFormRequest"
participant S as "UserService"
participant DB as "DB"
participant L as "审计日志"
R->>C : POST /admin/user/set_status
C->>V : validated()
V-->>C : {user_id, new_status}
C->>S : setStatus(userId, newStatus, adminId)
S->>DB : 读取当前状态
S->>S : canTransit(current, newStatus)
alt 允许迁移
S->>DB : update(status=newStatus)
S->>L : writeUserLog(set_status : current->new)
S-->>C : 成功
else 不允许迁移
S-->>C : 抛出异常
end
C-->>R : 重定向到编辑页

流程图:批量操作

flowchart TD
Start(["开始"]) --> Parse["解析 action 与 checkbox"]
Parse --> Check{"action 类型"}
Check --> |del_all| DelAll["校验ids非空 -> 批量删除SNS -> 批量删除用户 -> 审计日志"]
Check --> |excel| ExportSel["导出选中用户Excel"]
Check --> |excel_all| ExportAll["导出全部用户Excel"]
Check --> |其他| Error["抛出异常:选择为空或非法动作"]
DelAll --> End(["结束"])
ExportSel --> End
ExportAll --> End
Error --> End

依赖关系分析

  • 控制器依赖服务层,服务层依赖模型层与外部能力(附件、审计、Excel)
  • 模型层通过 ORM 与数据库交互,并通过配置开关决定是否预加载等级关联
  • 中间件位于控制器之前,确保只有已认证且有权限的请求才能到达业务逻辑
graph LR
MW["中间件"] --> CTRL["控制器"]
CTRL --> SVC["服务层"]
SVC --> MOD["模型层"]
SVC --> ATT["附件存储"]
SVC --> AUD["审计日志"]
SVC --> XLS["Excel导出"]

性能考虑

  • 列表查询避免 N+1:通过 withLevelIfAvailable 按需预加载等级关联
  • 分页限制:每页固定条数,减少单次返回数据量
  • 聚合查询分离:最后登录、积分、余额、消费、推广、VIP 等通过独立查询聚合,避免大表 JOIN
  • 导出优化:Excel 导出仅选取必要字段,按主键降序稳定排序
  • 索引建议:user 表的 email、mobile、user_sn、status、id 等字段应建立合适索引以提升查询效率

故障排查指南

  • 无法访问用户管理页面
    • 检查认证中间件是否成功恢复登录态
    • 检查权限中间件是否允许当前管理员访问该模块与动作
  • 新增用户失败
    • 检查表单校验规则(邮箱/手机格式、唯一性、密码一致性)
    • 检查必填字段(至少邮箱或手机)
  • 编辑用户报错
    • 检查 user_id 是否有效
    • 检查邮箱/手机唯一性(排除自身)
  • 状态变更无效
    • 检查当前状态与目标状态是否允许迁移
    • 查看审计日志确认是否执行成功
  • 批量操作无效果
    • 检查 action 是否为受支持的类型
    • 检查 checkbox 是否为空或包含非法 ID

结论

DouPHP 后台用户管理采用清晰的分层架构与严格的输入校验,结合状态机迁移与审计日志,实现了安全可控的用户生命周期管理。列表查询与分页、批量操作、Excel 导出等功能完备,便于日常运营与维护。建议在大数据量场景下关注索引设计与聚合查询优化,进一步提升性能。

附录

用户数据模型设计

  • 主表 user
    • 标识:id(主键)
    • 账号:email、mobile、user_sn
    • 安全:password、token、reset_token、login_fail_count、login_locked_at
    • 属性:sex、nickname、avatar、defined、pay_code、login_count、status、created_at
    • 等级:level_id(关联 user_level)、distribution_level_id(分销等级)
  • 关联表 user_level
    • 标识:id(主键)
    • 名称:name
    • 升级策略:upgrade_type、upgrade_condition
    • 权益:good_discount、icon
    • 时间:created_at
  • 验证规则
    • 邮箱/手机号格式与唯一性(新增/编辑区分)
    • 密码长度与一致性(新增必填,编辑留空不修改)
    • 性别枚举 0/1
    • 地址/电话等字段非法字符过滤
  • 关联关系
    • User belongsTo UserLevel(level_id)
    • 删除用户时联动删除 user_sns

权限级别划分与访问控制

  • 超级管理员:type 不为 defined,直接放行所有模块访问
  • 普通管理员:type 为 defined,按 action_list 白名单判定模块与动作访问
  • 中间件链:认证中间件优先恢复登录态,权限中间件随后校验模块访问

用户列表查询与分页显示

  • 列表构建:按用户名关键字(手机/邮箱/user_sn/联系人)解析为用户 ID 过滤,支持状态筛选
  • 分页:每页固定条数,返回 pager 对象供模板渲染
  • 附加信息:聚合最后登录时间、积分、余额、消费、推广、VIP 信息

批量操作

  • 批量删除:校验 IDs,删除 SNS 关联,批量删除用户,记录审计日志
  • 导出选中/全部:构建 Excel 头部与数据行,直接输出二进制响应

高级功能方案

  • 用户数据导入
    • 可在现有 Excel 导出基础上扩展导入逻辑,复用字段映射与校验规则
    • 建议分批导入并记录导入日志,失败行单独输出
  • 密码重置
    • 可通过设置 reset_token 与过期时间,配合前端重置流程更新密码
    • 注意令牌唯一性与有效期校验
  • 账户锁定/解锁
    • 利用 login_fail_count 与 login_locked_at 字段实现失败次数锁定
    • 解锁时可清零失败计数并清空锁定时间
添加日期:2026-10-05