c3899594d0
- 新建 frontend-portal/src/api/qrcode.ts — /api/auth_qrcode/* API 适配
- 新建 frontend-portal/src/composables/useQrcodeLogin.ts — 扫码核心逻辑
- 新建 frontend-portal/src/views/QrcodeLogin.vue — Portal 扫码登录 UI
- 扫码成功后按角色自动跳:
- 只有 admin → /itadmin/
- 只有 agent → /itagent/
- admin+agent → /itportal/select(多角色)
- 默认 user → /itdesk/
- 改 frontend-portal/src/router/index.ts — 默认 / → /qrcode-login
(原 PortalSelect.vue 保留作多角色 fallback)
- 新建 docs/NGINX-DOMAIN-ROUTING.md — 运维域名分发配置模板
build: ✅ frontend-portal vue-tsc + vite build 通过
QrcodeLogin chunk 4.82 kB
256 lines
9.5 KiB
Markdown
256 lines
9.5 KiB
Markdown
# Nginx 域名路由分发配置(Phase 1.3 task #16)
|
|
|
|
> 创建:2026-06-21
|
|
> 适用版本:v0.7.0+ (Phase 1.3 扫码登录上线后)
|
|
|
|
## 🎯 目标
|
|
|
|
不同入口域名/子路径 → 不同前端应用,但所有请求共用同一个后端 API。
|
|
|
|
| 入口 | URL | 前端应用 | 用途 |
|
|
|---|---|---|---|
|
|
| **坐席端** | `https://itsupport.servyou.com.cn/itagent/` | `frontend-agent/dist` | 坐席工作台 |
|
|
| **管理端** | `https://itsupport.servyou.com.cn/itadmin/` | `frontend-admin/dist` | 管理后台 |
|
|
| **Portal 统一入口** | `https://itsupport.servyou.com.cn/itportal/` | `frontend-portal/dist` | 扫码登录 + 多角色选择 |
|
|
| **H5 员工端** | `https://itsupport.servyou.com.cn/itdesk/` | `frontend-h5/dist` | 员工端(企微内) |
|
|
|
|
> **两种方案**:单域名多路径(本项目当前)+ 多子域名(可选升级)
|
|
|
|
---
|
|
|
|
## 🅰️ 方案 A:单域名 + 多子路径(推荐,运维简单)
|
|
|
|
### nginx server block
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl;
|
|
server_name itsupport.servyou.com.cn;
|
|
|
|
# SSL 证书(由公司统一管理)
|
|
ssl_certificate /etc/nginx/certs/itsupport.servyou.com.cn.crt;
|
|
ssl_certificate_key /etc/nginx/certs/itsupport.servyou.com.cn.key;
|
|
|
|
# 通用安全头
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
|
|
# ========================================================================
|
|
# 1. Portal 统一入口(扫码登录)
|
|
# ========================================================================
|
|
location /itportal/ {
|
|
alias /opt/wecom-it-desk/frontend-portal/dist/;
|
|
try_files $uri $uri/ /itportal/index.html;
|
|
|
|
# 允许企业微信 OAuth 回调(测试期)
|
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
}
|
|
|
|
# ========================================================================
|
|
# 2. 坐席工作台
|
|
# ========================================================================
|
|
location /itagent/ {
|
|
alias /opt/wecom-it-desk/frontend-agent/dist/;
|
|
try_files $uri $uri/ /itagent/index.html;
|
|
}
|
|
|
|
# ========================================================================
|
|
# 3. 管理后台
|
|
# ========================================================================
|
|
# IP 白名单(临时方案,v1.0 前收窄 — 见 ip-whitelist-trust-proxies-todo.md)
|
|
location /itadmin/ {
|
|
allow 0.0.0.0/0; # ⚠️ 临时全开
|
|
# allow 10.90.0.0/16; # TODO 收窄到内网
|
|
# allow 115.236.188.3; # 公网入口 IP
|
|
|
|
alias /opt/wecom-it-desk/frontend-admin/dist/;
|
|
try_files $uri $uri/ /itadmin/index.html;
|
|
}
|
|
|
|
# ========================================================================
|
|
# 4. H5 员工端
|
|
# ========================================================================
|
|
location /itdesk/ {
|
|
alias /opt/wecom-it-desk/frontend-h5/dist/;
|
|
try_files $uri $uri/ /itdesk/index.html;
|
|
|
|
# 允许嵌入到企微 WebView
|
|
add_header X-Frame-Options "ALLOW-FROM https://work.weixin.qq.com" always;
|
|
}
|
|
|
|
# ========================================================================
|
|
# 5. 后端 API(4 个端共用)
|
|
# ========================================================================
|
|
location /api/ {
|
|
# 管理端 API 严格白名单
|
|
location /api/admin/ {
|
|
allow 0.0.0.0/0; # ⚠️ 临时全开
|
|
# allow 10.90.0.0/16; # TODO 收窄
|
|
# allow 115.236.188.3;
|
|
|
|
proxy_pass http://wecom_it_backend;
|
|
}
|
|
|
|
# 其他 API 放行
|
|
proxy_pass http://wecom_it_backend;
|
|
}
|
|
|
|
# ========================================================================
|
|
# 6. WebSocket(坐席端 WS-01 鉴权)
|
|
# ========================================================================
|
|
location /ws/ {
|
|
proxy_pass http://wecom_it_backend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
# WS 心跳
|
|
proxy_read_timeout 600s;
|
|
}
|
|
|
|
# ========================================================================
|
|
# 7. 静态资源(图片/上传文件)
|
|
# ========================================================================
|
|
location /api/media/ {
|
|
proxy_pass http://wecom_it_backend;
|
|
proxy_set_header Host $host;
|
|
# 上传文件 30 天缓存
|
|
expires 30d;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
# ========================================================================
|
|
# 8. 根路径 → Portal 统一入口
|
|
# ========================================================================
|
|
location = / {
|
|
return 302 /itportal/;
|
|
}
|
|
}
|
|
|
|
# upstream 后端(内网容器)
|
|
upstream wecom_it_backend {
|
|
server 127.0.0.1:8000; # 容器映射到宿主机的端口
|
|
}
|
|
```
|
|
|
|
### 部署步骤
|
|
|
|
```bash
|
|
# 1. 上传 dist 文件(各前端 build 产物)
|
|
scp -r frontend-portal/dist root@10.90.5.110:/opt/wecom-it-desk/frontend-portal/
|
|
scp -r frontend-agent/dist root@10.90.5.110:/opt/wecom-it-desk/frontend-agent/
|
|
scp -r frontend-admin/dist root@10.90.5.110:/opt/wecom-it-desk/frontend-admin/
|
|
scp -r frontend-h5/dist root@10.90.5.110:/opt/wecom-it-desk/frontend-h5/
|
|
|
|
# 2. 上传 nginx 配置(本地 + 堡垒机 PuTTY)
|
|
# 参考:feedback-putty-not-openssh.md(用 PuTTY 操作)
|
|
|
|
# 3. 验证配置
|
|
sudo nginx -t
|
|
|
|
# 4. reload
|
|
sudo nginx -s reload
|
|
|
|
# 5. 验证(本地或企微)
|
|
curl -I https://itsupport.servyou.com.cn/itportal/
|
|
```
|
|
|
|
---
|
|
|
|
## 🅱️ 方案 B:多子域名(可选升级,需要 DNS 解析)
|
|
|
|
| 子域名 | 解析到 | 用途 |
|
|
|---|---|---|
|
|
| `portal.itsupport.servyou.com.cn` | nginx:443 | 统一入口 |
|
|
| `agent.itsupport.servyou.com.cn` | nginx:443 | 坐席工作台 |
|
|
| `admin.itsupport.servyou.com.cn` | nginx:443 | 管理后台(内网白名单) |
|
|
| `h5.itsupport.servyou.com.cn` | nginx:443 | H5 员工端 |
|
|
|
|
### 优点
|
|
- 跨域 cookie 隔离更清晰
|
|
- 每个子域可独立上 HTTPS 证书
|
|
- 内网白名单更容易配置(直接 deny all 到 admin.*)
|
|
|
|
### 缺点
|
|
- 需要运维额外加 4 个 A 记录
|
|
- 前端跨域 API 调用要 CORS 配全
|
|
- 坐席/管理员跨域切换要 CORS preflight
|
|
|
|
**当前 v0.7.0 推荐方案 A**,v1.0 再考虑方案 B。
|
|
|
|
---
|
|
|
|
## 🔄 扫码登录流程(方案 A 下)
|
|
|
|
```
|
|
[1] 用户访问 https://itsupport.servyou.com.cn/itagent/
|
|
→ nginx 命中 location /itagent/ → 返回 frontend-agent/dist/index.html
|
|
→ 前端路由守卫检查 localStorage.agent_token,没有 → 跳 /itportal/
|
|
|
|
[2] 用户访问 https://itsupport.servyou.com.cn/itportal/
|
|
→ nginx 命中 location /itportal/ → 返回 frontend-portal/dist/index.html
|
|
→ QrcodeLogin.vue 显示二维码
|
|
|
|
[3] 员工用企微扫码
|
|
→ 企微 OAuth 回调到后端 → 后端写 Redis qrcode:scan:{ticket}
|
|
→ Portal 轮询 /api/auth_qrcode/poll/{ticket} → 拿到 status=scanned
|
|
→ UI 显示"请在手机上确认登录"
|
|
|
|
[4] 员工在手机上点"确认登录"
|
|
→ 后端 /api/auth_qrcode/confirm → 创建 token → 写 Redis qrcode:confirm:{ticket}
|
|
→ Portal 轮询拿到 status=confirmed + token + roles
|
|
|
|
[5] Portal 按角色分发(见 QrcodeLogin.vue dispatchToRole)
|
|
- 只有 agent → window.location.href = /itagent/?token=xxx
|
|
- 只有 admin → window.location.href = /itadmin/?token=xxx
|
|
- admin + agent → window.location.href = /itportal/select(让用户选)
|
|
- 默认 user → window.location.href = /itdesk/?token=xxx
|
|
|
|
[6] 目标端 Login.vue 读 ?token=xxx 写入 localStorage + 跳 /workspace
|
|
```
|
|
|
|
---
|
|
|
|
## ⚠️ 已知问题 & TODO
|
|
|
|
| 问题 | 状态 | 备注 |
|
|
|---|---|---|
|
|
| `/itadmin/` IP 白名单临时全开 | 🟡 临时 | v1.0 前必须收窄(见 `ip-whitelist-trust-proxies-todo.md`) |
|
|
| `/api/admin/` IP 白名单临时全开 | 🟡 临时 | 同上 |
|
|
| H5 端需要企微内访问 | 🟢 保持 | 用户决策,H5 仍在企微内是主场景 |
|
|
| 跨子路径刷新 404 | 🟢 已处理 | `try_files $uri $uri/ /itagent/index.html` |
|
|
| 静态资源 cache | 🟡 待优化 | 可加 version hash 强制刷新 |
|
|
| admin Login.vue 仍用表单 | 🟡 待改 | 后续 task:重写 admin Login 为扫码 UI |
|
|
|
|
---
|
|
|
|
## 🧪 验证清单
|
|
|
|
部署完成后,在以下场景测试:
|
|
|
|
- [ ] 浏览器直接访问 `/itportal/` → 显示扫码二维码
|
|
- [ ] 用企微扫码 + 确认 → Portal 自动跳到对应端
|
|
- [ ] 坐席(只有 agent 角色)扫码 → 自动跳 `/itagent/?token=xxx` → 自动登录进 /workspace
|
|
- [ ] 管理员(只有 admin 角色)扫码 → 自动跳 `/itadmin/?token=xxx` → 进 admin dashboard
|
|
- [ ] 多角色用户(admin + agent)扫码 → 跳 `/itportal/select` → 看到选择页
|
|
- [ ] H5(企微内) → 仍走企微 OAuth,扫码二维码区域正常
|
|
- [ ] 浏览器直接访问 `/itagent/workspace`(没 token)→ 跳 `/itportal/`
|
|
- [ ] 扫码登录 120s 过期 → UI 显示"已过期,点击刷新"
|
|
|
|
---
|
|
|
|
## 📚 相关文档
|
|
|
|
- [project-knowledge-base.md](../memory/project-knowledge-base.md) — 项目知识库
|
|
- [feedback-wecom-only-external-urls.md](../memory/feedback-wecom-only-external-urls.md) — 企微入口约束(部分解除)
|
|
- [phase1-progress.md](../memory/phase1-progress.md) — Phase 1+2 进度
|
|
- [deployment.md](../memory/deployment.md) — 部署经验
|
|
- [nginx-container-name-wecom-it-nginx.md](../memory/nginx-container-name-wecom-it-nginx.md) — 容器名坑
|
|
|
|
---
|
|
|
|
**变更历史**:
|
|
- 2026-06-21 创建(Phase 1.3 task #16) |