From 1752a5b6859502bd5f4090cae1e3429f63a2645b Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 22 Oct 2026 17:44:36 +0800 Subject: [PATCH] feat(ui): refresh dashboard and paper boat branding --- deploy/local/demo.template.html | 1 + design/brand-refresh/DESIGN.md | 38 + design/brand-refresh/PROMPTS.md | 25 + design/brand-refresh/README.md | 36 + design/brand-refresh/asset-manifest.json | 299 +++ .../brand-refresh/assets/portraits-sheet.png | Bin 0 -> 1537620 bytes design/brand-refresh/reference-paper-boat.png | Bin 0 -> 1381514 bytes e2e/src/pages/dashboard.page.ts | 7 +- frontend/index.html | 14 +- frontend/public/apple-touch-icon-180x180.png | Bin 4896 -> 2935 bytes frontend/public/assets/favicon.ico | Bin 15086 -> 15474 bytes frontend/public/assets/favicon.svg | 7 +- frontend/public/assets/images/logo.svg | 19 +- frontend/public/assets/images/logo_dark.svg | 21 +- frontend/public/favicon.ico | Bin 15086 -> 15474 bytes frontend/public/favicon.svg | 7 +- frontend/public/images/logo.svg | 7 +- frontend/public/notification-badge-96.png | Bin 516 -> 1432 bytes frontend/public/pwa-192x192.png | Bin 6503 -> 2924 bytes frontend/public/pwa-512x512.png | Bin 17620 -> 7853 bytes frontend/public/pwa-maskable-512x512.png | Bin 12739 -> 7853 bytes frontend/public/webclient/chattermate.min.js | 17 +- .../components/common/BrandMark.spec.ts | 30 + .../components/layout/navItems.spec.ts | 16 +- .../__tests__/layouts/DashboardLayout.spec.ts | 59 +- .../src/__tests__/utils/paperAvatars.spec.ts | 90 + .../src/__tests__/views/LoginView.spec.ts | 2 +- .../avatars/avatar-01-asian-woman-1.png | Bin 250418 -> 137558 bytes .../assets/avatars/avatar-02-black-man-1.png | Bin 253050 -> 127749 bytes .../avatars/avatar-03-white-woman-glasses.png | Bin 283284 -> 141549 bytes .../avatar-04-south-asian-man-glasses.png | Bin 272010 -> 141571 bytes .../assets/avatars/avatar-05-hijab-woman.png | Bin 256063 -> 135913 bytes .../assets/avatars/avatar-06-latino-man.png | Bin 264201 -> 129977 bytes .../avatars/avatar-07-asian-woman-2.png | Bin 257043 -> 138723 bytes .../avatars/avatar-08-black-woman-curly.png | Bin 251234 -> 136890 bytes .../avatars/avatar-09-white-man-glasses.png | Bin 269469 -> 139584 bytes .../avatars/avatar-10-south-asian-woman.png | Bin 282863 -> 137755 bytes .../assets/avatars/avatar-11-latina-woman.png | Bin 291318 -> 138156 bytes .../avatars/avatar-12-east-asian-man.png | Bin 242619 -> 133904 bytes frontend/src/assets/avatars/paper-boat.svg | 1 + frontend/src/assets/avatars/paper-book.svg | 1 + frontend/src/assets/avatars/paper-heart.svg | 1 + frontend/src/assets/avatars/paper-house.svg | 1 + .../src/assets/avatars/paper-ink-boat.svg | 1 + frontend/src/assets/avatars/paper-kite.svg | 1 + frontend/src/assets/avatars/paper-leaf.svg | 1 + frontend/src/assets/avatars/paper-letter.svg | 1 + .../src/assets/avatars/paper-pinwheel.svg | 1 + frontend/src/assets/avatars/paper-plane.svg | 1 + frontend/src/assets/base.css | 28 +- frontend/src/assets/logo.svg | 7 +- frontend/src/assets/styles/base.css | 99 +- frontend/src/assets/styles/components.css | 1351 +++++++++- frontend/src/assets/styles/design-tokens.css | 469 ++-- .../agent/AgentChatPreviewPanel.vue | 43 +- .../agent/AgentCustomizationView.vue | 2 +- frontend/src/components/agent/AgentDetail.vue | 38 +- frontend/src/components/agent/AgentList.vue | 1398 +++++----- .../analytics/AnalyticsDashboard.vue | 1550 +++++------ .../analytics/SentimentAnalytics.vue | 2 +- frontend/src/components/common/BrandMark.vue | 13 + .../conversations/ChatInfoPanel.vue | 1000 +++++--- .../conversations/ConversationChat.vue | 2285 ++++++++++------- .../conversations/ConversationFilters.vue | 288 ++- .../conversations/ConversationsList.vue | 754 +++--- .../components/conversations/HandlerBadge.vue | 62 +- .../conversations/MessageStatusTicks.vue | 43 +- .../components/conversations/MessageTag.vue | 20 +- .../src/components/human-agent/UserList.vue | 1197 +++++---- .../knowledge/KnowledgeAddSourceModal.vue | 453 ++-- .../knowledge/KnowledgeExplorer.vue | 742 ++++-- .../knowledge/KnowledgeLinkModal.vue | 295 ++- .../knowledge/KnowledgePageDetail.vue | 473 ++-- .../knowledge/KnowledgePageEditor.vue | 180 +- .../knowledge/KnowledgePlanMeters.vue | 116 +- .../knowledge/KnowledgeSourceTree.vue | 840 ++++-- frontend/src/components/layout/AppSidebar.vue | 613 +++-- frontend/src/components/layout/navIcons.ts | 52 +- frontend/src/components/layout/navItems.ts | 44 +- frontend/src/composables/useTheme.ts | 2 +- frontend/src/composables/useWidgetStyles.ts | 7 +- frontend/src/config/themeColors.ts | 4 +- frontend/src/layouts/DashboardLayout.vue | 1159 ++------- frontend/src/main.ts | 2 +- frontend/src/utils/orb.ts | 121 +- frontend/src/views/AnalyticsView.vue | 4 +- frontend/src/views/ConversationsView.vue | 494 ++-- frontend/src/views/HumanAgentView.vue | 425 +-- frontend/src/views/KnowledgeView.vue | 25 +- frontend/src/views/LoginView.vue | 1208 +++++---- frontend/src/webclient/WidgetBuilder.vue | 40 +- frontend/src/webclient/chattermate.js | 20 +- frontend/vite.config.ts | 4 +- 93 files changed, 11134 insertions(+), 7543 deletions(-) create mode 100644 design/brand-refresh/DESIGN.md create mode 100644 design/brand-refresh/PROMPTS.md create mode 100644 design/brand-refresh/README.md create mode 100644 design/brand-refresh/asset-manifest.json create mode 100644 design/brand-refresh/assets/portraits-sheet.png create mode 100644 design/brand-refresh/reference-paper-boat.png create mode 100644 frontend/src/__tests__/components/common/BrandMark.spec.ts create mode 100644 frontend/src/__tests__/utils/paperAvatars.spec.ts create mode 100644 frontend/src/assets/avatars/paper-boat.svg create mode 100644 frontend/src/assets/avatars/paper-book.svg create mode 100644 frontend/src/assets/avatars/paper-heart.svg create mode 100644 frontend/src/assets/avatars/paper-house.svg create mode 100644 frontend/src/assets/avatars/paper-ink-boat.svg create mode 100644 frontend/src/assets/avatars/paper-kite.svg create mode 100644 frontend/src/assets/avatars/paper-leaf.svg create mode 100644 frontend/src/assets/avatars/paper-letter.svg create mode 100644 frontend/src/assets/avatars/paper-pinwheel.svg create mode 100644 frontend/src/assets/avatars/paper-plane.svg create mode 100644 frontend/src/components/common/BrandMark.vue diff --git a/deploy/local/demo.template.html b/deploy/local/demo.template.html index 7b6b66f..d89c33f 100644 --- a/deploy/local/demo.template.html +++ b/deploy/local/demo.template.html @@ -3,6 +3,7 @@ + ChatterMate 网站客服测试 \ No newline at end of file + diff --git a/frontend/src/components/agent/AgentCustomizationView.vue b/frontend/src/components/agent/AgentCustomizationView.vue index e51e8ff..bb89be3 100644 --- a/frontend/src/components/agent/AgentCustomizationView.vue +++ b/frontend/src/components/agent/AgentCustomizationView.vue @@ -149,7 +149,7 @@ const chatStyleOptions = [ { value: 'AURORA' as ChatStyle, label: '极光', - description: '全新的随便问——深色主题,配发光极光球头像。', + description: '深色随便问主题,可搭配纸艺头像。', group: 'new' as const, }, { diff --git a/frontend/src/components/agent/AgentDetail.vue b/frontend/src/components/agent/AgentDetail.vue index 647515d..be5f1ba 100644 --- a/frontend/src/components/agent/AgentDetail.vue +++ b/frontend/src/components/agent/AgentDetail.vue @@ -19,7 +19,7 @@ import { useRouter } from 'vue-router' import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue' import type { AgentWithCustomization, AgentCustomization } from '@/types/agent' import { getApiUrl, getWidgetUrl, resolveUploadUrl } from '@/config/api' -import { ORB_PALETTE_COUNT, getOrbStyleAt, resolveOrbStyle, orbSvgDataUri, terminalMarkSvgDataUri } from '@/utils/orb' +import { ORB_PALETTE_COUNT, PAPER_AVATAR_NAMES, getOrbStyleAt, resolveOrbStyle, orbSvgDataUri, terminalMarkSvgDataUri } from '@/utils/orb' import KnowledgeExplorer from '@/components/knowledge/KnowledgeExplorer.vue' import AgentCustomizationView from './AgentCustomizationView.vue' @@ -64,7 +64,7 @@ const toggleAvatarPicker = () => { if (isUploading.value) return showAvatarPicker.value = !showAvatarPicker.value } -// Aurora orb avatar (generated, no photo). Stored in customization_metadata so no +// Paper-craft avatar (legacy orb storage key). Stored in customization_metadata so no // schema change is needed. Selecting a real picture resets this back to 'photo'. const orbCount = ORB_PALETTE_COUNT const orbMeta = computed( @@ -104,7 +104,7 @@ const selectOrbAvatar = async (variant: number) => { if (isUploading.value) return closeAvatarPicker() try { - // Store the orb as an SVG data URI in photo_url so it propagates everywhere + // Store the paper-craft avatar as an SVG data URI in photo_url so it propagates everywhere // (agent list, widget header, previews) via the normal avatar path. const orbUrl = orbSvgDataUri(agentData.value.name || '', variant) await persistAvatarMeta({ avatar_style: 'orb', orb_variant: variant }, orbUrl) @@ -118,7 +118,7 @@ const selectTerminalMark = async () => { if (isUploading.value) return closeAvatarPicker() try { - // Tint the ">" mark with the agent's accent (falls back to the Terminal lime). + // Tint the ">" mark with the agent's accent (falls back to the muted celadon). const accent = (agentData.value.customization?.accent_color as string | undefined) || undefined const markUrl = terminalMarkSvgDataUri(accent) await persistAvatarMeta({ avatar_style: 'terminal' }, markUrl) @@ -134,7 +134,7 @@ const selectPresetAvatar = async (url: string) => { optimisticPhoto.value = url try { await applyPresetAvatar(url) - // A real picture was chosen — turn off the orb if it was on. + // A real picture was chosen — turn off the paper-craft avatar if it was on. if (useOrbAvatar.value) await persistAvatarMeta({ avatar_style: 'photo' }) } finally { optimisticPhoto.value = null @@ -873,8 +873,8 @@ onMounted(async () => { :class="{ active: useOrbAvatar && (currentOrbVariant ?? -1) === n - 1 }" :disabled="isUploading" @click="selectOrbAvatar(n - 1)" - :aria-label="`光球 ${n}`" - :title="`光球 ${n}`" + :aria-label="PAPER_AVATAR_NAMES[n - 1]" + :title="PAPER_AVATAR_NAMES[n - 1]" > @@ -887,7 +887,7 @@ onMounted(async () => { aria-label="终端标记" title="Terminal >" > - > +