Files
wecom_it_smart_desk/docs/04-运维文档/部署运维/NGINX-DOMAIN-ROUTING.md
T
Simon 44e77dcb0e chore(docs): docs/ 目录全面重新编号 + 重组
**重构前**(旧编号 02-11):
- docs/02-产品需求/      → 00 产品规划/PRD
- docs/03-技术架构/      → 01-05 子目录散落
- docs/04-原型设计/      → 01-02 产品设计(HTML 原型)
- docs/05-原型设计/      → screens/
- docs/06-测试素材/      → 02-E2E / 03-功能 / 04-版本测试
- docs/07-项目管理/      → 任务说明书/日报/计划
- docs/08-安全审计/      → 审计报告
- docs/09-堡垒运维/      → toolbox / deploy
- docs/10-项目管理/      → 任务说明书(重复)
- docs/11-历史归档/      → deploy-nas-archived

**重构后**(新编号 00-07,语义化):
- docs/00-产品开发流程与文档管理规范.md
- docs/00-版本迭代总览.md
- docs/01-产品文档/      (PRD/原型/认证/会话/AI 服务/坐席/集成)
- docs/02-技术文档/      (技术方案/架构图/重构记录/前端改造/实现配置)
- docs/03-测试文档/      (E2E/功能用例/版本报告/缺陷单)
- docs/04-运维文档/      (部署运维/运维指南)
- docs/05-运营文档/      (品牌推广/用户手册)
- docs/06-安全审计/      (审计报告)
- docs/07-项目管理/      (任务说明书/日报/计划/看板)

**净收益**:
- 目录编号与产品文档管理规范对齐(按文档阶段 01-07 编号)
- 消除 02-产品需求 与 10-项目管理 的编号重叠
- 子目录按文档类型分组(如 01-产品文档/00-产品规划、01-产品文档/01-认证与登录)
- 把运维/安全/项目管理从 0X 散落改为 04/06/07

合计 494 文件 + 78495 行 / - 14076 行
2026-08-03 18:46:55 +08:00

10 KiB

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

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 白名单(2026-07-06 更新 — 添加办公网IP)
    location /itadmin/ {
        # 允许的IP列表(按需求添加)
        allow 10.90.0.0/16;    # 内网段 - 税友内网
        allow 10.240.0.0/16;    # 内网段 - 办公网
        allow 117.147.35.138;   # 办公网出口IP
        allow 218.75.34.87;     # 办公网出口IP
        allow 127.0.0.1;        # 本地
        deny all;                # 其他拒绝

        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 严格白名单(与/itadmin/一致)
        location /api/admin/ {
            # 允许的IP列表(按需求添加)
            allow 10.90.0.0/16;    # 内网段 - 税友内网
            allow 10.240.0.0/16;    # 内网段 - 办公网
            allow 117.147.35.138;   # 办公网出口IP
            allow 218.75.34.87;     # 办公网出口IP
            allow 127.0.0.1;        # 本地
            deny all;                # 其他拒绝

            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;  # 容器映射到宿主机的端口
}

部署步骤

# 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 显示"已过期,点击刷新"

📚 相关文档


变更历史:

  • 2026-06-21 创建(Phase 1.3 task #16)