diff --git a/server/cmd/seed/main.go b/server/cmd/seed/main.go
index 2fdbe4d..e1d2c66 100644
--- a/server/cmd/seed/main.go
+++ b/server/cmd/seed/main.go
@@ -81,56 +81,6 @@ func seed() {
}
model.DB.Create(&channels)
- // Customers
- customers := []model.Customer{
- {TenantID: tenants[0].ID, Name: "张三", Phone: "138****8888", Email: "zhang@example.com", Tags: `["VIP客户","新客户"]`, Source: "网页", Status: "online", ConversationCount: 12},
- {TenantID: tenants[0].ID, Name: "李四", Phone: "139****7777", Email: "li@example.com", Tags: `["活跃"]`, Source: "微信", Status: "offline", ConversationCount: 8},
- {TenantID: tenants[0].ID, Name: "王五", Phone: "137****6666", Email: "wang@example.com", Tags: `["企业客户","VIP客户"]`, Source: "APP", Status: "busy", ConversationCount: 25},
- {TenantID: tenants[0].ID, Name: "赵六科技", Phone: "136****5555", Email: "zhao@tech.com", Tags: `["企业客户"]`, Source: "网页", Status: "online", ConversationCount: 6},
- {TenantID: tenants[0].ID, Name: "钱七", Phone: "135****4444", Tags: `["沉默"]`, Source: "邮件", Status: "offline", ConversationCount: 3},
- {TenantID: tenants[0].ID, Name: "孙八", Phone: "134****3333", Email: "sun@example.com", Tags: `["新客户","活跃"]`, Source: "网页", Status: "online", ConversationCount: 2},
- }
- model.DB.Create(&customers)
-
- // Sessions(含访客 IP/地区,与工作台顶栏展示一致)
- sessions := []model.Session{
- {TenantID: tenants[0].ID, ChannelID: channels[0].ID, CustomerID: customers[0].ID, AgentID: &agent1.ID, Status: "active", Priority: "urgent", VisitorIP: "192.168.1.105", VisitorRegion: "北京", UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"},
- {TenantID: tenants[0].ID, ChannelID: channels[1].ID, CustomerID: customers[1].ID, AgentID: &agent2.ID, Status: "active", Priority: "normal", VisitorIP: "10.0.0.23", VisitorRegion: "内网", UserAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0) Safari/604.1"},
- {TenantID: tenants[0].ID, ChannelID: channels[0].ID, CustomerID: customers[2].ID, AgentID: nil, Status: "waiting", Priority: "normal", VisitorIP: "223.5.5.5", VisitorRegion: "中国", UserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X) Chrome/120.0.0.0"},
- {TenantID: tenants[0].ID, ChannelID: channels[0].ID, CustomerID: customers[3].ID, AgentID: &agent3.ID, Status: "ended", Priority: "normal", SatisfactionScore: ptr(5), VisitorIP: "114.114.114.114", VisitorRegion: "中国"},
- {TenantID: tenants[0].ID, ChannelID: channels[0].ID, CustomerID: customers[4].ID, AgentID: &agent1.ID, Status: "ended", Priority: "normal", SatisfactionScore: ptr(4), VisitorIP: "8.8.8.8", VisitorRegion: "美国"},
- }
- model.DB.Create(&sessions)
-
- // Messages - 模拟真实对话
- messages := []model.Message{
- // Session 1: 张三 - 订单物流咨询 (urgent)
- {SessionID: sessions[0].ID, SenderType: "visitor", Content: "你好,我的订单怎么还没发货?已经3天了", Type: "text", Seq: 1, SentAt: now.Add(-10 * time.Minute)},
- {SessionID: sessions[0].ID, SenderType: "agent", SenderID: &agent1.ID, Content: "您好,请提供一下您的订单号,我帮您查询", Type: "text", Seq: 2, SentAt: now.Add(-9 * time.Minute)},
- {SessionID: sessions[0].ID, SenderType: "visitor", Content: "订单号 AB20260714001", Type: "text", Seq: 3, SentAt: now.Add(-8 * time.Minute)},
- {SessionID: sessions[0].ID, SenderType: "agent", SenderID: &agent1.ID, Content: "稍等,正在为您查询物流信息...", Type: "text", Seq: 4, SentAt: now.Add(-7 * time.Minute)},
- {SessionID: sessions[0].ID, SenderType: "agent", SenderID: &agent1.ID, Content: "您好,您的包裹已到达北京分拨中心,预计明天下午送达。给您带来不便敬请谅解", Type: "text", Seq: 5, SentAt: now.Add(-6 * time.Minute)},
-
- // Session 2: 李四 - 退换货咨询 (active)
- {SessionID: sessions[1].ID, SenderType: "visitor", Content: "你好,我买的商品有质量问题,想退货", Type: "text", Seq: 1, SentAt: now.Add(-5 * time.Minute)},
- {SessionID: sessions[1].ID, SenderType: "agent", SenderID: &agent2.ID, Content: "非常抱歉给您带来不便。请拍照上传问题商品图片,我们核实后会为您办理退货", Type: "text", Seq: 2, SentAt: now.Add(-4 * time.Minute)},
- {SessionID: sessions[1].ID, SenderType: "visitor", Content: "好的,我拍照上传", Type: "text", Seq: 3, SentAt: now.Add(-3 * time.Minute)},
-
- // Session 3: 王五 - 等待分配 (waiting)
- {SessionID: sessions[2].ID, SenderType: "visitor", Content: "您好,请问企业版是否有优惠?我们公司需要50个坐席", Type: "text", Seq: 1, SentAt: now.Add(-2 * time.Minute)},
-
- // Session 4: 赵六科技 - 已结束
- {SessionID: sessions[3].ID, SenderType: "visitor", Content: "产品使用手册在哪里下载?", Type: "text", Seq: 1, SentAt: now.Add(-2 * time.Hour)},
- {SessionID: sessions[3].ID, SenderType: "agent", SenderID: &agent3.ID, Content: "您好,请在官网帮助中心→文档下载中获取,也可直接访问 docs.example.com", Type: "text", Seq: 2, SentAt: now.Add(-1 * time.Hour + 55*time.Minute)},
- {SessionID: sessions[3].ID, SenderType: "visitor", Content: "找到了,谢谢!", Type: "text", Seq: 3, SentAt: now.Add(-1 * time.Hour + 50*time.Minute)},
-
- // Session 5: 钱七 - 已结束
- {SessionID: sessions[4].ID, SenderType: "visitor", Content: "退款什么时候到账?已经3天了", Type: "text", Seq: 1, SentAt: now.Add(-3 * time.Hour)},
- {SessionID: sessions[4].ID, SenderType: "agent", SenderID: &agent1.ID, Content: "您好,退款一般在3-5个工作日到账,我帮您催一下财务", Type: "text", Seq: 2, SentAt: now.Add(-2 * time.Hour + 55*time.Minute)},
- {SessionID: sessions[4].ID, SenderType: "agent", SenderID: &agent1.ID, Content: "已为您加急处理,预计明天到账,请注意查收", Type: "text", Seq: 3, SentAt: now.Add(-2 * time.Hour + 50*time.Minute)},
- }
- model.DB.Create(&messages)
-
// Knowledge categories(两级树,对齐设计稿)
tid := tenants[0].ID
rootFAQ := model.Category{TenantID: tid, Name: "产品常见问题"}
diff --git a/web/index.html b/web/index.html
index 5e3836a..41fea48 100644
--- a/web/index.html
+++ b/web/index.html
@@ -2,9 +2,9 @@
-
+
- web
+ 客服云平台 - 全渠道智能客服系统
diff --git a/web/public/logo.svg b/web/public/logo.svg
new file mode 100644
index 0000000..1e18bc4
--- /dev/null
+++ b/web/public/logo.svg
@@ -0,0 +1,26 @@
+
diff --git a/web/src/components/common/Logo.tsx b/web/src/components/common/Logo.tsx
new file mode 100644
index 0000000..704e951
--- /dev/null
+++ b/web/src/components/common/Logo.tsx
@@ -0,0 +1,262 @@
+import React from 'react'
+
+export type LogoVariant = 'aurora' | 'headset' | 'cloud' | 'letterK'
+
+interface LogoProps {
+ /** 尺寸(像素),默认 32 */
+ size?: number
+ /** 设计版本:'aurora' (双气泡极光) | 'headset' (智能耳机) | 'cloud' (智云星环) | 'letterK' (几何折叠K) */
+ variant?: LogoVariant
+ /** 是否展示文字名称,默认 false */
+ withText?: boolean
+ /** 主题风格:'light' | 'dark' | 'auto',默认 'auto' */
+ theme?: 'light' | 'dark' | 'auto'
+ /** 自定义副标题,例如 'KEFU CLOUD' */
+ subtitle?: string
+ /** 自定义类名 */
+ className?: string
+}
+
+/**
+ * 版本 A:双重极光对话气泡 (Dual Aurora Bubbles) —— 空间交叠拟态,客我连接与智能星芒
+ */
+const AuroraLogo: React.FC<{ size: number; className?: string }> = ({ size, className = '' }) => (
+
+)
+
+/**
+ * 版本 B:现代空间客服耳机 (Spatial Headset & Spark) —— 专业客服身份、环绕声波与连通微标
+ */
+const HeadsetLogo: React.FC<{ size: number; className?: string }> = ({ size, className = '' }) => (
+
+)
+
+/**
+ * 版本 C:科技对称智云星环 (Symmetric Cloud & Signal Ring) —— 纯粹对称云朵 + 向上无线信号
+ */
+const CloudLogo: React.FC<{ size: number; className?: string }> = ({ size, className = '' }) => (
+
+)
+
+/**
+ * 版本 D:字母「K」几何折叠光翼 (Geometric Origami 'K' & Dialogue) —— 极简国际化、Kefu 专属首字母
+ */
+const LetterKLogo: React.FC<{ size: number; className?: string }> = ({ size, className = '' }) => (
+
+)
+
+export const LogoIcon: React.FC<{ size?: number; variant?: LogoVariant; className?: string }> = ({
+ size = 32,
+ variant = 'aurora',
+ className = '',
+}) => {
+ switch (variant) {
+ case 'headset':
+ return
+ case 'cloud':
+ return
+ case 'letterK':
+ return
+ case 'aurora':
+ default:
+ return
+ }
+}
+
+export const Logo: React.FC = ({
+ size = 32,
+ variant = 'aurora',
+ withText = false,
+ theme = 'auto',
+ subtitle = 'KEFU CLOUD',
+ className = '',
+}) => {
+ if (!withText) {
+ return
+ }
+
+ const isDark = theme === 'dark'
+ const titleClass = isDark ? 'text-white' : 'text-slate-900'
+ const subClass = isDark ? 'text-blue-400' : 'text-blue-600'
+
+ return (
+
+
+
+
+ 客服云平台
+
+
+ {subtitle}
+
+
+
+ )
+}
+
+export default Logo
diff --git a/web/src/components/layout/AdminSidebar.tsx b/web/src/components/layout/AdminSidebar.tsx
index 3b31d80..c39b932 100644
--- a/web/src/components/layout/AdminSidebar.tsx
+++ b/web/src/components/layout/AdminSidebar.tsx
@@ -1,10 +1,10 @@
import { useLocation, useNavigate } from 'react-router-dom'
import {
DashboardOutlined, TeamOutlined, GiftOutlined, ToolOutlined, LogoutOutlined,
- CrownOutlined,
} from '@ant-design/icons'
import { Tooltip } from 'antd'
import { useAuth } from '@/stores/auth'
+import { LogoIcon } from '@/components/common/Logo'
const menuItems = [
{ key: '/admin/dashboard', icon: , label: '运营概览' },
@@ -36,12 +36,10 @@ const AdminSidebar = () => {
className="flex items-center gap-2.5 px-4 shrink-0 border-b border-slate-100"
style={{ height: 'var(--header-height)' }}
>
-
-
-
+
- 管理总台
- ADMIN CONSOLE
+ 管理总台
+ ADMIN CONSOLE
diff --git a/web/src/components/layout/AgentSidebar.tsx b/web/src/components/layout/AgentSidebar.tsx
index 7d0144b..0d8c680 100644
--- a/web/src/components/layout/AgentSidebar.tsx
+++ b/web/src/components/layout/AgentSidebar.tsx
@@ -1,12 +1,13 @@
import { useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import {
- AppstoreOutlined, MessageOutlined, HistoryOutlined, TeamOutlined,
+ AppstoreOutlined, HistoryOutlined, TeamOutlined,
FileTextOutlined, BarChartOutlined, SettingOutlined, LogoutOutlined,
ThunderboltOutlined, DownOutlined, StopOutlined, SafetyOutlined, BellOutlined, BellFilled,
} from '@ant-design/icons'
import { Button, Dropdown, message as antMsg, Popover, Switch, Tooltip } from 'antd'
import { useAuth } from '@/stores/auth'
+import { LogoIcon } from '@/components/common/Logo'
import { useAgentNotifications } from '@/stores/notifications'
import type { AgentPresence } from '@/services/api'
@@ -121,12 +122,10 @@ const AgentSidebar = () => {
className="flex items-center gap-2.5 px-4 shrink-0 border-b border-slate-100"
style={{ height: 'var(--header-height)' }}
>
-
-
-
+
- 客服工作台
- KEFU CLOUD
+ 客服工作台
+ KEFU CLOUD
消息提醒设置}>