Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v1.9-员工端落地版.archive.html
T

407 lines
19 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">
<title>工具栏统一设计 v1.9 - 员工端落地版</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
background: linear-gradient(135deg, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
color: #1a1a1a;
padding: 24px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
min-height: 100vh;
}
h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #1a1a1a; }
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 32px 0 12px; color: #1a1a1a; }
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 20px; }
/* === 员工端会话窗口(落地版)— 连续表面、无内部区隔线 === */
.chatpanel-mock {
width: 100%;
max-width: 720px;
margin: 0 auto;
background: linear-gradient(180deg, rgba(255,255,255,0.95) 0%, rgba(247,248,252,0.95) 100%);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.9);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
overflow: hidden;
position: relative;
}
.chatpanel-mock-header {
padding: 12px 16px;
border-bottom: 1px solid rgba(99, 102, 241, 0.1); /* 仅窗口标题栏分隔 */
background: rgba(255, 255, 255, 0.4);
font-size: 13px;
color: #374151;
display: flex;
align-items: center;
gap: 8px;
}
.chatpanel-mock-header .dot { width: 8px; height: 8px; border-radius: 50%; background: #10b981; }
.chatpanel-mock-header .title { font-weight: 600; }
.chatpanel-mock-header .sub { color: #9ca3af; font-size: 11.5px; }
/* === 消息流区域(员工端会话窗口)— 透明背景,融入连续表面 === */
.chatpanel-mock-messages {
min-height: 250px;
padding: 20px 16px;
background: transparent;
display: flex;
flex-direction: column;
gap: 10px;
}
.mock-msg {
max-width: 74%;
padding: 9px 13px;
border-radius: 14px;
font-size: 13px;
line-height: 1.55;
}
.mock-msg .who { font-size: 10.5px; opacity: 0.65; margin-bottom: 3px; }
.mock-msg.user {
align-self: flex-end;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: #fff;
border-bottom-right-radius: 4px;
}
.mock-msg.ai {
align-self: flex-start;
background: rgba(99, 102, 241, 0.06);
color: #1a1a1a;
border: 1px solid rgba(99, 102, 241, 0.1);
border-bottom-left-radius: 4px;
}
.mock-msg.ai .quick {
margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap;
}
.mock-msg.ai .quick span {
font-size: 11.5px; padding: 4px 10px; border-radius: 12px;
background: rgba(99, 102, 241, 0.08); color: #4f46e5; border: 1px solid rgba(99, 102, 241, 0.15);
}
/* === gem 工具栏 band — 透明、无上下边框,融于连续表面 === */
.gem-band {
background: transparent;
padding: 8px 0 12px;
display: flex;
justify-content: center;
}
.gem-toolbar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 0 16px;
width: fit-content;
height: 84px;
}
.gem-toolbar-bg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 0;
pointer-events: none;
overflow: visible;
}
.gem-row { position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 12px; }
.gem-toolbar .agent-btn.gem {
width: 60px; height: 60px; margin: 0 6px; z-index: 3; box-shadow: none;
}
.gem-toolbar .glass-btn { z-index: 2; }
/* === InputBar(消息输入区)— 透明背景、无顶部边框,仅输入框本身为控件 === */
.inputbar-mock {
background: transparent;
padding: 4px 16px 16px;
position: relative;
}
.inputbar-mock-field {
width: 100%;
min-height: 56px;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(99, 102, 241, 0.12);
border-radius: 12px;
padding: 10px 14px;
font-size: 13px;
color: #9ca3af;
line-height: 1.6;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset;
}
.inputbar-mock-field .send {
margin-left: 12px;
padding: 7px 18px;
border-radius: 10px;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
color: #fff; font-size: 13px; font-weight: 600;
box-shadow: 0 2px 6px rgba(99,102,241,0.25);
}
/* === 通用按钮 === */
.glass-btn {
width: 40px; height: 40px;
border: 1px solid rgba(255, 255, 255, 0.6);
background: rgba(255, 255, 255, 0.55);
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
border-radius: 50%;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
-webkit-tap-highlight-color: transparent;
position: relative; z-index: 2;
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 4px rgba(0,0,0,0.04);
}
.glass-btn:hover { background: rgba(255,255,255,0.75); transform: translateY(-1px) scale(1.06); }
.glass-btn:active { transform: translateY(0) scale(0.95); }
.glass-btn svg { width: 22px; height: 22px; display: block; }
/* 可见的 focus 态(键盘可达性) */
.glass-btn:focus-visible,
.agent-btn:focus-visible,
.inputbar-mock-field:focus-within {
outline: 2px solid #6366f1;
outline-offset: 2px;
}
.agent-btn {
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
position: relative; z-index: 2;
padding: 0;
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%) padding-box;
}
.agent-btn::before {
content: ""; position: absolute; inset: -2px; border-radius: 50%;
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%); z-index: -1;
}
.agent-btn img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; object-position: center 15%; display: block; }
.agent-badge { position: absolute; bottom: 0; right: 0; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; z-index: 3; box-shadow: 0 1px 2px rgba(0,0,0,0.2); }
.agent-badge.is-online { background: #10b981; }
/* === 提示块 / 表格 / 落地清单 === */
.note-info { background: rgba(219, 234, 254, 0.6); border-left: 3px solid #3b82f6; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #1e3a8a; margin: 16px 0; backdrop-filter: blur(10px); }
.note-success { background: rgba(209, 250, 229, 0.6); border-left: 3px solid #10b981; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #064e3b; margin: 16px 0; backdrop-filter: blur(10px); }
.note { background: rgba(254, 243, 199, 0.6); border-left: 3px solid #d97706; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #78350f; margin: 16px 0; backdrop-filter: blur(10px); }
table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
thead tr { background: rgba(255, 255, 255, 0.6); }
th { border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; text-align: left; font-weight: 600; }
td { border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; }
.checklist li { list-style: none; padding-left: 22px; position: relative; line-height: 1.9; font-size: 13px; }
.checklist li::before { content: "□"; position: absolute; left: 4px; color: #6366f1; font-weight: 700; }
.checklist li.done::before { content: "☑"; color: #10b981; }
</style>
</head>
<body>
<svg width="0" height="0" style="position: absolute;">
<defs>
<linearGradient id="g-emoji" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#fde68a"/><stop offset="60%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#d97706"/>
</linearGradient>
<radialGradient id="g-emoji-blush" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="rgba(244, 63, 94, 0.4)"/>
<stop offset="100%" stop-color="rgba(244, 63, 94, 0)"/>
</radialGradient>
<linearGradient id="g-highlight" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="white" stop-opacity="0.7"/>
<stop offset="100%" stop-color="white" stop-opacity="0"/>
</linearGradient>
<linearGradient id="g-doc-body" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/><stop offset="100%" stop-color="#dbeafe"/>
</linearGradient>
<linearGradient id="g-doc-fold" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#6366f1"/>
</linearGradient>
<linearGradient id="g-doc-text" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#a855f7"/>
</linearGradient>
<linearGradient id="g-mic-body" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#c4b5fd"/><stop offset="50%" stop-color="#8b5cf6"/><stop offset="100%" stop-color="#6d28d9"/>
</linearGradient>
<linearGradient id="g-group" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#a5b4fc"/><stop offset="100%" stop-color="#c4b5fd"/>
</linearGradient>
<linearGradient id="g-group-strong" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#6366f1"/><stop offset="50%" stop-color="#a855f7"/><stop offset="100%" stop-color="#ec4899"/>
</linearGradient>
<linearGradient id="g-rail" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#818cf8" stop-opacity="0.5"/>
<stop offset="50%" stop-color="#c4b5fd" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#818cf8" stop-opacity="0.5"/>
</linearGradient>
</defs>
</svg>
<h1>工具栏统一设计 v1.9 — <span style="color:#047857;">员工端落地版</span></h1>
<p class="meta">把 v1.9「圆润拱形 + 三区无边框融合」效果正式落到员工端会话窗口 · 作为 <strong>输入区主 CTA 工具栏</strong> 的最终视觉方案 · 2026-08-05</p>
<div class="note-success">
<strong>本版作为员工端落地交付</strong>:圆润拱形轨道 + 三区融为连续浅色表面(无内部区隔线,仅保留窗口标题栏 chrome 分隔) + 工具栏作为唯一浮起玻璃元素嵌于「会话消息区 ↔ 消息输入区」之间。配套交付开发时请连同下方「落地检查清单」一并同步。
<br>
🔄 <strong>最终微调(更圆润)</strong>:穹顶区间由 x 96..204 拓宽至 <strong>x 84..216</strong>(更宽弧线铺开);顶点控制点 (126,6)/(186,6)、顶点 (156,4);底端镜像。顶点切线更平、曲率半径更大 → 顶端视觉上更接近真正的圆顶。
</div>
<h2>🎯 员工端落地效果(最终视觉)</h2>
<div class="chatpanel-mock">
<div class="chatpanel-mock-header">
<span class="dot"></span>
<span class="title">IT 智能服务台</span>
<span class="sub">· 在线 · 工单 #SR-20260805-0392</span>
</div>
<div class="chatpanel-mock-messages">
<div class="mock-msg user">
<div class="who"></div>
你好,我的 VPN 连不上,提示 691 错误,影响今天远程办公。
</div>
<div class="mock-msg ai">
<div class="who">智能助手</div>
您好,VPN 691 通常是账号密码错误或账号被锁定。已为您查询:账号状态正常、未过期。<br>
建议先自助排查:① 确认密码未过期;② 在 portal 重置密码后重试。
<div class="quick">
<span>重置 VPN 密码</span><span>查看排障指引</span><span>转人工坐席</span>
</div>
</div>
<div class="mock-msg user">
<div class="who"></div>
重置了还是不行,麻烦转人工。
</div>
<div class="mock-msg ai">
<div class="who">智能助手</div>
已为您转接人工坐席,请稍候。也可点击下方工具栏「人工坐席」按钮随时发起通话。
</div>
</div>
<div class="gem-band">
<div class="gem-toolbar">
<svg class="gem-toolbar-bg" viewBox="0 0 312 84" preserveAspectRatio="xMidYMid meet"
aria-hidden="true" role="presentation">
<path d="M 18 18
L 84 18
C 116 18, 126 6, 156 4
C 186 6, 196 18, 216 18
L 294 18
C 302 18, 312 26, 312 34
L 312 50
C 312 58, 302 66, 294 66
L 216 66
C 196 66, 186 78, 156 80
C 126 78, 116 66, 84 66
L 18 66
C 0 66, 0 58, 0 50
L 0 34
C 0 26, 10 18, 18 18 Z"
fill="url(#g-rail)" stroke="rgba(255,255,255,0.85)" stroke-width="1.2"/>
</svg>
<div class="gem-row">
<button class="glass-btn" title="表情" aria-label="表情">
<svg viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
</svg>
</button>
<button class="glass-btn" title="文件" aria-label="文件">
<svg viewBox="0 0 24 24" fill="none">
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8"/>
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8"/>
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
</svg>
</button>
<button class="agent-btn gem" title="人工坐席" aria-label="转接人工坐席">
<img src="./agent-avatar-v0.8.jpg" alt="人工坐席"/>
<span class="agent-badge is-online" aria-label="在线"></span>
</button>
<button class="glass-btn" title="语音输入" aria-label="语音输入">
<svg viewBox="0 0 24 24" fill="none">
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2"/>
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2"/>
</svg>
</button>
<button class="glass-btn" title="群聊" aria-label="发起群聊">
<svg viewBox="0 0 24 24" fill="none">
<circle cx="8" cy="9" r="2.2" fill="url(#g-group)"/>
<path d="M5 16 Q5 13 8 13 Q11 13 11 16 Z" fill="url(#g-group)"/>
<circle cx="16" cy="9" r="2.2" fill="url(#g-group)"/>
<path d="M13 16 Q13 13 16 13 Q19 13 19 16 Z" fill="url(#g-group)"/>
<circle cx="12" cy="10.5" r="2.8" fill="url(#g-group-strong)"/>
<path d="M8.5 18.5 Q8.5 14 12 14 Q15.5 14 15.5 18.5 Z" fill="url(#g-group-strong)"/>
</svg>
</button>
</div>
</div>
</div>
<div class="inputbar-mock">
<div class="inputbar-mock-field" tabindex="0">
<span>描述您的问题,或点击上方工具栏发起操作…</span>
<span class="send">发送</span>
</div>
</div>
</div>
<h2>📋 员工端落地检查清单</h2>
<ul class="checklist">
<li class="done">圆角长方形 + 中央圆润拱形轨道(SVG path 已固化)</li>
<li class="done">人工坐席按钮 60px 居中、不探出、无光晕</li>
<li class="done">两端 4 个工具按钮(emoji/文件/语音/群聊)保持 40px 圆形玻璃,在轨道内不溢出</li>
<li class="done">消息区 / gem 工具栏 / InputBar 三区融为连续浅色表面,无内部区隔线</li>
<li class="done">仅窗口标题栏保留 chrome 分隔(border-bottom</li>
<li class="done">键盘可达:所有按钮 <code>title</code> + <code>aria-label</code>,可见 <code>:focus-visible</code> 蓝环</li>
<li class="done">装饰性 SVG 轨道 <code>aria-hidden="true" role="presentation"</code>,不进入辅助阅读</li>
<li>头像占位图 <code>./agent-avatar-v0.8.jpg</code> 接入实际员工头像资源</li>
<li>开发实现:<code>InputBar.vue</code> 按此版结构重构(已在 v1.7 列好文件清单)</li>
<li>响应式:≤480px 宽度下退化方案 <strong>A 扁平胶囊</strong>(拱形在窄屏易走样,预留 fallback)</li>
<li>深色模式:背景渐变 / 轨道渐变 / 气泡背景三处需额外定义 <code>prefers-color-scheme: dark</code> 变量</li>
<li>回归测试:补充两端收口 + 坐席 60px 居中结构测试用例(<code>InputBar.test.ts</code></li>
</ul>
<h2>🧭 方向选择记录(拍板结果)</h2>
<div class="note-info">
本版按用户在 v1.9 专业建议中给出的方向确认结论:<strong>选 B(拱形 v1.9</strong>作为员工端的差异化品牌签名。若后续在窄屏(≤480px)出现渲染问题,临时降级为 <strong>A 扁平胶囊</strong>,已在检查清单预留 fallback。
</div>
<h2>📊 版本演进一览(v1.3 → v1.9)</h2>
<table>
<thead>
<tr><th>版本</th><th>关键变化</th><th>状态</th></tr>
</thead>
<tbody>
<tr><td>v1.3</td><td>删除 IntegrationZone 旧坐席按钮,InputBar 4 按钮</td><td>基线</td></tr>
<tr><td>v1.4</td><td>新增群聊图标 + 坐席居中</td><td>已归档</td></tr>
<tr><td>v1.5</td><td>宝石嵌入式(镜片轨道 + 坐席探出 + 紫晕)</td><td>否定</td></tr>
<tr><td>v1.6</td><td>圆角长方形中央隆起,去探出/光晕/溢出</td><td>已归档</td></tr>
<tr><td>v1.7</td><td>两端收口 + 坐席 60px(较 40px 大 50%</td><td>已归档</td></tr>
<tr><td>v1.8</td><td>融合会话窗口 + 顶端圆润化</td><td>已归档</td></tr>
<tr><td><strong>v1.9</strong></td><td><strong>三区无边框融合 + 拱肩水平切线 + 穹顶更宽 + 顶点更平</strong></td><td><strong>✅ 当前落地版</strong></td></tr>
</tbody>
</table>
<h2>⚠️ 待开发确认的开放项</h2>
<ol style="margin-left: 20px; line-height: 1.8; font-size: 13px;">
<li><strong>坐席 60px 口径</strong>:按「较 40px 工具图标大 50%」= 60px 实现。若指 v1.6 的 54px 再 +50%=81px),告知即改</li>
<li><strong>头像占位图</strong><code>./agent-avatar-v0.8.jpg</code>,接入实际员工头像资源</li>
<li><strong>窄屏 fallback</strong>:≤480px 退化为 A 扁平胶囊(已在检查清单)</li>
<li><strong>深色模式</strong>:背景/轨道/气泡三处需补 <code>prefers-color-scheme: dark</code> 变量定义</li>
</ol>
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.15); color: #6b7280; font-size: 11.5px;">
v1.9 员工端落地版 · 2026-08-05 · Duckula 主理人 · 等待开发实现
</p>
</body>
</html>