refine: 亮灯表视觉优化

- 用几何圆形图标代替文字'亮/临/灭':
  ● 实心圆(已拜访) / ◐ 半圆(临期) / ○ 空心圆(未拜访) / ◌ 虚线圆(未分配)
- 客户名称全量显示, 允许换行, card 拓宽至 220px
- 仪表盘标签从 '🟢 亮灯' 改为 '已拜访/临期/未拜访/未分配'
This commit is contained in:
2026-06-24 16:07:15 +08:00
parent 305ee5df09
commit a8ed71fbff
+40 -30
View File
@@ -52,16 +52,6 @@ async function loadData() {
onMounted(loadData)
function statusLabel(status: string): string {
const map: Record<string, string> = { green: '亮灯', yellow: '临期', red: '灭灯', gray: '未分配' }
return map[status] || status
}
function statusGlyph(status: string): string {
const map: Record<string, string> = { green: '亮', yellow: '临', red: '灭', gray: '—' }
return map[status] || '?'
}
function goCustomerVisits(customerId: string) {
router.push({ path: '/weekly-report', query: { customer_id: customerId } })
}
@@ -108,19 +98,19 @@ const coverageColor = (rate: number): string => {
</div>
<div class="team-stat team-stat--green">
<span class="team-stat-num">{{ board.team_summary.visited_this_month }}</span>
<span class="team-stat-label">🟢 亮灯</span>
<span class="team-stat-label">已拜访</span>
</div>
<div class="team-stat team-stat--yellow">
<span class="team-stat-num">{{ board.team_summary.visited_last_month_only }}</span>
<span class="team-stat-label">🟡 临期</span>
<span class="team-stat-label">临期</span>
</div>
<div class="team-stat team-stat--red">
<span class="team-stat-num">{{ board.team_summary.not_visited_2months }}</span>
<span class="team-stat-label">🔴 灭灯</span>
<span class="team-stat-label">未拜访</span>
</div>
<div class="team-stat" v-if="board.team_summary.unassigned">
<span class="team-stat-num">{{ board.team_summary.unassigned }}</span>
<span class="team-stat-label"> 未分配</span>
<span class="team-stat-label">未分配</span>
</div>
<div class="team-stat team-stat--coverage">
<span class="team-stat-num">{{ (board.team_summary.coverage_rate * 100).toFixed(0) }}%</span>
@@ -144,9 +134,9 @@ const coverageColor = (rate: number): string => {
<span class="manager-count">{{ m.total_customers }} 个客户</span>
</div>
<div class="manager-lights">
<span class="light-dot light-dot--green" :title="`亮灯 ${m.visited_this_month}`">{{ m.visited_this_month }}</span>
<span class="light-dot light-dot--green" :title="`已拜访 ${m.visited_this_month}`">{{ m.visited_this_month }}</span>
<span class="light-dot light-dot--yellow" :title="`临期 ${m.visited_last_month_only}`">{{ m.visited_last_month_only }}</span>
<span class="light-dot light-dot--red" :title="`灭灯 ${m.not_visited_2months}`">{{ m.not_visited_2months }}</span>
<span class="light-dot light-dot--red" :title="`未拜访 ${m.not_visited_2months}`">{{ m.not_visited_2months }}</span>
</div>
<div class="manager-coverage">
<div class="coverage-bar">
@@ -173,7 +163,7 @@ const coverageColor = (rate: number): string => {
<div class="card-status-stripe"></div>
<div class="card-body">
<div class="card-name-row">
<span class="card-glyph" :class="`card-glyph--${cust.status}`">{{ statusGlyph(cust.status) }}</span>
<span class="status-circle" :class="`status-circle--${cust.status}`"></span>
<strong class="card-name">{{ cust.customer_name }}</strong>
</div>
<div class="card-meta">
@@ -215,7 +205,7 @@ const coverageColor = (rate: number): string => {
<div class="card-status-stripe"></div>
<div class="card-body">
<div class="card-name-row">
<span class="card-glyph card-glyph--gray"></span>
<span class="status-circle status-circle--gray"></span>
<strong class="card-name">{{ cust.customer_name }}</strong>
</div>
<div class="card-meta">
@@ -371,7 +361,7 @@ const coverageColor = (rate: number): string => {
/* ═══ Customer Card ═══ */
.customer-card {
width: 200px;
width: 220px;
background: var(--paper);
border: 1px solid var(--warm-border);
cursor: pointer;
@@ -407,25 +397,45 @@ const coverageColor = (rate: number): string => {
flex: 1; min-width: 0;
}
.card-name-row {
display: flex; align-items: center; gap: 6px;
display: flex; align-items: flex-start; gap: 8px;
margin-bottom: 6px;
}
.card-glyph {
display: inline-flex; align-items: center; justify-content: center;
width: 20px; height: 20px; border-radius: 2px;
font-family: 'ZCOOL XiaoWei', STSong, serif;
font-size: 12px; color: #fff;
/* ═══ Status Circle Icons (geometric, no text) ═══ */
.status-circle {
display: inline-block;
width: 16px; height: 16px;
border-radius: 50%;
flex-shrink: 0;
margin-top: 2px;
}
/* Visited this month — solid filled circle ● */
.status-circle--green {
background: var(--sage);
box-shadow: 0 0 0 2px rgba(74,103,65,0.15);
}
/* Visited last month only — half-filled circle ◐ */
.status-circle--yellow {
background: conic-gradient(var(--gold) 50%, transparent 50%);
box-shadow: inset 0 0 0 1.5px var(--gold);
}
/* Not visited 2+ months — empty circle ○ */
.status-circle--red {
background: transparent;
border: 2px solid var(--vermilion);
box-shadow: 0 0 0 2px rgba(184,71,46,0.08);
}
/* Unassigned — dash */
.status-circle--gray {
background: transparent;
border: 1.5px dashed var(--warm-gray);
}
.card-glyph--green { background: var(--sage); }
.card-glyph--yellow { background: var(--gold); }
.card-glyph--red { background: var(--vermilion); }
.card-glyph--gray { background: var(--warm-gray); }
.card-name {
font-family: 'ZCOOL XiaoWei', STSong, serif;
font-size: 13px; color: var(--ink); letter-spacing: 0.03em;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
line-height: 1.4;
word-break: break-all;
}
.card-meta {
display: flex; gap: 6px; flex-wrap: wrap;