Files
wecom_it_smart_desk/docs/01-产品文档/01-02产品设计/admin-dashboard-v1.html
T
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

767 lines
46 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IT智能服务台 — 管理后台 v1</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
:root {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-tertiary: #334155;
--bg-card: #1e293b;
--bg-hover: #334155;
--bg-active: #3b82f6;
--text-primary: #f1f5f9;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--accent: #3b82f6;
--accent-hover: #2563eb;
--accent-light: rgba(59,130,246,0.15);
--success: #10b981;
--success-bg: rgba(16,185,129,0.12);
--warning: #f59e0b;
--warning-bg: rgba(245,158,11,0.12);
--danger: #ef4444;
--danger-bg: rgba(239,68,68,0.12);
--border: rgba(148,163,184,0.12);
--border-hover: rgba(148,163,184,0.25);
--radius: 8px;
--radius-lg: 12px;
--shadow: 0 1px 3px rgba(0,0,0,0.3);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--bg-primary); color: var(--text-primary); height: 100vh; overflow: hidden; }
/* 布局 */
.layout { display: flex; height: 100vh; }
.sidebar { width: 220px; background: var(--bg-secondary); border-right: 1px solid var(--border); display: flex; flex-direction: column; flex-shrink: 0; }
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
.header { height: 56px; background: var(--bg-secondary); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; padding: 0 24px; }
.content { flex: 1; overflow-y: auto; padding: 24px; }
/* 侧边栏 */
.logo { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 10px; }
.logo-icon { width: 32px; height: 32px; background: linear-gradient(135deg, #3b82f6, #8b5cf6); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; }
.logo-text { font-size: 15px; font-weight: 600; }
.logo-sub { font-size: 10px; color: var(--text-muted); }
.nav-section { padding: 12px 0; }
.nav-section-title { padding: 0 20px; font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; }
.nav-item { display: flex; align-items: center; gap: 10px; padding: 10px 20px; cursor: pointer; color: var(--text-secondary); transition: all 0.2s; font-size: 13px; border-left: 3px solid transparent; }
.nav-item:hover { background: var(--bg-hover); color: var(--text-primary); }
.nav-item.active { background: var(--accent-light); color: var(--accent); border-left-color: var(--accent); }
.nav-item i { width: 18px; text-align: center; font-size: 14px; }
.nav-badge { margin-left: auto; background: var(--danger); color: white; font-size: 10px; padding: 1px 6px; border-radius: 10px; }
.nav-priority { font-size: 9px; padding: 1px 5px; border-radius: 3px; font-weight: 600; }
.p0 { background: rgba(239,68,68,0.15); color: #f87171; }
.p1 { background: rgba(245,158,11,0.15); color: #fbbf24; }
.p2 { background: rgba(16,185,129,0.15); color: #34d399; }
/* 头部 */
.header-left { display: flex; align-items: center; gap: 16px; }
.breadcrumb { font-size: 13px; color: var(--text-secondary); }
.breadcrumb span { color: var(--text-primary); }
.header-right { display: flex; align-items: center; gap: 16px; }
.header-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; }
/* 页面内容 */
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 4px; }
.page-desc { font-size: 13px; color: var(--text-secondary); margin-bottom: 24px; }
/* 统计卡片 */
.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
.stat-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; }
.stat-label { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; }
.stat-value { font-size: 28px; font-weight: 700; }
.stat-change { font-size: 11px; margin-top: 4px; }
.stat-up { color: var(--success); }
.stat-down { color: var(--danger); }
/* 表格 */
.table-wrapper { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; }
.table-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.table-title { font-size: 15px; font-weight: 600; }
table { width: 100%; border-collapse: collapse; }
th { padding: 12px 16px; text-align: left; font-size: 12px; color: var(--text-muted); font-weight: 500; border-bottom: 1px solid var(--border); background: var(--bg-tertiary); }
td { padding: 12px 16px; font-size: 13px; border-bottom: 1px solid var(--border); }
tr:hover td { background: var(--bg-hover); }
/* 按钮 */
.btn { padding: 8px 16px; border-radius: var(--radius); font-size: 13px; cursor: pointer; border: none; transition: all 0.2s; display: inline-flex; align-items: center; gap: 6px; }
.btn-primary { background: var(--accent); color: white; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-ghost { background: transparent; color: var(--text-secondary); border: 1px solid var(--border); }
.btn-ghost:hover { border-color: var(--border-hover); color: var(--text-primary); }
.btn-sm { padding: 4px 10px; font-size: 12px; }
/* 标签/徽章 */
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 500; }
.tag-success { background: var(--success-bg); color: var(--success); }
.tag-warning { background: var(--warning-bg); color: var(--warning); }
.tag-danger { background: var(--danger-bg); color: var(--danger); }
.tag-info { background: var(--accent-light); color: var(--accent); }
/* 开关 */
.switch { width: 40px; height: 22px; background: var(--bg-tertiary); border-radius: 11px; position: relative; cursor: pointer; transition: background 0.2s; }
.switch.on { background: var(--success); }
.switch::after { content: ''; width: 18px; height: 18px; background: white; border-radius: 50%; position: absolute; top: 2px; left: 2px; transition: transform 0.2s; }
.switch.on::after { transform: translateX(18px); }
/* 功能开关页面 */
.feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.feature-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; }
.feature-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.feature-card-title { font-size: 14px; font-weight: 600; }
.feature-card-desc { font-size: 12px; color: var(--text-secondary); margin-bottom: 12px; }
.feature-item { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-top: 1px solid var(--border); }
.feature-item-name { font-size: 13px; }
.feature-item-stage { font-size: 11px; color: var(--text-muted); }
/* 快速回复管理 */
.category-tabs { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.category-tab { padding: 6px 14px; border-radius: 20px; font-size: 12px; cursor: pointer; background: var(--bg-tertiary); color: var(--text-secondary); border: 1px solid transparent; transition: all 0.2s; }
.category-tab.active { background: var(--accent-light); color: var(--accent); border-color: var(--accent); }
.category-tab:hover { border-color: var(--border-hover); color: var(--text-primary); }
.reply-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-bottom: 10px; }
.reply-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.reply-card-title { font-size: 13px; font-weight: 600; }
.reply-card-content { font-size: 12px; color: var(--text-secondary); line-height: 1.6; background: var(--bg-primary); padding: 10px; border-radius: 6px; }
.reply-actions { display: flex; gap: 8px; }
/* 搜索框 */
.search-box { display: flex; align-items: center; background: var(--bg-primary); border: 1px solid var(--border); border-radius: var(--radius); padding: 0 12px; }
.search-box input { background: transparent; border: none; color: var(--text-primary); padding: 8px; font-size: 13px; outline: none; width: 200px; }
.search-box i { color: var(--text-muted); font-size: 13px; }
/* 页面容器(用于切换) */
.page { display: none; }
.page.active { display: block; }
/* 集成卡片 */
.integration-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.integration-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; text-align: center; }
.integration-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; margin: 0 auto 12px; }
.integration-name { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.integration-status { font-size: 12px; margin-bottom: 12px; }
.integration-detail { font-size: 11px; color: var(--text-muted); }
/* 分配模式 */
.mode-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; margin-bottom: 12px; display: flex; align-items: center; gap: 16px; }
.mode-radio { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--text-muted); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.mode-radio.selected { border-color: var(--accent); }
.mode-radio.selected::after { content: ''; width: 10px; height: 10px; border-radius: 50%; background: var(--accent); }
.mode-info { flex: 1; }
.mode-title { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
.mode-desc { font-size: 12px; color: var(--text-secondary); }
.mode-badge { font-size: 11px; padding: 2px 8px; border-radius: 4px; }
.mode-locked { opacity: 0.5; pointer-events: none; }
.mode-lock-text { font-size: 11px; color: var(--text-muted); font-style: italic; }
/* 滚动条 */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
</style>
</head>
<body>
<div class="layout">
<!-- 侧边栏 -->
<div class="sidebar">
<div class="logo">
<div class="logo-icon"><i class="fas fa-headset"></i></div>
<div>
<div class="logo-text">IT智能服务台</div>
<div class="logo-sub">管理后台 v1.0</div>
</div>
</div>
<div class="nav-section">
<div class="nav-section-title">概览</div>
<div class="nav-item active" onclick="switchPage('dashboard')">
<i class="fas fa-chart-pie"></i> 运营总览
</div>
</div>
<div class="nav-section">
<div class="nav-section-title">P0 核心配置</div>
<div class="nav-item" onclick="switchPage('features')">
<i class="fas fa-toggle-on"></i> 功能开关
<span class="nav-priority p0">P0</span>
</div>
<div class="nav-item" onclick="switchPage('agents')">
<i class="fas fa-users"></i> 坐席管理
<span class="nav-priority p0">P0</span>
</div>
<div class="nav-item" onclick="switchPage('integrations')">
<i class="fas fa-plug"></i> 系统集成
<span class="nav-priority p0">P0</span>
</div>
</div>
<div class="nav-section">
<div class="nav-section-title">P1 运营管理</div>
<div class="nav-item" onclick="switchPage('assignment')">
<i class="fas fa-random"></i> 分配模式
<span class="nav-priority p1">P1</span>
</div>
<div class="nav-item" onclick="switchPage('quickreply')">
<i class="fas fa-reply-all"></i> 快速回复
<span class="nav-priority p1">P1</span>
</div>
<div class="nav-item" onclick="switchPage('monitor')">
<i class="fas fa-desktop"></i> 会话监控
<span class="nav-priority p1">P1</span>
</div>
</div>
<div class="nav-section">
<div class="nav-section-title">P2 高级功能</div>
<div class="nav-item" onclick="switchPage('flowchart')">
<i class="fas fa-project-diagram"></i> 排查流程图
<span class="nav-priority p1">P1~P2</span>
</div>
<div class="nav-item" style="opacity:0.4">
<i class="fas fa-palette"></i> 主题模板
<span class="nav-priority p2">P2</span>
</div>
<div class="nav-item" style="opacity:0.4">
<i class="fas fa-chart-bar"></i> 数据看板
<span class="nav-priority p2">P2</span>
</div>
<div class="nav-item" style="opacity:0.4">
<i class="fas fa-book"></i> 知识库
<span class="nav-priority p2">P2</span>
</div>
</div>
</div>
<!-- 主内容区 -->
<div class="main">
<div class="header">
<div class="header-left">
<div class="breadcrumb">管理后台 / <span id="header-title">运营总览</span></div>
</div>
<div class="header-right">
<div class="search-box">
<i class="fas fa-search"></i>
<input type="text" placeholder="搜索功能或配置...">
</div>
<i class="fas fa-bell" style="color:var(--text-secondary);cursor:pointer"></i>
<div class="header-avatar"></div>
</div>
</div>
<div class="content">
<!-- ==================== 运营总览 ==================== -->
<div class="page active" id="page-dashboard">
<div class="page-title">运营总览</div>
<div class="page-desc">实时监控服务台运行状态,关键指标一目了然</div>
<div class="stats-row">
<div class="stat-card">
<div class="stat-label">在线坐席</div>
<div class="stat-value" style="color:var(--success)">2 <span style="font-size:14px;color:var(--text-muted)">/3</span></div>
<div class="stat-change stat-up"><i class="fas fa-circle" style="font-size:8px"></i> 运行正常</div>
</div>
<div class="stat-card">
<div class="stat-label">今日会话</div>
<div class="stat-value">47</div>
<div class="stat-change stat-up"><i class="fas fa-arrow-up"></i> +12% 较昨日</div>
</div>
<div class="stat-card">
<div class="stat-label">平均响应时间</div>
<div class="stat-value">1.8<span style="font-size:14px;color:var(--text-muted)">s</span></div>
<div class="stat-change stat-down"><i class="fas fa-arrow-down"></i> -0.3s 改善</div>
</div>
<div class="stat-card">
<div class="stat-label">AI 命中率</div>
<div class="stat-value">68<span style="font-size:14px;color:var(--text-muted)">%</span></div>
<div class="stat-change stat-up"><i class="fas fa-arrow-up"></i> +5% 本周</div>
</div>
</div>
<div style="display:grid;grid-template-columns:2fr 1fr;gap:16px">
<div class="table-wrapper">
<div class="table-header">
<div class="table-title">待处理事项</div>
<span class="tag tag-warning">3 项待审</span>
</div>
<table>
<thead><tr><th>类型</th><th>内容</th><th>提交人</th><th>时间</th><th>操作</th></tr></thead>
<tbody>
<tr><td><span class="tag tag-info">快速回复</span></td><td>VPN连接失败排查话术</td><td>张伟</td><td>10分钟前</td><td><button class="btn btn-sm btn-ghost">审核</button></td></tr>
<tr><td><span class="tag tag-warning">知识推荐</span></td><td>打印机脱机问题(同类18次)</td><td>系统</td><td>1小时前</td><td><button class="btn btn-sm btn-ghost">处理</button></td></tr>
<tr><td><span class="tag tag-danger">异常告警</span></td><td>坐席王丽会话超时未响应</td><td>系统</td><td>2小时前</td><td><button class="btn btn-sm btn-ghost">查看</button></td></tr>
</tbody>
</table>
</div>
<div class="table-wrapper">
<div class="table-header">
<div class="table-title">系统健康</div>
</div>
<div style="padding:16px">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
<span style="font-size:13px">Dify AI 引擎</span>
<span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 正常</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
<span style="font-size:13px">RAGFlow 知识库</span>
<span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 正常</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
<span style="font-size:13px">Redis 缓存</span>
<span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 正常</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
<span style="font-size:13px">PostgreSQL</span>
<span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 正常</span>
</div>
<div style="display:flex;justify-content:space-between;align-items:center">
<span style="font-size:13px">WebSocket 服务</span>
<span class="tag tag-warning"><i class="fas fa-circle" style="font-size:6px"></i> 2连接抖动</span>
</div>
</div>
</div>
</div>
</div>
<!-- ==================== 功能开关 ==================== -->
<div class="page" id="page-features">
<div class="page-title">功能开关 / 参数</div>
<div class="page-desc">按阶段控制功能开放,运行时切换无需改代码。配置变更即时生效,支持回滚。</div>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-robot" style="color:var(--accent);margin-right:6px"></i> AI 对话引擎</div>
<span class="tag tag-success">已启用</span>
</div>
<div class="feature-card-desc">Dify Agent + RAGFlow 检索增强,员工自助咨询</div>
<div class="feature-item"><span class="feature-item-name">AI 自动回复</span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">转人工关键词触发</span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">AI 命中阈值 <code style="color:var(--accent);font-size:11px">3次</code></span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
</div>
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-headset" style="color:var(--success);margin-right:6px"></i> 人工服务</div>
<span class="tag tag-success">已启用</span>
</div>
<div class="feature-card-desc">员工可摇铃呼叫坐席,坐席手动接单</div>
<div class="feature-item"><span class="feature-item-name">摇铃呼叫坐席</span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">手动接单模式</span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">邀请员工加入会话</span><div class="switch on" onclick="this.classList.toggle('on')"></div></div>
</div>
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-clock" style="color:var(--warning);margin-right:6px"></i> 排队系统</div>
<span class="tag tag-warning">阶段二</span>
</div>
<div class="feature-card-desc">坐席全忙时排队等待,支持优先级排序</div>
<div class="feature-item"><span class="feature-item-name">排队等待 <span class="feature-item-stage">阶段二</span></span><div class="switch" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">优先级排序 <span class="feature-item-stage">阶段二</span></span><div class="switch" onclick="this.classList.toggle('on')"></div></div>
</div>
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-star" style="color:#fbbf24;margin-right:6px"></i> 满意度评价</div>
<span class="tag tag-warning">阶段二</span>
</div>
<div class="feature-card-desc">会话结束后推送评价,统计满意度趋势</div>
<div class="feature-item"><span class="feature-item-name">评价推送 <span class="feature-item-stage">阶段二</span></span><div class="switch" onclick="this.classList.toggle('on')"></div></div>
<div class="feature-item"><span class="feature-item-name">评价统计 <span class="feature-item-stage">阶段二</span></span><div class="switch" onclick="this.classList.toggle('on')"></div></div>
</div>
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-shield-alt" style="color:var(--danger);margin-right:6px"></i> 应急模式</div>
<span class="tag tag-danger">当前关闭</span>
</div>
<div class="feature-card-desc">系统维护时降级,引导员工走企微原生通道</div>
<div class="feature-item"><span class="feature-item-name">应急模式开关</span><div class="switch" onclick="this.classList.toggle('on');updateEmergency(this)"></div></div>
</div>
<div class="feature-card">
<div class="feature-card-header">
<div class="feature-card-title"><i class="fas fa-key" style="color:var(--accent);margin-right:6px"></i> 关键词管理</div>
<span class="tag tag-success">已启用</span>
</div>
<div class="feature-card-desc">转人工/情绪关键词,JSON 格式存储</div>
<div class="feature-item"><span class="feature-item-name">转人工关键词 <code style="color:var(--accent);font-size:11px">转人工/人工/人工服务</code></span><button class="btn btn-sm btn-ghost">编辑</button></div>
<div class="feature-item"><span class="feature-item-name">情绪关键词 <code style="color:var(--accent);font-size:11px">投诉/差评/不满</code></span><button class="btn btn-sm btn-ghost">编辑</button></div>
</div>
</div>
</div>
<!-- ==================== 坐席管理 ==================== -->
<div class="page" id="page-agents">
<div class="page-title">坐席人员管理</div>
<div class="page-desc">坐席状态、技能标签、权限分级管理。技能标签与快速回复7大类对齐。</div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px">
<div style="display:flex;gap:8px">
<div class="category-tab active" onclick="filterAgents(this,'all')">全部 (3)</div>
<div class="category-tab" onclick="filterAgents(this,'online')">在线 (2)</div>
<div class="category-tab" onclick="filterAgents(this,'busy')">忙碌 (0)</div>
<div class="category-tab" onclick="filterAgents(this,'offline')">离线 (1)</div>
</div>
<button class="btn btn-primary"><i class="fas fa-plus"></i> 添加坐席</button>
</div>
<div class="table-wrapper">
<table>
<thead><tr><th>坐席</th><th>状态</th><th>技能标签</th><th>角色</th><th>当前/最大负载</th><th>今日结单</th><th>操作</th></tr></thead>
<tbody>
<tr>
<td><div style="display:flex;align-items:center;gap:10px"><div style="width:32px;height:32px;border-radius:50%;background:var(--accent-light);display:flex;align-items:center;justify-content:center;color:var(--accent);font-size:12px;font-weight:600"></div><div><div style="font-weight:500">宋献</div><div style="font-size:11px;color:var(--text-muted)">EMP001</div></div></div></td>
<td><span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 在线</span></td>
<td><span class="tag tag-info" style="margin:1px">电脑</span><span class="tag tag-info" style="margin:1px">网络</span><span class="tag tag-info" style="margin:1px">软件</span></td>
<td><span class="tag tag-warning">组长</span></td>
<td>3 / 5</td>
<td>12</td>
<td><button class="btn btn-sm btn-ghost">编辑</button></td>
</tr>
<tr>
<td><div style="display:flex;align-items:center;gap:10px"><div style="width:32px;height:32px;border-radius:50%;background:rgba(16,185,129,0.12);display:flex;align-items:center;justify-content:center;color:var(--success);font-size:12px;font-weight:600"></div><div><div style="font-weight:500">王丽</div><div style="font-size:11px;color:var(--text-muted)">EMP002</div></div></div></td>
<td><span class="tag tag-success"><i class="fas fa-circle" style="font-size:6px"></i> 在线</span></td>
<td><span class="tag tag-info" style="margin:1px">外设</span><span class="tag tag-info" style="margin:1px">安全</span></td>
<td><span class="tag tag-info">坐席</span></td>
<td>2 / 5</td>
<td>8</td>
<td><button class="btn btn-sm btn-ghost">编辑</button></td>
</tr>
<tr>
<td><div style="display:flex;align-items:center;gap:10px"><div style="width:32px;height:32px;border-radius:50%;background:rgba(100,116,139,0.12);display:flex;align-items:center;justify-content:center;color:var(--text-muted);font-size:12px;font-weight:600"></div><div><div style="font-weight:500">张伟</div><div style="font-size:11px;color:var(--text-muted)">EMP003</div></div></div></td>
<td><span class="tag" style="background:var(--bg-tertiary);color:var(--text-muted)"><i class="fas fa-circle" style="font-size:6px"></i> 离线</span></td>
<td><span class="tag tag-info" style="margin:1px">资产</span><span class="tag tag-info" style="margin:1px">其他</span></td>
<td><span class="tag tag-info">坐席</span></td>
<td>0 / 5</td>
<td>0</td>
<td><button class="btn btn-sm btn-ghost">编辑</button></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 系统集成 ==================== -->
<div class="page" id="page-integrations">
<div class="page-title">外部系统集成</div>
<div class="page-desc">管理后台管「配置和参数」,Dify 网页管「Workflow 逻辑」,两者边界明确。</div>
<div class="integration-grid">
<div class="integration-card">
<div class="integration-icon" style="background:var(--accent-light);color:var(--accent)"><i class="fas fa-brain"></i></div>
<div class="integration-name">Dify AI</div>
<div class="integration-status"><span class="tag tag-success">已连接</span></div>
<div class="integration-detail">Agent URL/Key · 连接测试<br>Agent 状态查看</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">配置</button> <button class="btn btn-sm btn-ghost">测试</button></div>
</div>
<div class="integration-card">
<div class="integration-icon" style="background:var(--success-bg);color:var(--success)"><i class="fas fa-database"></i></div>
<div class="integration-name">RAGFlow</div>
<div class="integration-status"><span class="tag tag-warning">部分集成</span></div>
<div class="integration-detail">API URL/Key · 知识库列表<br>同步状态查看</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">配置</button></div>
</div>
<div class="integration-card">
<div class="integration-icon" style="background:var(--warning-bg);color:var(--warning)"><i class="fas fa-chart-line"></i></div>
<div class="integration-name">数据平台</div>
<div class="integration-status"><span class="tag" style="background:var(--bg-tertiary);color:var(--text-muted)">未连接</span></div>
<div class="integration-detail">数据库连接 · 看板 URL<br>同步状态</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">配置</button></div>
</div>
<div class="integration-card">
<div class="integration-icon" style="background:rgba(139,92,246,0.12);color:#8b5cf6"><i class="fas fa-id-card"></i></div>
<div class="integration-name">北森 eHR</div>
<div class="integration-status"><span class="tag" style="background:var(--bg-tertiary);color:var(--text-muted)">未连接</span></div>
<div class="integration-detail">OAuth2 · 员工信息<br>任职信息 API</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">配置</button></div>
</div>
<div class="integration-card">
<div class="integration-icon" style="background:var(--danger-bg);color:var(--danger)"><i class="fas fa-shield-virus"></i></div>
<div class="integration-name">火绒安全</div>
<div class="integration-status"><span class="tag" style="background:var(--bg-tertiary);color:var(--text-muted)">未连接</span></div>
<div class="integration-detail">AccessKey · 终端查询<br>病毒库/漏洞状态</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">配置</button></div>
</div>
<div class="integration-card">
<div class="integration-icon" style="background:rgba(236,72,153,0.12);color:#ec4899"><i class="fas fa-laptop-code"></i></div>
<div class="integration-name">联软安全</div>
<div class="integration-status"><span class="tag" style="background:var(--bg-tertiary);color:var(--text-muted)">待确认</span></div>
<div class="integration-detail">API 开放性待确认<br>需联系终端安全团队</div>
<div style="margin-top:12px"><button class="btn btn-sm btn-ghost">申请</button></div>
</div>
</div>
</div>
<!-- ==================== 分配模式 ==================== -->
<div class="page" id="page-assignment">
<div class="page-title">消息分配模式</div>
<div class="page-desc">当前坐席1人足以承担,手动接单完全满足。后续模式按坐席规模自动解锁。</div>
<div class="mode-card" style="border-color:var(--accent)">
<div class="mode-radio selected"></div>
<div class="mode-info">
<div class="mode-title">手动接单 <span class="mode-badge tag tag-success">当前启用</span></div>
<div class="mode-desc">坐席在待办列表中自行选择接单。AB 角色冗余设计,1 人即可承担。</div>
</div>
</div>
<div class="mode-card mode-locked">
<div class="mode-radio"></div>
<div class="mode-info">
<div class="mode-title">轮询分配 <span class="mode-badge tag tag-info">P2</span></div>
<div class="mode-desc">按坐席列表顺序依次分配,循环往复。</div>
<div class="mode-lock-text"><i class="fas fa-lock" style="margin-right:4px"></i> 坐席人数不足3人,暂不需要</div>
</div>
</div>
<div class="mode-card mode-locked">
<div class="mode-radio"></div>
<div class="mode-info">
<div class="mode-title">最少活跃优先 <span class="mode-badge tag tag-info">P2</span></div>
<div class="mode-desc">自动分配给当前活跃会话数最少的坐席。</div>
<div class="mode-lock-text"><i class="fas fa-lock" style="margin-right:4px"></i> 坐席人数不足3人,暂不需要</div>
</div>
</div>
<div class="mode-card mode-locked">
<div class="mode-radio"></div>
<div class="mode-info">
<div class="mode-title">加权比例分配 <span class="mode-badge" style="background:var(--bg-tertiary);color:var(--text-muted)">P3</span></div>
<div class="mode-desc">按坐席权重分配(如高级权重2、初级权重1)。</div>
<div class="mode-lock-text"><i class="fas fa-lock" style="margin-right:4px"></i> 坐席人数不足5人,暂不需要</div>
</div>
</div>
<div class="mode-card mode-locked">
<div class="mode-radio"></div>
<div class="mode-info">
<div class="mode-title">技能匹配分配 <span class="mode-badge" style="background:var(--bg-tertiary);color:var(--text-muted)">P3</span></div>
<div class="mode-desc">根据问题类别匹配坐席技能标签。</div>
<div class="mode-lock-text"><i class="fas fa-lock" style="margin-right:4px"></i> 需坐席≥5人 + 技能标签体系成熟</div>
</div>
</div>
<div class="mode-card mode-locked">
<div class="mode-radio"></div>
<div class="mode-info">
<div class="mode-title">优先队列 <span class="mode-badge" style="background:var(--bg-tertiary);color:var(--text-muted)">P3</span></div>
<div class="mode-desc">紧急/阻断性问题优先路由到高级坐席/组长。</div>
<div class="mode-lock-text"><i class="fas fa-lock" style="margin-right:4px"></i> 需坐席≥5人 + 紧急度评分上线</div>
</div>
</div>
</div>
<!-- ==================== 快速回复管理 ==================== -->
<div class="page" id="page-quickreply">
<div class="page-title">快速回复管理</div>
<div class="page-desc">分类管理 + 版本历史 + 审核发布流程。坐席提交→组长审核→全员可见。</div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
<div class="category-tabs">
<div class="category-tab active" onclick="filterCategory(this)">全部 (28)</div>
<div class="category-tab" onclick="filterCategory(this)">电脑 (6)</div>
<div class="category-tab" onclick="filterCategory(this)">软件 (5)</div>
<div class="category-tab" onclick="filterCategory(this)">外设 (4)</div>
<div class="category-tab" onclick="filterCategory(this)">网络 (5)</div>
<div class="category-tab" onclick="filterCategory(this)">安全 (3)</div>
<div class="category-tab" onclick="filterCategory(this)">资产 (3)</div>
<div class="category-tab" onclick="filterCategory(this)">其他 (2)</div>
</div>
<button class="btn btn-primary"><i class="fas fa-plus"></i> 新增模板</button>
</div>
<div class="reply-card">
<div class="reply-card-header">
<div class="reply-card-title"><span class="tag tag-info" style="margin-right:8px">网络</span> VPN连接失败排查</div>
<div class="reply-actions">
<span class="tag tag-success">已审核</span>
<button class="btn btn-sm btn-ghost"><i class="fas fa-edit"></i></button>
<button class="btn btn-sm btn-ghost"><i class="fas fa-history"></i></button>
</div>
</div>
<div class="reply-card-content">您好{employee_name}VPN连接失败请按以下步骤排查:<br>1. 确认网络连接正常<br>2. 检查VPN客户端是否最新版本<br>3. 尝试重新输入密码<br>4. 如仍无法连接,请提供错误截图</div>
<div style="font-size:11px;color:var(--text-muted);margin-top:8px">变量: employee_name · 最后更新: 2026-06-10 · 版本 v3</div>
</div>
<div class="reply-card">
<div class="reply-card-header">
<div class="reply-card-title"><span class="tag tag-info" style="margin-right:8px">电脑</span> 电脑蓝屏处理话术</div>
<div class="reply-actions">
<span class="tag tag-success">已审核</span>
<button class="btn btn-sm btn-ghost"><i class="fas fa-edit"></i></button>
<button class="btn btn-sm btn-ghost"><i class="fas fa-history"></i></button>
</div>
</div>
<div class="reply-card-content">您好,电脑蓝屏请不要慌张,请尝试以下操作:<br>1. 长按电源键10秒强制关机,再重新开机<br>2. 如频繁蓝屏,请记录错误代码(如 IRQL_NOT_LESS_OR_EQUAL<br>3. 联系IT支持获取进一步帮助</div>
<div style="font-size:11px;color:var(--text-muted);margin-top:8px">最后更新: 2026-06-08 · 版本 v2</div>
</div>
<div class="reply-card" style="border-color:var(--warning)">
<div class="reply-card-header">
<div class="reply-card-title"><span class="tag tag-info" style="margin-right:8px">安全</span> 密码重置引导(新)</div>
<div class="reply-actions">
<span class="tag tag-warning">待审核</span>
<button class="btn btn-sm btn-primary">通过</button>
<button class="btn btn-sm btn-ghost">驳回</button>
</div>
</div>
<div class="reply-card-content">您好{employee_name},密码重置请按以下操作:<br>1. 访问自助密码重置门户<br>2. 输入工号验证身份<br>3. 设置新密码(需包含大小写+数字+特殊字符)<br>4. 等待5分钟同步生效</div>
<div style="font-size:11px;color:var(--text-muted);margin-top:8px">提交人: 张伟 · 提交时间: 2026-06-11 · 仅提交人可用</div>
</div>
</div>
<!-- ==================== 会话监控 ==================== -->
<div class="page" id="page-monitor">
<div class="page-title">会话监控</div>
<div class="page-desc">实时查看坐席工作状态、会话队列、异常告警。阶段二功能,当前为 Demo 预览。</div>
<div class="stats-row">
<div class="stat-card">
<div class="stat-label">进行中会话</div>
<div class="stat-value" style="color:var(--accent)">5</div>
</div>
<div class="stat-card">
<div class="stat-label">等待中</div>
<div class="stat-value" style="color:var(--warning)">0</div>
</div>
<div class="stat-card">
<div class="stat-label">今日已结单</div>
<div class="stat-value" style="color:var(--success)">42</div>
</div>
<div class="stat-card">
<div class="stat-label">异常告警</div>
<div class="stat-value" style="color:var(--danger)">1</div>
</div>
</div>
<div class="table-wrapper">
<div class="table-header">
<div class="table-title">实时会话</div>
<span class="tag tag-info">Demo 预览</span>
</div>
<table>
<thead><tr><th>会话ID</th><th>员工</th><th>坐席</th><th>持续时长</th><th>消息数</th><th>状态</th></tr></thead>
<tbody>
<tr><td>#C042</td><td>李明 (EMP101)</td><td>宋献</td><td>5分32秒</td><td>8</td><td><span class="tag tag-success">进行中</span></td></tr>
<tr><td>#C041</td><td>赵刚 (EMP205)</td><td>宋献</td><td>12分08秒</td><td>14</td><td><span class="tag tag-success">进行中</span></td></tr>
<tr><td>#C040</td><td>孙芳 (EMP312)</td><td>王丽</td><td>8分45秒</td><td>6</td><td><span class="tag tag-warning">超时未响应</span></td></tr>
<tr><td>#C039</td><td>周磊 (EMP088)</td><td>宋献</td><td>3分12秒</td><td>4</td><td><span class="tag tag-success">进行中</span></td></tr>
<tr><td>#C038</td><td>吴婷 (EMP156)</td><td>王丽</td><td>1分56秒</td><td>2</td><td><span class="tag tag-info">AI 对话中</span></td></tr>
</tbody>
</table>
</div>
</div>
<!-- ==================== 排查流程图 ==================== -->
<div class="page" id="page-flowchart">
<div class="page-title">排查流程图管理</div>
<div class="page-desc">JSON 导入导出 + 预览 + 版本管理。阶段三开始实现,后续升级为可视化拖拽编辑。</div>
<div style="display:flex;gap:12px;margin-bottom:20px">
<button class="btn btn-primary"><i class="fas fa-file-import"></i> 导入 JSON</button>
<button class="btn btn-ghost"><i class="fas fa-file-export"></i> 导出全部</button>
<button class="btn btn-ghost"><i class="fas fa-plus"></i> 新建流程图</button>
</div>
<div class="table-wrapper">
<table>
<thead><tr><th>流程图名称</th><th>分类</th><th>节点数</th><th>版本</th><th>最后更新</th><th>状态</th><th>操作</th></tr></thead>
<tbody>
<tr><td><i class="fas fa-project-diagram" style="color:var(--accent);margin-right:6px"></i>VPN连接故障排查</td><td><span class="tag tag-info">网络</span></td><td>12</td><td>v2.1</td><td>2026-06-10</td><td><span class="tag tag-success">已发布</span></td><td><button class="btn btn-sm btn-ghost">预览</button> <button class="btn btn-sm btn-ghost">编辑</button></td></tr>
<tr><td><i class="fas fa-project-diagram" style="color:var(--accent);margin-right:6px"></i>打印机脱机排查</td><td><span class="tag tag-info">外设</span></td><td>8</td><td>v1.3</td><td>2026-06-08</td><td><span class="tag tag-success">已发布</span></td><td><button class="btn btn-sm btn-ghost">预览</button> <button class="btn btn-sm btn-ghost">编辑</button></td></tr>
<tr><td><i class="fas fa-project-diagram" style="color:var(--accent);margin-right:6px"></i>邮箱登录失败排查</td><td><span class="tag tag-info">软件</span></td><td>10</td><td>v1.0</td><td>2026-06-06</td><td><span class="tag tag-warning">草稿</span></td><td><button class="btn btn-sm btn-ghost">预览</button> <button class="btn btn-sm btn-ghost">编辑</button></td></tr>
</tbody>
</table>
</div>
<div style="margin-top:24px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius-lg);padding:20px">
<div style="font-size:14px;font-weight:600;margin-bottom:12px"><i class="fas fa-road" style="color:var(--accent);margin-right:6px"></i> 实现路径</div>
<div style="display:flex;gap:12px;align-items:center">
<div style="background:var(--accent-light);border:1px solid var(--accent);border-radius:var(--radius);padding:12px 16px;flex:1;text-align:center">
<div style="font-size:12px;color:var(--accent);font-weight:500">Step 1</div>
<div style="font-size:13px;margin-top:4px">JSON 导入导出 + 预览</div>
<div style="font-size:11px;color:var(--text-muted)">阶段三 3B</div>
</div>
<i class="fas fa-arrow-right" style="color:var(--text-muted)"></i>
<div style="background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px;flex:1;text-align:center">
<div style="font-size:12px;color:var(--text-muted);font-weight:500">Step 2</div>
<div style="font-size:13px;margin-top:4px">导出为 Dify 变量</div>
<div style="font-size:11px;color:var(--text-muted)">阶段四 4A</div>
</div>
<i class="fas fa-arrow-right" style="color:var(--text-muted)"></i>
<div style="background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px;flex:1;text-align:center">
<div style="font-size:12px;color:var(--text-muted);font-weight:500">Step 3</div>
<div style="font-size:13px;margin-top:4px">Dify HTTP 回调</div>
<div style="font-size:11px;color:var(--text-muted)">阶段四</div>
</div>
<i class="fas fa-arrow-right" style="color:var(--text-muted)"></i>
<div style="background:var(--bg-primary);border:1px solid var(--border);border-radius:var(--radius);padding:12px 16px;flex:1;text-align:center">
<div style="font-size:12px;color:var(--text-muted);font-weight:500">Step 4</div>
<div style="font-size:13px;margin-top:4px">可视化拖拽编辑</div>
<div style="font-size:11px;color:var(--text-muted)">远景</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function switchPage(pageId) {
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
document.getElementById('page-' + pageId).classList.add('active');
event.currentTarget.classList.add('active');
var titles = {
dashboard: '运营总览',
features: '功能开关/参数',
agents: '坐席人员管理',
integrations: '外部系统集成',
assignment: '消息分配模式',
quickreply: '快速回复管理',
monitor: '会话监控',
flowchart: '排查流程图管理'
};
document.getElementById('header-title').textContent = titles[pageId] || pageId;
}
function filterAgents(el, status) {
el.parentElement.querySelectorAll('.category-tab').forEach(t => t.classList.remove('active'));
el.classList.add('active');
}
function filterCategory(el) {
el.parentElement.querySelectorAll('.category-tab').forEach(t => t.classList.remove('active'));
el.classList.add('active');
}
function updateEmergency(sw) {
var card = sw.closest('.feature-card');
var badge = card.querySelector('.feature-card-header .tag');
if (sw.classList.contains('on')) {
badge.className = 'tag tag-danger';
badge.textContent = '已启用';
} else {
badge.className = 'tag tag-danger';
badge.textContent = '当前关闭';
}
}
</script>
</body>
</html>