Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v0.4-WB风格.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

435 lines
17 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>工具栏统一设计 v0.4 - WB 专家团队风格</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
background: #f5f6f8;
color: #1a1a1a;
padding: 32px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #1a1a1a; }
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 40px 0 12px; color: #1a1a1a; }
h3 { font-size: 14px; font-weight: 600; margin: 16px 0 8px; color: #333; }
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 24px; }
/* === 4 按钮统一容器(模拟 InputBar 工具栏) === */
.toolbar {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 10px;
background: #ffffff;
border: 1px solid #e8eaed;
border-radius: 12px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.toolbar-divider {
width: 1px;
height: 22px;
background: #e8eaed;
margin: 0 2px;
}
/* === 统一按钮基础(35×35,圆润) === */
.tool-btn {
width: 35px;
height: 35px;
border: 1px solid #e8eaed;
background: #ffffff;
border-radius: 50%; /* 圆形按钮 — WB 风格 */
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
-webkit-tap-highlight-color: transparent;
position: relative;
color: #5f6368;
font-size: 16px;
}
.tool-btn:hover {
background: #f5f6f8;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
}
.tool-btn:active { transform: translateY(0) scale(0.94); }
.tool-btn svg { width: 18px; height: 18px; }
/* === WB 风格:客服 = 圆形渐变头像 + 白色客服图标 === */
.wb-agent {
border: 1.5px solid transparent;
background-clip: padding-box;
position: relative;
overflow: visible;
}
.wb-agent::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
padding: 1.5px;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.wb-agent::after {
content: "";
position: absolute;
inset: 1.5px;
border-radius: 50%;
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #db2777 100%);
pointer-events: none;
z-index: 0;
}
.wb-agent .agent-content {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
}
.wb-agent .agent-content svg {
width: 18px;
height: 18px;
color: #ffffff;
}
/* 6 态 - 渐变色变化 */
.wb-agent.is-active::after { background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #db2777 100%); }
.wb-agent.is-active::before { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #ec4899 100%); }
.wb-agent.is-disabled { opacity: 0.4; cursor: not-allowed; }
.wb-agent.is-disabled:hover { transform: none; box-shadow: none; }
.wb-agent.is-disabled::after { background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%); }
.wb-agent.is-disabled::before { background: linear-gradient(135deg, #d1d5db 0%, #9ca3af 100%); }
.wb-agent.is-urgent {
animation: agentGlow 1.6s ease-in-out infinite;
}
.wb-agent.is-urgent::after { background: linear-gradient(135deg, #ef4444 0%, #dc2626 50%, #b91c1c 100%); }
.wb-agent.is-urgent::before { background: linear-gradient(135deg, #f87171 0%, #ef4444 50%, #dc2626 100%); }
@keyframes agentGlow {
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0.18); }
}
.wb-agent.is-waiting::after { background: linear-gradient(135deg, #f59e0b 0%, #d97706 50%, #b45309 100%); }
.wb-agent.is-waiting::before { background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 50%, #d97706 100%); }
.wb-agent.is-end::after { background: linear-gradient(135deg, #10b981 0%, #059669 50%, #047857 100%); }
.wb-agent.is-end::before { background: linear-gradient(135deg, #34d399 0%, #10b981 50%, #059669 100%); }
.wb-agent.is-reopen::after { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%); }
.wb-agent.is-reopen::before { background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 50%, #2563eb 100%); }
/* === 演示容器 === */
.demo-block {
background: #ffffff;
border: 1px solid #e8eaed;
border-radius: 14px;
padding: 28px;
margin-bottom: 20px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.demo-label { font-size: 11.5px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; font-weight: 500; }
/* === 状态切换 tab === */
.state-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid #e8eaed; }
.state-tab {
padding: 6px 12px;
border: 1px solid #e8eaed;
background: #ffffff;
border-radius: 6px;
cursor: pointer;
font-size: 12.5px;
color: #5f6368;
transition: all 0.15s;
font-family: inherit;
}
.state-tab:hover { background: #f5f6f8; }
.state-tab.active { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
.state-stage {
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #fafbfc 0%, #f0f1f5 100%);
border-radius: 10px;
padding: 32px;
}
.state-desc { color: #5f6368; font-size: 12.5px; line-height: 1.7; background: #fafbfc; padding: 12px 14px; border-radius: 6px; border-left: 2px solid #6366f1; margin-top: 12px; }
.state-desc strong { color: #1a1a1a; }
/* === 4 按钮并排 === */
.four-btns {
display: flex;
gap: 6px;
align-items: center;
padding: 16px;
background: linear-gradient(135deg, #fafbfc 0%, #f0f1f5 100%);
border: 1px solid #e8eaed;
border-radius: 12px;
margin: 12px 0;
}
/* === 对比表 === */
.cmp-table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
.cmp-table th, .cmp-table td { border: 1px solid #e8eaed; padding: 8px 10px; text-align: left; }
.cmp-table th { background: #fafbfc; font-weight: 600; }
.yes { color: #059669; }
.no { color: #dc2626; }
.partial { color: #d97706; }
.palette { display: flex; gap: 6px; flex-wrap: wrap; }
.palette-item { width: 56px; height: 56px; border-radius: 6px; display: flex; align-items: flex-end; padding: 4px; font-size: 9.5px; color: #fff; font-weight: 500; }
.note { background: #fef3c7; border-left: 3px solid #d97706; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #78350f; margin: 16px 0; }
.gradient-bar {
height: 40px;
border-radius: 6px;
display: flex;
align-items: center;
padding: 0 12px;
color: #fff;
font-size: 11.5px;
font-weight: 500;
}
</style>
</head>
<body>
<h1>工具栏统一设计 v0.4 — WB 专家团队风格</h1>
<p class="meta">圆形按钮 + 渐变色客服头像 + 高级感设计 · 2026-08-04 凌晨</p>
<div class="note">
📌 本版核心改动(对比 v0.3 克制拟人):<br>
• 4 按钮改为<strong>圆形</strong>(35×35 圆按钮, WB 企微/钉钉生态风格)<br>
• 客服按钮采用<strong>渐变边框 + 渐变背景 + 白色客服图标</strong>设计(类似企微客服小助手)<br>
• 配色更<strong>大胆</strong>:紫粉渐变(默认)/ 红橙(urgent)/ 绿(end)/ 橙黄(waiting)/ 蓝(reopen)<br>
• 整体感觉<strong>更"专业 SaaS"</strong>,类似企微客服、钉钉智能客服、飞书服务台
</div>
<h2>🎨 配色色板(渐变色为主)</h2>
<div class="demo-block">
<h3>客服 6 态渐变色</h3>
<div style="display: flex; flex-direction: column; gap: 8px;">
<div class="gradient-bar" style="background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 50%, #db2777 100%);">active 紫粉渐变 (默认 · 客服在线)</div>
<div class="gradient-bar" style="background: linear-gradient(135deg, #9ca3af 0%, #6b7280 100%); opacity: 0.6;">disabled 灰度</div>
<div class="gradient-bar" style="background: linear-gradient(135deg, #ef4444 0%, #dc2626 50%, #b91c1c 100%);">urgent 红渐变 (紧急)</div>
<div class="gradient-bar" style="background: linear-gradient(135deg, #f59e0b 0%, #d97706 50%, #b45309 100%);">waiting 橙渐变 (排队)</div>
<div class="gradient-bar" style="background: linear-gradient(135deg, #10b981 0%, #059669 50%, #047857 100%);">end 绿渐变 (已接入)</div>
<div class="gradient-bar" style="background: linear-gradient(135deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%);">reopen 蓝渐变 (重新打开)</div>
</div>
</div>
<h2>🎭 4 按钮统一设计(WB 风格 — 圆形)</h2>
<div class="demo-block">
<div class="demo-label">工具栏并排展示(模拟 InputBar 工具栏)</div>
<div class="four-btns">
<!-- 表情 -->
<button class="tool-btn" title="表情">
<svg viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="9" r="6.5" fill="none" stroke="currentColor" stroke-width="1.5"/>
<circle cx="6.5" cy="8" r="0.8" fill="currentColor"/>
<circle cx="11.5" cy="8" r="0.8" fill="currentColor"/>
<path d="M6 11.5 Q9 13.5 12 11.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
<!-- 文件 -->
<button class="tool-btn" title="文件">
<svg viewBox="0 0 18 18" fill="none">
<path d="M3 2 L11 2 L15 6 L15 16 L3 16 Z" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<path d="M11 2 L11 6 L15 6" fill="#f5f6f8" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<line x1="6" y1="10" x2="12" y2="10" stroke="currentColor" stroke-width="1.2"/>
<line x1="6" y1="13" x2="10" y2="13" stroke="currentColor" stroke-width="1.2"/>
</svg>
</button>
<div class="toolbar-divider"></div>
<!-- 语音 -->
<button class="tool-btn" title="语音">
<svg viewBox="0 0 18 18" fill="none">
<rect x="6" y="2" width="6" height="9" rx="3" fill="none" stroke="currentColor" stroke-width="1.5"/>
<path d="M3 9 Q3 13 9 13 Q15 13 15 9" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
<line x1="9" y1="13" x2="9" y2="16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</button>
<!-- 客服(WB 风格) -->
<button class="tool-btn wb-agent is-active" title="客服在线 · 点击呼叫">
<span class="agent-content">
<svg viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="8" r="3.5" fill="none" stroke="currentColor" stroke-width="1.4"/>
<path d="M3.5 8 Q3.5 5 5 5 L5 11 Q3.5 11 3.5 8 Z" fill="currentColor" opacity="0.95"/>
<path d="M14.5 8 Q14.5 5 13 5 L13 11 Q14.5 11 14.5 8 Z" fill="currentColor" opacity="0.95"/>
<circle cx="7" cy="8" r="0.6" fill="currentColor"/>
<circle cx="11" cy="8" r="0.6" fill="currentColor"/>
<path d="M7.5 10.2 Q9 11.4 10.5 10.2" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
</svg>
</span>
</button>
</div>
<p style="font-size: 12px; color: #5f6368; margin-top: 8px;">
视觉特点: 35×35 圆形按钮 + 客服按钮 1.5px 渐变边框(紫粉) + 渐变背景 + 白色客服图标
</p>
</div>
<h2>🎬 客服按钮 6 态切换</h2>
<div class="demo-block">
<div class="state-tabs">
<button class="state-tab active" data-state="active">active</button>
<button class="state-tab" data-state="disabled">disabled</button>
<button class="state-tab" data-state="urgent">urgent</button>
<button class="state-tab" data-state="waiting">waiting</button>
<button class="state-tab" data-state="end">end</button>
<button class="state-tab" data-state="reopen">reopen</button>
</div>
<div class="state-stage" id="stage"></div>
<div class="state-desc" id="desc"></div>
</div>
<h2>📊 与之前版本对比</h2>
<table class="cmp-table">
<thead>
<tr>
<th>维度</th>
<th>v0.1 方块按钮</th>
<th>v0.2 灵动岛卡通</th>
<th>v0.3 克制拟人</th>
<th>v0.4 WB 渐变 ⭐</th>
</tr>
</thead>
<tbody>
<tr>
<td>按钮形态</td>
<td>方块 8px 圆角</td>
<td>方块 18px 圆角</td>
<td>方块 8px 圆角</td>
<td class="yes"><strong>圆形(35×35)</strong></td>
</tr>
<tr>
<td>4 按钮统一</td>
<td class="no">×</td>
<td class="no">×</td>
<td class="yes">✓ 4 按钮</td>
<td class="yes">✓ 4 按钮(圆形)</td>
</tr>
<tr>
<td>角色设计</td>
<td class="no">emoji</td>
<td class="no">夸张卡通</td>
<td class="partial">克制拟人</td>
<td class="yes"><strong>渐变头像 + 客服图标(企微风)</strong></td>
</tr>
<tr>
<td>配色</td>
<td class="no">单调</td>
<td class="no">卡通色</td>
<td class="partial">中性灰</td>
<td class="yes"><strong>渐变色(紫粉/红/橙/绿/蓝)</strong></td>
</tr>
<tr>
<td>专业感</td>
<td class="partial">★★★</td>
<td class="no"></td>
<td class="yes">★★★★</td>
<td class="yes"><strong>★★★★★(企微/钉钉/飞书级)</strong></td>
</tr>
<tr>
<td>技术实现</td>
<td class="yes">纯 CSS 简单</td>
<td class="partial">CSS + SVG</td>
<td class="partial">CSS + SVG</td>
<td class="partial">CSS + SVG + 渐变(中等)</td>
</tr>
</tbody>
</table>
<h2>❓ 待你拍板</h2>
<ol style="margin-left: 20px; line-height: 1.8;">
<li><strong>WB 风格(圆形 + 渐变)</strong>符合你期望吗?如果"WB 专家团队"指具体产品(如企微、钉钉、飞书的客服),可能需要我再调整</li>
<li><strong>默认渐变色</strong>是紫粉(更年轻/活泼)还是其他(更专业/冷静)?如蓝色、蓝绿、暗色等</li>
<li><strong>客服图标</strong>是戴耳机小人(当前)还是纯文字"客服"两字/品牌 logo 缩写?</li>
<li><strong>圆形 vs 方块</strong>:WB 风格如果太"活泼",我可以做方形 + 渐变(更克制)</li>
</ol>
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid #e8eaed; color: #6b7280; font-size: 11.5px;">
v0.4 WB 风格 · 2026-08-04 · Duckula 主理人 · 等待用户拍板
</p>
<script>
const states = {
active: {
cls: 'is-active',
desc: '<strong>active</strong>: 紫粉渐变(蓝→紫→粉)+ 白色客服图标 — 默认"客服在线,等待呼叫"。类似企微客服小助手的"标准态"'
},
disabled: {
cls: 'is-disabled',
desc: '<strong>disabled</strong>: 灰度渐变 + opacity 0.4 — 表达"不可用",无动画'
},
urgent: {
cls: 'is-urgent',
desc: '<strong>urgent</strong>: 红色渐变(浅红→中红→深红)+ 1.6s 发光呼吸(box-shadow 扩散 6px) — 表达"紧急,需关注"'
},
waiting: {
cls: 'is-waiting',
desc: '<strong>waiting</strong>: 橙色渐变(浅黄→橙→深橙) — 表达"排队中"'
},
end: {
cls: 'is-end',
desc: '<strong>end</strong>: 绿色渐变(浅绿→中绿→深绿) — 表达"已接入坐席,通话中"'
},
reopen: {
cls: 'is-reopen',
desc: '<strong>reopen</strong>: 蓝色渐变(浅蓝→中蓝→深蓝) — 表达"会话已关闭,可重新打开"'
}
};
const svgHTML = `<svg viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="8" r="3.5" fill="none" stroke="currentColor" stroke-width="1.4"/>
<path d="M3.5 8 Q3.5 5 5 5 L5 11 Q3.5 11 3.5 8 Z" fill="currentColor" opacity="0.95"/>
<path d="M14.5 8 Q14.5 5 13 5 L13 11 Q14.5 11 14.5 8 Z" fill="currentColor" opacity="0.95"/>
<circle cx="7" cy="8" r="0.6" fill="currentColor"/>
<circle cx="11" cy="8" r="0.6" fill="currentColor"/>
<path d="M7.5 10.2 Q9 11.4 10.5 10.2" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
</svg>`;
const stage = document.getElementById('stage');
const descEl = document.getElementById('desc');
const tabs = document.querySelectorAll('.state-tab');
function render(state) {
const s = states[state];
stage.innerHTML = `<button class="tool-btn wb-agent ${s.cls}" style="width: 56px; height: 56px;"><span class="agent-content">${svgHTML}</span></button>`;
descEl.innerHTML = s.desc;
}
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
render(tab.dataset.state);
});
});
render('active');
</script>
</body>
</html>