# 任务说明书 — 审批流程系统 > **版本**: v1.0 | **日期**: 2026-07-10 --- ## 📋 基本信息 | 项目 | 内容 | |------|------| | **任务名称** | 审批类型扩展 + 卡片URL直跳 + 同窗口导航 + 免登录研究 | | **任务ID** | #113-115 | | **优先级** | 🟡 P2 | | **类型** | 功能开发 | | **状态** | ✅ 已完成并部署 | | **负责人** | 开发团队(software-approval-expand / software-approval-nav 团队) | | **创建日期** | 2026-07-10 | | **完成日期** | 2026-07-10 | --- ## 📥 输入项来源 ### 产品需求 | 来源文档 | 相关章节 | 说明 | |----------|----------|------| | `01-产品文档/IT智能服务台-产品需求文档PRD-v2.md` | §v2.2 增量需求 P2-07~P2-11 | 审批类型扩展、卡片URL关联、导航方式、免登录研究 | | `02-技术文档/实现配置/approval_templates.json` | 全文 | 18个审批流程的结构化数据源 | | `02-技术文档/实现配置/dify_approval_system_prompt_v2.0.md` | 全文 | Dify意图识别System Prompt v2 | | `01-产品文档/外来资料-IT审批与运维流程清单.xlsx` | 全文 | 原始审批流程清单(18行) | ### 技术架构 | 来源文档 | 相关章节 | 说明 | |----------|----------|------| | `02-技术文档/技术架构/IT智能服务台-系统架构设计文档v2.md` | §15.4.3~15.4.8 | 审批模板扩展、意图识别链路、前端卡片架构、导航方案选型、跨应用免登录、后端API | --- ## 📝 任务详情 ### 子任务 #113:审批类型扩展与卡片URL直跳 #### 背景 原系统仅支持 5 种审批类型(设备申请、账号权限、软件服务、资产处置、办公用品),Dify 意图识别也仅覆盖这 5 类。根据 `IT审批与运维流程清单.xlsx`,实际需要覆盖 12 种审批类型 / 18 个审批流程(企微审批 12 个 + 运维平台 6 个)。 #### 实现内容 **后端** (`backend/app/api/approval.py`): - `APPROVAL_TEMPLATES` 从 5 个扩展到 18 个(静态硬编码,含完整 URL、keywords、location) - `APPROVAL_PREFILTER_KEYWORDS` 从 5 类扩展到 12 类关键词 - `KEYWORD_TO_APPROVAL_TYPE` 扩展为 12 类映射 - 新增 7 种类型:会议室故障报修、企业应用管理、资产变更确认、终端设备网络准入、活动与会议技术支持、员工IT支持与故障报修、公共邮箱账号申请 - 意图识别三级链路保持不变:关键词预过滤 → Dify原生API → 关键词降级兜底 **前端** (`frontend-h5/src/components/chat/ApprovalCardModal.vue`): - `ApprovalOption` 接口新增 `url?: string` 字段 - `APPROVAL_OPTIONS` 从 5 类扩展到 12 类 / 17 个选项,每个选项携带完整审批 URL - `handleSelect` 优先检查 `option.url`,有则直接跳转;无则 fallback 到后端模板匹配 **Dify**: - System Prompt v2 覆盖全部 12 种审批类型,含示例、匹配规则、置信度评分指南 - 已由管理员手动粘贴发布到 Dify 后台 **数据文件**: - `approval_templates.json` — 18 个审批流程的结构化数据(id, name, category, location, template_id, url, keywords, icon, desc) - `dify_approval_system_prompt_v2.md` — Dify 应用的完整 System Prompt 文本 #### 审批流程清单(18个) | # | 审批类型 | 流程名称 | 平台 | |---|---------|---------|------| | 1 | 设备申请 | IT设备领用申请 | 企微审批 | | 2 | 设备申请 | IT设备外修申请 | 企微审批 | | 3 | 账号权限申请 | VPN权限申请 | 企微审批 | | 4 | 账号权限申请 | 企微外联权限申请 | 企微审批 | | 5 | 软件服务申请 | 商业软件服务申请 | 企微审批 | | 6 | 资产处置申请 | IT资产报废申请 | 企微审批 | | 7 | 资产处置申请 | IT资产退还申请 | 企微审批 | | 8 | 办公用品申请 | 办公用品超额领用审批 | 企微审批 | | 9 | 会议室故障报修 | 会议室故障报修 | 企微审批 | | 10 | 企业应用管理 | 企业应用管理 | 企微审批 | | 11 | 资产变更确认 | 资产变更确认 | 企微审批 | | 12 | 员工IT支持与故障报修 | 员工IT支持与故障报修 | 企微审批 | | 13 | 终端设备网络准入 | 终端设备网络准入申请 | 运维平台 | | 14 | 终端设备网络准入 | 终端设备网络准入-会议室设备 | 运维平台 | | 15 | 活动与会议技术支持 | 大型活动技术保障申请 | 运维平台 | | 16 | 活动与会议技术支持 | 会议技术支持申请 | 运维平台 | | 17 | 公共邮箱账号申请 | 公共邮箱账号申请 | 运维平台 | | 18 | 员工IT支持与故障报修 | 故障报修工单 | 运维平台 | --- ### 子任务 #114:审批卡片同窗口导航改造 #### 背景 初始实现使用 `window.open(url, '_blank')` 在新标签页打开审批页面。在企微 H5 webview 内,新标签页体验不佳(用户需手动切换标签页)。改为同窗口导航 `window.location.href = url`,由企微原生提供顶部返回按钮。 #### 安全头分析 生产环境 H5 页面设置了以下安全头,阻止跨域 iframe 嵌入: | 安全头 | 当前值 | 影响 | |--------|--------|------| | CSP `default-src` | `'self'`(无 `frame-src`) | 只允许同域 iframe | | COEP | `require-corp` | 跨域资源必须带 CORP 头 | | CORP | `same-origin` | H5 自身资源仅同域可加载 | **结论**:不改安全头的情况下,同窗口导航(方案 A)是最佳选择。企微审批 URL 本身未设 `X-Frame-Options`,但 COEP 这一层仍会拦截 iframe。 #### 方案选型 | 方案 | 说明 | 改动量 | 风险 | 选型 | |------|------|--------|------|------| | A. 同窗口导航 | `location.href = url`,企微原生返回 | 1行 | 零 | ✅ 已采用 | | B. iframe嵌入 | 自定义返回/关闭覆盖层 | 需改COEP/CSP | 降低安全级别 | 待评估 | | C. 同源代理 | 后端代理iframe | 复杂度高 | 可能破坏JS/cookie | 不推荐 | #### 代码改动 文件 `frontend-h5/src/components/chat/ApprovalCardModal.vue`: ```typescript // 改动1:handleSelect 中 option.url 分支 // Before: window.open(option.url, '_blank'); showToast('已打开审批页面'); // After: window.location.href = option.url; // 改动2:handleSelect 中 fallback 匹配分支 // Before: window.open(result.url, '_blank'); showToast('已打开审批页面'); // After: window.location.href = result.url; ``` 移除两处 `showToast` 调用(页面立即跳转,toast 不可见)。 --- ### 子任务 #115:企微跨应用免登录可行性研究 #### 背景 IT智能服务台 H5 与一站式运维平台同为税友集团企微下的自建应用(同一 corpid)。用户从 IT 服务台 H5 点击运维平台审批链接时,是否需要重新登录? #### 结论 **可行**。同一 corpid 下的自建应用各自独立走 OAuth2 `snsapi_base` 静默授权: 1. 用户从 IT 服务台 H5 点击运维平台链接 2. 运维平台检测到未登录 → 自动发起 OAuth2 `snsapi_base` 静默授权 3. 企微 webview 自动带上 corpid 凭证 → 运维平台后端拿到 `userid` 4. 用户无感知完成登录 **前提条件**: - 运维平台已配置企微可信域名 - 运维平台已实现 OAuth2 回调后端逻辑 - 两个应用在同一企微 corpid 下 **企微审批 URL** (`app.work.weixin.qq.com`):企微内置浏览器打开时自动登录,无需额外配置。 --- ## 🔧 技术方案 ### 后端 API 端点 | 端点 | 方法 | 说明 | 认证 | |------|------|------|------| | `/approval/templates` | GET | 返回全部18个审批模板 | 需要 | | `/approval/keywords` | GET | 返回12类审批关键词映射 | 需要 | | `/approval/detect` | POST | 意图识别(关键词预过滤 → Dify → 降级兜底) | 需要 | | `/approval/jump/{template_id}` | POST | 创建审批跳转 | 需要 | ### 意图识别三级链路 ``` 用户消息 ↓ 1. 关键词预过滤 (_keyword_prefilter) 命中 → 返回模板 未命中 ↓ 2. Dify 原生 API (app-7jkRkAzvX4QM9v9SM3P8mMEO) 返回 is_approval_request + approval_type 置信度 ≥ 0.7 → 匹配模板 未命中 ↓ 3. 关键词降级兜底 (_fallback_detect) 模糊匹配 → 返回模板或 None ``` ### 前端组件架构 ``` ApprovalCardModal.vue ├── ApprovalOption 接口 { name, icon, desc, url? } ├── APPROVAL_OPTIONS (12类 / 17选项,每个带 url) ├── handleSelect(option) │ ├── option.url 存在 → window.location.href = option.url │ └── fallback → 调后端 /approval/detect → /approval/jump ├── loadKeywords() → 从后端加载关键词列表 └── onMounted → 初始化 ``` --- ## 📦 交付物清单 ### 代码文件 | 文件 | 改动类型 | 说明 | |------|---------|------| | `backend/app/api/approval.py` | 修改 | 18个模板+12类关键词+映射表 | | `frontend-h5/src/components/chat/ApprovalCardModal.vue` | 修改 | 12类卡片+URL直跳+同窗口导航 | ### 数据文件 | 文件 | 说明 | |------|------| | `02-技术文档/实现配置/approval_templates.json` | 18个审批流程结构化数据 | | `02-技术文档/实现配置/dify_approval_system_prompt_v2.md` | Dify System Prompt v2全文 | | `02-技术文档/实现配置/IT审批与运维流程清单.xlsx` | 原始数据源 | ### 文档更新 | 文档 | 更新内容 | |------|---------| | `01-产品文档/` | IT智能服务台产品需求文档 | | `docs/02-技术文档/技术架构/IT智能服务台-系统架构设计文档v2.md` | §15.4.3~15.4.8 扩展 | | `docs/07-项目管理/任务说明书/IT智能服务台-项目管理主文档.md` | 新增 #113-115 任务 | --- ## ✅ 验证结果 | 验证项 | 方法 | 结果 | |--------|------|------| | 后端 API 模板列表 | `docker exec wecom_it_backend curl -s http://localhost:8000/approval/templates` | ✅ 返回18个模板 | | 后端 API 关键词 | `docker exec wecom_it_backend curl -s http://localhost:8000/approval/keywords` | ✅ 12类关键词映射正确 | | 前端 H5 页面可访问 | `docker exec wecom_it_nginx curl -s -o /dev/null -w '%{http_code}' http://localhost/h5/` | ✅ HTTP 301(正常重定向) | | nginx 容器文件 | `docker exec wecom_it_nginx ls /usr/share/nginx/html/h5/` | ✅ assets/ + index.html 齐全 | | 浏览器渲染 | agent-browser 打开 H5 URL | ✅ 登录页正常渲染,无JS报错 | | 生产容器状态 | `docker ps` | ✅ backend healthy / nginx running | | 企微内实测 | 用户手动测试 | ✅ 企微审批+运维平台审批均通过 | | Dify 意图识别 | 用户手动测试 | ✅ Dify v2 已发布,识别新增7种类型 | --- ## 📌 已知非阻塞项 | 项 | 说明 | 影响 | |----|------|------| | `import os` 未使用 | `approval.py` 中 `os.getenv` 调用被移除后,`import os` 变为未使用 | Linter警告,不影响运行 | | `it_device_repair` 模板 | 后端模板中有 `it_device_repair` 但前端"设备申请"下无对应选项 | 不影响功能,该模板通过意图识别仍可触发 | --- ## 🚀 部署记录 | 步骤 | 操作 | 时间 | |------|------|------| | 后端文件上传 | `v2_ops.py upload` → `/tmp/approval_v2.py` | 2026-07-10 | | 后端替换+重启 | `cp /tmp/approval_v2.py` + `docker compose restart backend` | 2026-07-10 | | 前端构建 | `npm run build`(465 modules, 3.18s) | 2026-07-10 | | 前端打包上传 | `tar -czf` → `v2_ops.py upload` | 2026-07-10 | | 前端解压+重启 | `tar -xzf` + `docker compose restart nginx` | 2026-07-10 | | 导航改造部署 | 同上流程(第二次部署) | 2026-07-10 | | 临时文件清理 | `/tmp/approval_v2.py` + `/tmp/frontend-h5-dist*.tar.gz` | 2026-07-10 | | Dify System Prompt | 用户手动粘贴发布 | 2026-07-10 | --- ## 📎 关联文档 | 文档 | 位置 | |------|------| | PRD v2 | `01-产品文档/` | | 架构设计 v2 | `02-技术文档/技术架构/IT智能服务台-系统架构设计文档v2.md` | | 审批模板数据 | `02-技术文档/实现配置/approval_templates.json` | | Dify Prompt v2 | `02-技术文档/实现配置/dify_approval_system_prompt_v2.md` | | 原始清单 | `02-技术文档/实现配置/` |