449c6d4875
## H5 员工端 v4 (2026-07-13 00:48 已部署)
- 人工按钮三态文案统一为"人工坐席"
- 按钮位置移至发送键和语音按钮上方(垂直堆叠)
- 点按钮直接调 store.shakeAgent(),删除 CallAgentModal 弹窗动画
- 截图快捷键提示改为"截图->粘贴:Alt+Shift+A-Ctrl+V ---> Ctrl+V"
- 移动端隐藏截图提示(CSS 媒体查询)
- AI转人工提示改为"已为您呼叫人工坐席,请稍等!"
- 坐席接入提示改为"坐席正在查看您的信息,请等待处理回复!"
- 删除"摇铃呼叫坐席"入口和文案
- 删除孤儿组件 MessageList.vue + shake 动画 CSS
## H5 员工端 v5 (2026-07-13 02:08 已部署)
- RightPanel v2.1:删除"软件安装"和"资源权限"标签页
- 移除标签栏,智能推荐(DynamicRecommend)直接展示
- 删除 SoftwareDownloads/ApprovalLinks 引用和相关 CSS
## AI 对话链路全栈改造 Phase 1-6 (已部署)
- Phase 1: Dify JSON输出 + 后端blocking解析 + 双WS推送 + 错误降级
- Phase 2: 关键词收窄(~25强意图词) + 两级分类Prompt + 删除前端checkApprovalIntent
- Phase 3: WS扩展(ai_thinking+dynamic_recommend) + ai_structured气泡 + RightPanel v2 + 选项回传
- Phase 4: VisionService接入 + 图片消息融合(5秒窗口) + 降级策略
- Phase 5: 坐席端ai_thinking指示器 + ai_structured/byod_card渲染 + handleNewMessage修复
- Phase 6: diagnosis_stage(6值) + response_time_ms计时 + 慢响应告警(>10s)
## 坐席端 v5 (2026-07-13 01:38 已部署)
- ai_structured/byod_card 只读渲染
- AI思考指示器 UI
- handleNewMessage 透传 msg_type/extra_data 修复
- 布局优化v2.0: QuickReplyBar L1+L2悬浮 + ReplyBox左右分区 + 右栏260/560px切换
- 键盘快捷键v2.3: 纯数字路由 + ESC分层撤销 + Shift+Space用event.code
## 上下文感知智能诊断闭环 (2026-07-12 已部署)
- 三层诊断(API→Script→AI) + 三段排队(VIP→info_locked→not locked)
- 答题插队 + 五场景关闭
- 迁移052(6表+6列) + queue_service + quiz_service + closing_service
- H5前端: QueueWaiting + RightPanel双Tab + InputBar三态 + ResolveConfirmCard
- 坐席前端: pending_close结单流程 + 信息锁定(Dify步骤完成+有效回答率≥70%)
## 知识库迭代3 (2026-07-12 已部署)
- 分诊交互(H5+坐席+Dify独立应用)
- 拓扑预览(ECharts只读)
- 代答排除(4种匹配器: keyword/regex/intent/category)
- 迁移051 + 44文件43测试通过
## 后端变更
- 6个Python文件改造(h5_ai_task.py/h5.py/ai_service.py/closing_service.py等)
- funny_phrase_service.py: shake/connected/keyword 默认文案更新
- session_service.py: 企微消息文案同步
- 新增: queue.py/quiz.py/triage.py/exclusion_rules.py 等API端点
- 新增: diagnostic.py/quiz.py/triage_session.py 等模型
- 新增: closing_service/queue_service/quiz_service/triage_service 等服务
## 文档更新
- CHANGELOG.md: 新增 [未发布] 区全部变更记录
- 项目管理主文档 v2.5: 新增v0.7.3版本 + 已完成看板 + 最近搞定
- 版本记录: 新增v0.7.3条目
- AI对话链路实施计划: Phase 1-6 全部标记✅已实施
- 新增架构图/时序图/类图(mermaid)
## 部署路径修正
- 服务器项目根路径: /opt/wecom-it-desk/
- 所有前端dist均为ro bind mount,只能在宿主机源路径操作
- 服务器nginx /h5/ 是静态文件服务(非proxy_pass)
- elFinder上传二进制不可靠(MD5不匹配),改用base64分块上传
232 lines
8.1 KiB
YAML
232 lines
8.1 KiB
YAML
# =============================================================================
|
||
# 企微IT智能服务台 — Docker Compose(公司内网服务器版)
|
||
# =============================================================================
|
||
# 目标服务器:10.90.5.110
|
||
# 域名:itsupport.servyou.com.cn
|
||
#
|
||
# 用法:
|
||
# 1. 上传部署包到服务器
|
||
# 2. cp .env.example .env && vim .env # 填入真实配置
|
||
# 3. docker compose up -d # 启动所有服务
|
||
# 4. docker compose logs -f # 查看日志
|
||
#
|
||
# 架构:
|
||
# 客户端浏览器 → Nginx:80 → { /itdesk/, /itagent/, /itadmin/, /api/, /ws/ }
|
||
# =============================================================================
|
||
|
||
services:
|
||
# --------------------------------------------------------------------------
|
||
# PostgreSQL 16 — 持久化数据库
|
||
# --------------------------------------------------------------------------
|
||
postgres:
|
||
image: postgres:16-alpine
|
||
container_name: wecom_it_postgres
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_USER: ${POSTGRES_USER:-wecom}
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-wecom_secret}
|
||
POSTGRES_DB: ${POSTGRES_DB:-wecom_it_desk}
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-wecom}"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 5
|
||
networks:
|
||
- it-desk-internal
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Redis 7 — 缓存服务(token、会话、员工信息)
|
||
# --------------------------------------------------------------------------
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: wecom_it_redis
|
||
restart: unless-stopped
|
||
command: redis-server --appendonly yes --save 900 1 --save 300 10 --requirepass 'R3d!s@2026#Secure'
|
||
volumes:
|
||
- redis_data:/data
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "ping"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 5
|
||
networks:
|
||
- it-desk-internal
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Neo4j 5 — 知识图谱存储(社区版)
|
||
# --------------------------------------------------------------------------
|
||
neo4j:
|
||
image: neo4j:5-community
|
||
container_name: wecom_it_neo4j
|
||
restart: unless-stopped
|
||
environment:
|
||
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD}
|
||
NEO4J_PLUGINS: '["apoc"]'
|
||
volumes:
|
||
- neo4j_data:/data
|
||
- neo4j_logs:/logs
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "cypher-shell -u neo4j -p ${NEO4J_PASSWORD} 'RETURN 1'"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 10
|
||
networks:
|
||
- it-desk-internal
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
|
||
# --------------------------------------------------------------------------
|
||
# FastAPI 后端 — 核心业务服务
|
||
# --------------------------------------------------------------------------
|
||
backend:
|
||
build:
|
||
context: ./backend
|
||
dockerfile: Dockerfile
|
||
image: wecom-it-desk-backend:latest
|
||
container_name: wecom_it_backend
|
||
restart: unless-stopped
|
||
environment:
|
||
# 企微凭证
|
||
- WECOM_CORP_ID=${WECOM_CORP_ID}
|
||
- WECOM_AGENT_ID=${WECOM_AGENT_ID}
|
||
- WECOM_SECRET=${WECOM_SECRET}
|
||
- WECOM_APPROVAL_SECRET=${WECOM_APPROVAL_SECRET:-}
|
||
- WECOM_TOKEN=${WECOM_TOKEN}
|
||
- WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY}
|
||
# ITSM 运维平台(app_id/app_secret 待申请,先占位)
|
||
- ITSM_APP_ID=${ITSM_APP_ID:-}
|
||
- ITSM_APP_SECRET=${ITSM_APP_SECRET:-}
|
||
# 数据库(Docker 内部网络,用容器名通信)
|
||
- DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk}
|
||
# Redis(Docker 内部网络)
|
||
# Redis URL - 密码中的特殊字符需要URL编码 (#→%23)
|
||
- REDIS_URL=redis://:R3d%21s%402026%23Secure@redis:6379/0
|
||
# CORS
|
||
- CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn}
|
||
# AI 服务(Dify)
|
||
- DIFY_API_URL=${DIFY_API_URL}
|
||
- DIFY_API_KEY=${DIFY_API_KEY}
|
||
- DIFY_TIMEOUT=${DIFY_TIMEOUT:-30}
|
||
# AI Wingman(留空禁用)
|
||
- DIFY_WINGMAN_API_URL=${DIFY_WINGMAN_API_URL:-}
|
||
- DIFY_WINGMAN_API_KEY=${DIFY_WINGMAN_API_KEY:-}
|
||
- DIFY_WINGMAN_TIMEOUT=${DIFY_WINGMAN_TIMEOUT:-30}
|
||
# Neo4j 知识图谱
|
||
- NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687}
|
||
- NEO4J_USER=${NEO4J_USER:-neo4j}
|
||
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
|
||
- NEO4J_DATABASE=${NEO4J_DATABASE:-neo4j}
|
||
- NEO4J_MAX_CONNECTION_LIFETIME=${NEO4J_MAX_CONNECTION_LIFETIME:-3600}
|
||
- NEO4J_MAX_CONNECTION_POOL_SIZE=${NEO4J_MAX_CONNECTION_POOL_SIZE:-50}
|
||
# Mock 登录(生产环境默认关闭,如需临时调试请在 .env 中显式设置为 true)
|
||
- MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false}
|
||
# 终端页面基础URL(用于NE2005等终端生成二维码)
|
||
- TERMINAL_BASE_URL=${TERMINAL_BASE_URL:-https://itsupport.servyou.com.cn/itterminal/}
|
||
# 服务配置
|
||
- BACKEND_HOST=0.0.0.0
|
||
- BACKEND_PORT=8000
|
||
# 上传文件目录(持久化)
|
||
- UPLOAD_DIR=/app/uploads
|
||
# 运行期日志目录(供"运行期日志"管理页面读取,需与下方 volumes 挂载一致)
|
||
- RUNTIME_LOG_DIR=/app/logs
|
||
volumes:
|
||
# 代码热更新(生产环境:宿主机 ./app → 容器 /app/app)
|
||
- ./app:/app/app
|
||
- backend-uploads:/app/uploads
|
||
- ${RUNTIME_LOG_HOST_DIR:-/var/log/wecom-it-desk}:/app/logs
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
neo4j:
|
||
condition: service_healthy
|
||
command: >
|
||
/bin/sh -c "
|
||
echo '>>> 启动 API 服务 (跳过迁移)...' &&
|
||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 1
|
||
"
|
||
networks:
|
||
- it-desk-internal
|
||
healthcheck:
|
||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "20m"
|
||
max-file: "5"
|
||
|
||
# --------------------------------------------------------------------------
|
||
# Nginx — 反向代理 + 静态文件服务
|
||
# --------------------------------------------------------------------------
|
||
nginx:
|
||
image: nginx:1.27-alpine
|
||
container_name: wecom_it_nginx
|
||
restart: unless-stopped
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
volumes:
|
||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||
- ./nginx/ssl:/etc/nginx/ssl:ro
|
||
- ./frontend-h5/dist:/usr/share/nginx/html/itdesk:ro
|
||
- ./frontend-agent/dist:/usr/share/nginx/html/itagent:ro
|
||
- ./frontend-admin/dist:/usr/share/nginx/html/itadmin:ro
|
||
- ./frontend-portal/dist:/usr/share/nginx/html/itportal:ro
|
||
- ./frontend-terminal/dist:/usr/share/nginx/html/itterminal:ro
|
||
depends_on:
|
||
- backend
|
||
networks:
|
||
- it-desk-internal
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -f http://localhost:80/itdesk/health || exit 1"]
|
||
interval: 15s
|
||
timeout: 5s
|
||
retries: 3
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
|
||
# =============================================================================
|
||
# 网络
|
||
# =============================================================================
|
||
networks:
|
||
it-desk-internal:
|
||
driver: bridge
|
||
|
||
# =============================================================================
|
||
# 数据卷 — 持久化存储
|
||
# =============================================================================
|
||
volumes:
|
||
postgres_data:
|
||
name: wecom_it_postgres_data
|
||
redis_data:
|
||
name: wecom_it_redis_data
|
||
neo4j_data:
|
||
name: wecom_it_neo4j_data
|
||
neo4j_logs:
|
||
name: wecom_it_neo4j_logs
|
||
backend-uploads:
|
||
name: wecom_it_backend_uploads
|