简介
本文件面向 DouPHP 小程序“用户信息”相关能力,覆盖用户头像、用户资料、用户中心等组件的实现与集成说明。重点阐述:
- 用户数据模型与字段范围(基础资料、登录态、VIP/工作/分销等扩展)
- 权限控制与会话管理(API Token、登录态校验、退出登录)
- 微信授权与第三方登录流程(jscode2session、手机号解密、UnionID/OpenID 策略)
- 数据同步机制(前端状态 store、HTTP 层信封解析、缓存与去重)
- 隐私保护策略(最小化敏感信息回传、服务端校验与审计日志)
- 用户信息的编辑、验证、存储(昵称、联系方式、地址、头像上传)
项目结构
围绕“用户信息”的前后端关键位置如下:
- 小程序端
- 页面:用户中心、微信登录页、账号/手机登录页、密码重置页、个人资料编辑页等
- 状态:authStore 负责登录态持久化与聚合
- 网络:http.ts 统一封装请求、拦截器、信封解析、缓存与去重
- 后端 API
- 控制器:UserController(注册、登录、资料、头像、文件、区域、SNS 管理等)、WeixinController(小程序微信登录、手机号解密、支付)
- 服务:注册、登录、密码重置、资料、用户中心展示等服务类由控制器注入使用
graph TB
subgraph "小程序前端"
P_user["user.ts<br/>用户中心"]
P_loginwx["login_weixin.ts<br/>微信登录"]
S_auth["auth.ts<br/>登录态 Store"]
S_http["http.ts<br/>HTTP 层"]
end
subgraph "后端 API"
C_user["UserController.php<br/>用户业务接口"]
C_wx["WeixinController.php<br/>微信能力接口"]
end
P_user --> |GET /user| C_user
P_loginwx --> |POST/GET 微信登录| C_wx
P_loginwx --> |检查登录态| C_user
S_auth --> |Bearer Token| S_http
S_http --> |HTTP 请求| C_user
S_http --> |HTTP 请求| C_wx
图表来源
- miniprogram/default/pages/user/user.ts:58-88
- miniprogram/default/pages/user/login_weixin.ts:79-140
- miniprogram/default/stores/auth.ts:78-115
- miniprogram/default/services/http.ts:194-339
- api/controller/user/UserController.php:121-158
- api/controller/user/WeixinController.php:101-184
章节来源
- miniprogram/default/pages/user/user.ts:58-88
- api/controller/user/UserController.php:121-158
- api/controller/user/WeixinController.php:101-184
核心组件
- 用户中心(user.ts + UserController::index)
- 聚合返回:基础资料 dou.user、登录态与角色标志 dou.auth、VIP/工作/分销详情
- 用于渲染用户头像、昵称、欢迎语、入口链接等
- 微信登录(login_weixin.ts + WeixinController::login)
- 小程序 wx.login 获取 code,后端 jscode2session 换取 openid/unionid/session_key
- 支持预检手机号是否存在、自动注册或绑定既有账号、发放 API Token
- 登录态管理(auth.ts + http.ts)
- 本地持久化 api_token/user_id/loginEd
- 每次请求自动附加 Authorization: Bearer <token>
- 根据 user/index 的 dou.auth 刷新 is_login/is_vip/is_work/is_distribution
- 个人资料与头像(UserController::edit/editPost/uploadAvatar)
- 昵称、联系方式、地址、邮编、性别、自定义字段等
- 头像上传并更新 user.avatar,返回可访问 URL
章节来源
- miniprogram/default/pages/user/user.ts:58-88
- api/controller/user/UserController.php:121-158
- miniprogram/default/pages/user/login_weixin.ts:79-140
- api/controller/user/WeixinController.php:101-184
- miniprogram/default/stores/auth.ts:78-115
- miniprogram/default/services/http.ts:194-339
- api/controller/user/UserController.php:416-496
- api/controller/user/UserController.php:726-745
架构总览
下图展示了小程序用户信息能力的端到端调用链:从页面发起请求到后端处理,再到状态同步与 UI 更新。
sequenceDiagram
participant WX as "微信小程序"
participant Page as "login_weixin.ts"
participant Auth as "auth.ts"
participant HTTP as "http.ts"
participant API as "WeixinController.php"
participant UCtrl as "UserController.php"
WX->>Page : 触发微信登录
Page->>WX : wx.login() 获取 code
Page->>HTTP : GET /user/weixin/login?code=...&act=preload
HTTP->>API : 携带 Authorization : Bearer (可选)
API-->>HTTP : {phone_exist}
HTTP-->>Page : 返回预检结果
Page->>HTTP : GET /user/weixin/login?code=...
API->>API : jscode2session, 查/建/绑账号
API-->>HTTP : {user : {user_id, token}, dou : {auth}}
HTTP-->>Page : 成功载荷
Page->>Auth : login({token, user_id})
Auth->>HTTP : 后续请求自动带 Bearer Token
Page->>HTTP : GET /user (用户中心)
HTTP->>UCtrl : 读取用户资料与登录态
UCtrl-->>HTTP : {dou : {user, auth,...}}
HTTP-->>Page : 渲染用户中心
图表来源
- miniprogram/default/pages/user/login_weixin.ts:79-140
- api/controller/user/WeixinController.php:101-184
- miniprogram/default/stores/auth.ts:127-140
- miniprogram/default/services/http.ts:194-339
- api/controller/user/UserController.php:121-158
详细组件分析
用户中心(头像、资料、入口)
- 功能要点
- 拉取用户中心首页数据,包含基础资料、登录态标志、VIP/工作/分销详情
- 提供下载图片、复制文本、跳转用户中心子页面等交互
- 数据流
- 页面 onShow 调用 /user,将 data.dou 映射到视图数据
- 退出登录时清空本地缓存并跳转首页
- 权限与展示
- 通过 dou.auth.is_login 等标志控制可见性与可操作项
flowchart TD
Start(["进入用户中心"]) --> Fetch["请求 /user"]
Fetch --> Parse{"响应是否成功"}
Parse --> |是| Render["渲染 dou.user/dou.auth 等"]
Render --> Actions{"用户操作"}
Actions --> |下载图片| Download["调用系统保存"]
Actions --> |复制文本| Copy["写入剪贴板"]
Actions --> |跳转| Nav["navigateTo 子页面"]
Actions --> |退出| Logout["清除本地缓存并返回首页"]
Parse --> |否| Error["提示错误"]
图表来源
- miniprogram/default/pages/user/user.ts:58-88
- miniprogram/default/pages/user/user.ts:90-95
- api/controller/user/UserController.php:121-158
章节来源
- miniprogram/default/pages/user/user.ts:58-88
- api/controller/user/UserController.php:121-158
微信授权与登录(小程序)
- 流程概述
- 小程序端先预检手机号是否存在,再执行正式登录
- 后端通过 jscode2session 获取 openid/unionid,按策略匹配/注册/绑定账号
- 成功后下发 API Token,前端存入 authStore 并刷新登录态
- 关键点
- UnionID/OpenID 模式由配置决定
- 未绑定手机号时可尝试绑定已有手机号账号
- 自动登记推广关系(直推/间接)
sequenceDiagram
participant P as "login_weixin.ts"
participant H as "http.ts"
participant W as "WeixinController.php"
participant A as "auth.ts"
P->>H : GET /user/weixin/login?act=preload&code=...
H->>W : 请求微信登录(预检)
W-->>H : {phone_exist}
H-->>P : 设置 phoneExist
P->>H : GET /user/weixin/login?code=...
H->>W : jscode2session, 查/建/绑账号
W-->>H : {user : {user_id, token}, dou : {auth}}
H-->>P : 成功
P->>A : login({token, user_id})
A-->>P : 设置 is_login 等标志
图表来源
- miniprogram/default/pages/user/login_weixin.ts:79-140
- api/controller/user/WeixinController.php:101-184
- miniprogram/default/stores/auth.ts:127-140
章节来源
- miniprogram/default/pages/user/login_weixin.ts:79-140
- api/controller/user/WeixinController.php:101-184
- miniprogram/default/stores/auth.ts:127-140
手机号解密(小程序)
- 流程
- 小程序端通过 getPhoneNumber 获取 code,调用后端解密接口
- 后端向微信换取 access_token 并解密手机号
- 用途
- 在微信登录流程中作为手机号回填,便于绑定或自动注册
sequenceDiagram
participant P as "login_weixin.ts"
participant H as "http.ts"
participant W as "WeixinController.php"
P->>H : GET /user/weixin/get_phone?code=...
H->>W : 请求手机号解密
W->>W : 获取 access_token, 调用微信接口解密
W-->>H : {phone}
H-->>P : 返回手机号
P->>P : 继续微信登录流程
图表来源
- miniprogram/default/pages/user/login_weixin.ts:142-160
- api/controller/user/WeixinController.php:75-99
章节来源
- miniprogram/default/pages/user/login_weixin.ts:142-160
- api/controller/user/WeixinController.php:75-99
登录态与鉴权(Store + HTTP)
- 设计要点
- authStore 维护 api_token/user_id/loginEd 及 is_login/is_vip/is_work/is_distribution
- 启动时 restore 调用 /user 聚合登录态;失败仅 UNAUTHORIZED 才清空
- http.ts 为每个请求自动附加 Authorization: Bearer <token>
- 成功响应附带 message/request_id 便于调试
- 退出登录
- 清除本地缓存与状态,必要时跳转登录页
classDiagram
class AuthStore {
+string api_token
+string user_id
+boolean loginEd
+boolean is_login
+boolean is_vip
+boolean is_work
+boolean is_distribution
+hydrate() void
+applyAuthFlags(flags) void
+restore() Promise~void~
+ensureLogin(redirectUrl) Promise~boolean~
+login(payload) void
+logout() void
}
class HttpLayer {
+get(url,data,opts) Promise
+post(url,data,opts) Promise
+put(url,data,opts) Promise
+del(url,data,opts) Promise
+onRequest(fn) void
+onSuccess(fn) void
+onError(fn) void
}
AuthStore --> HttpLayer : "通过 /user 恢复登录态"
图表来源
- miniprogram/default/stores/auth.ts:69-155
- miniprogram/default/services/http.ts:194-339
章节来源
- miniprogram/default/stores/auth.ts:69-155
- miniprogram/default/services/http.ts:194-339
个人资料编辑与验证
- 字段范围
- 昵称、联系方式、电话、姓名(英文站点)、国家/省份、地址、邮编、性别、自定义字段
- 校验规则
- 必填与非法字符校验;昵称唯一性检查
- XSS 过滤后落库
- 存储
- 通过 ProfileService 更新用户资料
flowchart TD
Enter["进入编辑页"] --> Load["加载可编辑资料"]
Load --> Validate{"表单校验"}
Validate --> |失败| ShowErr["显示错误"]
Validate --> |成功| Submit["提交修改"]
Submit --> Update["ProfileService 更新资料"]
Update --> Done["返回成功"]
图表来源
- api/controller/user/UserController.php:416-496
章节来源
- api/controller/user/UserController.php:416-496
头像上传
- 流程
- 选择头像后调用上传接口,后端生成固定尺寸缩略图并写入 user.avatar
- 返回可访问的头像 URL
- 安全
- 基于当前登录用户 ID 进行归属校验与写入
sequenceDiagram
participant P as "用户"
participant H as "http.ts"
participant U as "UserController.php"
P->>H : POST /user/filebox (module=user, type=main, avatar)
H->>U : 携带 Bearer Token
U->>U : 校验用户身份, 存储头像, 更新 user.avatar
U-->>H : {file_url}
H-->>P : 更新头像预览
图表来源
- api/controller/user/UserController.php:726-745
章节来源
- api/controller/user/UserController.php:726-745
用户认证流程(账号/手机/微信)
- 账号密码登录
- 校验凭据,成功后下发 Token,返回 is_work 标志
- 手机验证码登录
- 校验验证码时效与内容,成功后下发 Token
- 微信登录
- 见“微信授权与登录”小节
flowchart TD
Start(["选择登录方式"]) --> Mode{"方式"}
Mode --> |账号密码| Acc["validateLoginCredentials"]
Mode --> |手机验证码| Phone["validatePhoneLogin"]
Mode --> |微信| Wx["jscode2session, 查/建/绑"]
Acc --> Token["issue token"]
Phone --> Token
Wx --> Token
Token --> End(["登录成功"])
图表来源
- api/controller/user/UserController.php:292-371
- api/controller/user/WeixinController.php:101-184
章节来源
- api/controller/user/UserController.php:292-371
- api/controller/user/WeixinController.php:101-184
依赖关系分析
- 前端依赖
- 页面依赖 http.ts 进行网络通信
- 页面依赖 auth.ts 管理登录态与路由守卫
- 后端依赖
- 控制器依赖多个 Service(注册、登录、资料、密码重置、用户中心展示、Token 服务等)
- 微信能力依赖微信开放平台接口与支付服务
graph LR
P_user["user.ts"] --> H["http.ts"]
P_login["login_weixin.ts"] --> H
H --> C_user["UserController.php"]
H --> C_wx["WeixinController.php"]
C_user --> S_reg["RegistrationService"]
C_user --> S_login["LoginService"]
C_user --> S_profile["ProfileService"]
C_user --> S_pwd["PasswordResetService"]
C_user --> S_ucenter["UserCenterPresenter"]
C_user --> S_token["ApiTokenService"]
C_wx --> S_wx["WxPayService"]
C_wx --> S_token
图表来源
- api/controller/user/UserController.php:55-119
- api/controller/user/WeixinController.php:49-73
- miniprogram/default/services/http.ts:194-339
章节来源
- api/controller/user/UserController.php:55-119
- api/controller/user/WeixinController.php:49-73
- miniprogram/default/services/http.ts:194-339
性能考虑
- 请求去重与内存缓存
- 相同 GET 请求在飞行中复用同一 Promise,减少重复网络开销
- 可选开启 cache/ttl 对只读数据进行短期缓存
- 登录态恢复优化
- 仅在 UNAUTHORIZED 时清空登录态,避免弱网误判导致频繁跳转登录
- 头像与图片
- 后端统一生成固定宽度缩略图,降低带宽与渲染成本
- 建议
- 对高频只读数据启用缓存;对写操作禁用缓存
- 合理设置 ttl,平衡实时性与性能
故障排查指南
- 常见问题定位
- 登录失败:检查微信 code 有效性、appid/appsecret 配置、IP 限流
- 手机号解密失败:确认小程序已开通手机号解密能力且 code 有效
- 头像上传失败:检查文件类型、大小、存储路径权限
- 资料保存失败:核对必填字段、非法字符、昵称唯一性
- 调试技巧
- 利用 http.ts 的 request_id 与服务端异常堆栈弹窗(开发环境)
- 查看 lastRequestId 与错误消息中的 req 片段,快速关联服务端日志
- 安全与审计
- 登录失败/成功均记录审计日志,便于追踪异常行为
章节来源
- miniprogram/default/services/http.ts:150-188
- api/controller/user/WeixinController.php:116-134
- api/controller/user/UserController.php:441-496
结论
DouPHP 小程序用户信息组件以清晰的职责分层实现:
- 前端通过 http.ts 统一网络层与 auth.ts 登录态管理,保证一致的用户体验
- 后端通过 UserController 与 WeixinController 集中处理用户业务与微信能力
- 结合缓存、去重、缩略图、审计日志等手段,兼顾性能与安全
- 提供完善的资料编辑、头像上传、微信授权与手机号解密能力,满足常见用户场景
附录
- 关键接口速览(概念性)
- 用户中心:GET /user
- 微信登录:GET /user/weixin/login
- 手机号解密:GET /user/weixin/get_phone
- 资料编辑:GET/POST /user/edit
- 头像上传:POST /user/filebox(module=user, type=main)
- 退出登录:POST /user/logout
- 配置项参考(概念性)
- 小程序 AppID/Secret、UnionID/OpenID 策略、短信/邮箱开关等