Files
wecom_it_smart_desk/docs/sequence-diagram.mermaid
T

100 lines
3.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
%% 4.1 员工端 OAuth 静默授权(snsapi_base → ?token= 镜像)
sequenceDiagram
participant U as 员工(企微WebView)
participant H5 as H5前端(/itdesk/)
participant R as 路由守卫
participant B as 后端(/api/h5)
participant W as 企微OAuth
U->>H5: 打开 /itdesk/
H5->>R: beforeEach 守卫
R->>R: 读 ?token=(无) / ?code=(无) / 无 token
R->>B: GET /h5/oauth/authorize (prod 校验 wxwork UA)
B-->>R: {authorize_url}
R->>W: 302 跳转企微授权页
W-->>H5: 回调 redirect_uri?code=CODE
H5->>B: GET /h5/oauth/sns-callback?code=CODE
B->>W: code 换 userid + 用户信息
B->>B: 生成 employee token 存 Redis(employee:token:)
B-->>H5: 302 /itdesk/?token=XXX
H5->>R: 守卫读 ?token=XXX
R->>R: localStorage.h5_token = XXXreplaceState 清除 URL
R->>B: 携带 Bearer 拉取用户信息
B-->>H5: 工作台数据(内层 data
%% 4.2 坐席/管理 扫码登录(auth_qrcode
sequenceDiagram
participant A as 坐席/管理员
participant FE as 前端登录页
participant B as 后端(/api/auth_qrcode)
participant WX as 企微App(扫码确认)
participant R as Redis
A->>FE: 点击「企微扫码登录」
FE->>B: POST /auth_qrcode/create
B->>R: 写 ticket(120s) + OAuth URL
B-->>FE: {ticket, qrcode_png_base64}
FE->>FE: 展示二维码 + 2s 轮询
loop 轮询
FE->>B: GET /auth_qrcode/poll/{ticket}
B-->>FE: {status: waiting/scanned}
end
WX->>B: GET /auth_qrcode/scan?code&state=ticket (企微OAuth回调)
B->>R: 写 scan:{ticket}
A->>WX: 在企微点「确认登录」
WX->>B: POST /auth_qrcode/confirm {ticket}
B->>B: 校验身份→签发 token(agent/admin)
B->>R: 写 confirm:{ticket}=token
FE->>B: GET /poll/{ticket} → {status:confirmed, token}
FE->>FE: localStorage.agent_token/admin_token = token
FE->>FE: 跳 /workspace 或 /
%% 4.3 坐席/管理 账号密码 + OTP
sequenceDiagram
participant A as 坐席/管理员
participant FE as 前端登录页
participant B as 后端(/api/agents/login)
participant M as MFAService/Redis
A->>FE: 输入账号+密码,点登录
FE->>B: POST /agents/login {user_id, password}
alt 已绑定 MFA 且无 otp_code
B-->>FE: {require_otp:true, user_id, name, role}(无 token
FE->>FE: 渲染 OTP 输入框(v-if requireOtp)
A->>FE: 输入 6 位 OTP
FE->>B: POST /agents/login {user_id, password, otp_code}
B->>M: verify_code(mfa_secret, otp_code)
M-->>B: True
B->>B: 签发 token
B-->>FE: {token, user_id, name, role}
else 未绑定 MFA
B-->>FE: {token, ...} 直接登录
end
FE->>FE: localStorage.agent_token/admin_token = token;跳主页
%% 4.4 令牌过期 / 401 处理
sequenceDiagram
participant FE as 三端前端
participant I as 响应拦截器
participant B as 后端
participant R as Redis
FE->>B: 业务请求(Bearer token)
B-->>FE: 401 / {code:1002}
alt H5 员工端
I->>I: 清 h5_token
alt 生产(有 CorpId)
I->>B: 重走 OAuth 重定向(带防循环计数)
else Mock(dev)
I->>FE: 跳 /itdesk/login
end
else 坐席端
I->>B: POST /api/auth/refresh?token=(静默)
B->>R: 延长 user:token TTL
alt 刷新成功
I->>FE: 重放原请求
else 失败
I->>I: 清 agent_token(不再清 portal_token
I->>FE: 跳 /login
end
else 管理端
I->>I: 清 admin_token
I->>FE: 跳 /login
end