用户使用流程图 — 认证与用户管理
端口说明: 📱 小程序 | 🖥 管理后台 | 📋 规划师端 | ⚙️ 系统自动
分层说明: 🏠 页面 → 🔗 API → ⚙️ Service → 📦 数据实体
flowchart TD
%% ============ 颜色定义 ============
classDef page fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
classDef api fill:#fff3e0,stroke:#f57c00,stroke-width:1px
classDef service fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
classDef data fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px
classDef external fill:#fce4ec,stroke:#d32f2f,stroke-width:1px,stroke-dasharray:3 2
classDef actor fill:#e1f5fe,stroke:#0288d1,stroke-width:2px,stroke-dasharray:5 3
%% ============ 角色 ============
ROLE_PARENT(("👤 家长")):::actor
ROLE_CHILD(("👶 孩子")):::actor
ROLE_JWT(("🔐 JWT认证")):::actor
%% ================================================================
%% 阶段一:注册登录
%% ================================================================
subgraph 阶段一[阶段一:注册登录]
direction TB
P1["🏠 小程序:登录页"]:::page
P1 -->|"选择操作"| P1_choice{"已有账号 / 新注册"}:::page
P1_choice -->|"新注册"| P1_reg{"选择注册方式"}:::page
P1_reg -->|"微信授权"| P1a["🏠 微信静默授权弹窗"]:::page
P1a -->|"微信code"| A1["🔗 POST /api/auth/silent-login"]:::api
A1 -->|"微信code"| S1["⚙️ WechatService.silentLogin()"]:::service
S1 -->|"openid, 新用户标记"| D1["📦 users 表(查询/创建)"]:::data
P1_reg -->|"手机号"| P1b["🏠 输入手机号"]:::page
P1b -->|"手机号"| A2["🔗 POST /api/auth/send-code"]:::api
A2 -->|"手机号"| S2["⚙️ SmsService.sendCode()"]:::service
S2 -->|"验证码, 过期时间"| D2["📦 sms_codes 表(写入)"]:::data
P1b -->|"手机号 + 验证码"| A3["🔗 POST /api/auth/phone-login"]:::api
A3 -->|"手机号, 验证码"| S3["⚙️ AuthService.phoneLogin()"]:::service
S3 -->|"用户信息"| D1
P1_reg -->|"手机号+身份证"| P1c["🏠 填写手机号+身份证"]:::page
P1c -->|"手机号, 身份证号"| A4["🔗 POST /api/auth/register-with-idcard"]:::api
A4 -->|"手机号, 身份证号"| S4["⚙️ AuthService.registerWithIdCard()"]:::service
S4 -->|"新用户记录"| D1
P1_reg -->|"邀请码"| P1d["🏠 输入邀请码"]:::page
P1d -->|"手机号, 邀请码"| A5["🔗 POST /api/auth/register-with-invite"]:::api
A5 -->|"手机号, 邀请码"| S5["⚙️ AuthService.registerWithInvite()"]:::service
S5 -->|"新用户记录 + 邀请关系"| D1
P1_reg -->|"直接注册"| P1e["🏠 填写基本信息"]:::page
P1e -->|"昵称, 头像"| A6["🔗 POST /api/auth/direct-register"]:::api
A6 -->|"用户信息"| S6["⚙️ AuthService.directRegister()"]:::service
S6 -->|"新用户记录"| D1
P1_choice -->|"已有账号"| P1_login{"选择登录方式"}:::page
P1_login -->|"微信"| P1f["🏠 微信授权弹窗"]:::page
P1f -->|"微信code"| A7["🔗 POST /api/auth/wechat-login"]:::api
A7 -->|"微信code"| S7["⚙️ WechatService.codeLogin()"]:::service
S7 -->|"用户ID"| D1
P1_login -->|"手机号"| P1g["🏠 输入手机号+验证码"]:::page
P1g -->|"手机号, 验证码"| A3
P1_login -->|"openid自动登录"| P1h["🏠 自动检测openid"]:::page
P1h -->|"openid"| A8["🔗 POST /api/auth/auto-login"]:::api
A8 -->|"openid"| S8["⚙️ AuthService.autoLogin()"]:::service
S8 -->|"用户ID"| D1
D1 -->|"用户信息"| S_JWT["⚙️ JwtUtil.generateToken()"]:::service
S_JWT -->|"JWT token"| D_JWT["📦 JWT Token(返回前端)"]:::data
end
%% ================================================================
%% 阶段二:认证与安全
%% ================================================================
subgraph 阶段二[阶段二:认证与安全]
D_JWT -->|"token"| P2["🏠 小程序:首页(已登录)"]:::page
P2 -->|"每次请求携带token"| A9["🔗 POST /api/auth/verify"]:::api
A9 -->|"JWT token"| S9["⚙️ JwtInterceptor.verify()"]:::service
S9 -->|"有效/过期"| VERIFY{"token有效?"}:::page
VERIFY -->|"有效"| P2a["🏠 获取用户信息"]:::page
P2a -->|"Authorization header"| A10["🔗 POST /api/auth/info"]:::api
A10 -->|"用户ID(从token提取)"| S10["⚙️ UserService.getUserInfo()"]:::service
S10 -->|"用户完整信息"| D_USER["📦 users 表(查询)"]:::data
P2a -->|"设置密码"| P2b["🏠 设置密码页"]:::page
P2b -->|"新密码"| A11["🔗 POST /api/auth/set-password"]:::api
A11 -->|"用户ID, 密码hash"| S11["⚙️ UserService.setPassword()"]:::service
S11 -->|"更新密码字段"| D_USER
P2a -->|"验证密码"| P2c["🏠 输入密码"]:::page
P2c -->|"密码"| A12["🔗 POST /api/auth/verify-password"]:::api
A12 -->|"用户ID, 密码"| S12["⚙️ UserService.verifyPassword()"]:::service
S12 -->|"匹配/不匹配"| D_USER
P2a -->|"检查手机号"| P2d["🏠 检查手机号页"]:::page
P2d -->|"手机号"| A13["🔗 POST /api/auth/check-phone"]:::api
A13 -->|"手机号"| S13["⚙️ UserService.checkPhoneExists()"]:::service
S13 -->|"已注册/未注册"| D_USER
VERIFY -->|"过期/无效"| P2e["🏠 重新登录页"]:::page
P2e -->|"重新引导"| P1
end
%% ================================================================
%% 阶段三:角色切换
%% ================================================================
subgraph 阶段三[阶段三:角色切换]
D_USER -->|"用户角色信息"| P3["🏠 个人中心"]:::page
P3 -->|"查看可用角色"| A14["🔗 POST /api/auth/roles"]:::api
A14 -->|"用户ID"| S14["⚙️ AuthService.getUserRoles()"]:::service
S14 -->|"角色列表"| D_ROLES["📦 user_roles 关联表"]:::data
D_ROLES -->|"家长角色"| P3a{"家长 / 孩子 / 规划师"}:::page
P3a -->|"家长→孩子"| P3b["🏠 切换到孩子视图"]:::page
P3b -->|"目标角色=child"| A15["🔗 POST /api/auth/switch-role"]:::api
A15 -->|"用户ID, 目标角色"| S15["⚙️ AuthService.switchRole()"]:::service
S15 -->|"新角色token"| D_JWT
P3a -->|"孩子→家长"| P3c["🏠 切换回家长视图"]:::page
P3c -->|"需密码校验?"| SW_VERIFY{"需密码校验?"}:::page
SW_VERIFY -->|"是"| P3d["🏠 输入家长密码"]:::page
P3d -->|"密码"| A16["🔗 POST /api/auth/switch-back-verify"]:::api
A16 -->|"用户ID, 密码"| S16["⚙️ AuthService.verifyAndSwitch()"]:::service
S16 -->|"校验通过, 新角色token"| D_JWT
SW_VERIFY -->|"否"| P3e["🏠 直接切换回家长"]
P3e -->|"目标角色=parent"| A17["🔗 POST /api/auth/switch-back-to-parent"]:::api
A17 -->|"用户ID"| S17["⚙️ AuthService.switchBackToParent()"]:::service
S17 -->|"新角色token"| D_JWT
P3a -->|"规划师"| P3f["🏠 切换到规划师视图"]:::page
P3f -->|"目标角色=teacher"| A15
end
%% ================================================================
%% 角色关联
%% ================================================================
ROLE_PARENT -.- P1
ROLE_PARENT -.- P2
ROLE_PARENT -.- P3
ROLE_CHILD -.- P1
ROLE_CHILD -.- P3c
ROLE_JWT -.- S_JWT
ROLE_JWT -.- S9
端点明细
注册登录
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/auth/send-code |
发送短信验证码 |
⚙️系统自动 |
{phone} |
{success, expireIn} |
POST /api/auth/phone-login |
手机号+验证码登录 |
📱小程序 |
{phone, code} |
{token, userInfo} |
POST /api/auth/wechat-phone-login |
微信手机号登录 |
📱小程序 |
{encryptedData, iv, code} |
{token, userInfo} |
POST /api/auth/silent-login |
微信静默登录(自动注册) |
📱小程序 |
{code} |
{token, userInfo, isNew} |
POST /api/auth/auto-login |
openid自动登录 |
📱小程序 |
{openid} |
{token, userInfo} |
POST /api/auth/register-with-idcard |
手机号+身份证注册登录 |
📱小程序 |
{phone, idCard, name} |
{token, userInfo} |
POST /api/auth/wechat-login |
微信code登录 |
📱小程序 |
{code} |
{token, userInfo} |
POST /api/auth/direct-register |
直接注册用户 |
📱小程序 |
{nickname, avatar} |
{token, userInfo} |
POST /api/auth/register-with-invite |
使用邀请码注册 |
📱小程序 |
{phone, inviteCode} |
{token, userInfo} |
认证与安全
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/auth/verify |
验证JWT Token有效性 |
⚙️系统自动 |
Header: Authorization: Bearer <token> |
{valid, userId, role} |
POST /api/auth/info |
获取当前用户信息 |
📱小程序 |
Header: Authorization: Bearer <token> |
User对象(含角色, 家庭信息) |
POST /api/auth/set-password |
设置密码 |
📱小程序 |
{password} |
{success} |
POST /api/auth/verify-password |
验证密码 |
📱小程序 |
{password} |
{valid} |
POST /api/auth/check-phone |
检查手机号是否已注册 |
📱小程序 |
{phone} |
{exists, registered} |
角色切换与用户管理
| 端点 |
说明 |
端口 |
请求数据 |
响应数据 |
POST /api/auth/switch-role |
切换到指定角色 |
📱小程序 |
{targetRole} |
{newToken, role} |
POST /api/auth/switch-back-to-parent |
切换回家长视图 |
📱小程序 |
— |
{newToken, role=parent} |
POST /api/auth/switch-back-verify |
密码校验后切换回家长 |
📱小程序 |
{password} |
{newToken, role=parent} |
POST /api/auth/roles |
获取用户角色列表 |
📱小程序 |
— |
{roles: [{role, familyId, ...}]} |
POST /api/user/info |
获取用户信息 |
📱小程序 |
Header: Authorization |
User对象 |
POST /api/user/update |
更新用户信息 |
📱小程序 |
{nickname, avatar, ...} |
{success} |
POST /api/user/children/list |
获取子女列表 |
📱小程序 |
— |
[Child对象] |
POST /api/user/family-members |
获取家庭成员列表 |
📱小程序 |
— |
[FamilyMember对象] |
POST /api/user/action-stats |
获取用户行动统计 |
📱小程序 |
— |
{taskCount, energyTotal, ...} |
完整性分析
| # |
维度 |
评估 |
说明 |
| 1 |
流程完整性 |
✅ 完整 |
覆盖新用户注册(5种方式)、老用户登录(3种方式)、认证校验、角色切换3个阶段,路径完整 |
| 2 |
异常路径 |
⚠️ 部分覆盖 |
Token过期引导重新登录已覆盖;注册时验证码错误、手机号已注册、邀请码无效等前端校验未画入图(业务逻辑在Service层处理) |
| 3 |
端点覆盖 |
✅ 完整 |
20个端点全部映射到流程图中,与代码实际暴露的/api/auth/*和/api/user/*一致 |
| 4 |
角色覆盖 |
✅ 完整 |
家长(parent)、孩子(child)、规划师(teacher)三种角色的注册/登录/切换均已覆盖;管理员(admin)使用管理后台独立登录流程,不在本图范围 |
| 5 |
数据实体 |
✅ 完整 |
users表、sms_codes表、user_roles关联表、JWT Token均在图中映射 |
| 6 |
一致性 |
✅ 与代码一致 |
所有端点路径与实际Controller(AuthController、UserController)中的@PostMapping匹配 |