feat(dashboard): 在工作台右侧扩展出海运营快捷中枢,新增8大高频业务入口、渠道矩阵与待办预警

这个提交包含在:
wikiboss
2026-09-21 10:27:20 +08:00
父节点 4843c6d713
当前提交 088a5f05e1
共有 4 个文件被更改,包括 582 次插入 和 232 次删除

查看文件

@@ -17,15 +17,21 @@ import {
Typography,
} from '@arco-design/web-react';
import {
IconApps,
IconArrowRise,
IconCompass,
IconDesktop,
IconDownload,
IconEye,
IconIdcard,
IconMobile,
IconPlus,
IconRight,
IconRobot,
IconSafe,
IconSend,
IconUserAdd,
IconUserGroup,
} from '@arco-design/web-react/icon';
import useLocale from '@/utils/useLocale';
import { getCssVariables, lightColors } from '@/style/tokens';
@@ -179,20 +185,9 @@ function Workplace(): React.ReactElement {
fetchOverview();
}, [fetchOverview]);
const handleCreateCard = () => {
history.push('/card/list');
};
const handleIssueCards = () => {
history.push('/nfc/batch');
};
const handleOpenRadar = () => {
history.push('/dashboard/radar-map');
};
const handleOpenAiConfig = () => {
history.push('/ai/concierge');
// 导航路由跳转处理器
const handleNav = (path: string) => {
history.push(path);
};
const handleExportLeads = async () => {
@@ -294,7 +289,7 @@ function Workplace(): React.ReactElement {
return (
<div className={styles.page} style={tokenStyle}>
{/* 顶部标题与唯 1 主 CTA */}
{/* 顶部标题与唯一主 CTA */}
<div className={styles.header}>
<div className={styles.headerInfo}>
<div className={styles.titleRow}>
@@ -317,78 +312,84 @@ function Workplace(): React.ReactElement {
type="primary"
icon={<IconPlus />}
className={styles.primaryCta}
onClick={handleCreateCard}
onClick={() => handleNav('/card/list')}
>
{t['workplace.cta.newCard']}
</Button>
</div>
<Spin loading={loading} style={{ display: 'block' }}>
{/* KPI 核心指标阵列 */}
{/* 宽屏 17 : 7 弹性整体双栏架构 */}
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} lg={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.taps']}</span>
<span className={styles.kpiIconWrapper}>
<IconMobile className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.tapCount} />
{renderDelta(kpis.tapDelta)}
</Card>
</Col>
{/* 左侧业务主流程 (17/24 栅格) */}
<Col xs={24} xl={17}>
{/* KPI 核心指标阵列 */}
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} md={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.taps']}</span>
<span className={styles.kpiIconWrapper}>
<IconMobile className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.tapCount} />
{renderDelta(kpis.tapDelta)}
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.views']}</span>
<span className={styles.kpiIconWrapper}>
<IconEye className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.viewCount} />
{renderDelta(kpis.viewDelta)}
</Card>
</Col>
<Col xs={24} sm={12} md={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.views']}</span>
<span className={styles.kpiIconWrapper}>
<IconEye className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.viewCount} />
{renderDelta(kpis.viewDelta)}
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.leads']}</span>
<span className={styles.kpiIconWrapper}>
<IconUserAdd className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.newLeadCount} />
{renderDelta(kpis.newLeadDelta)}
</Card>
</Col>
<Col xs={24} sm={12} md={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.leads']}</span>
<span className={styles.kpiIconWrapper}>
<IconUserAdd className={styles.kpiIcon} />
</span>
</div>
<Statistic value={kpis.newLeadCount} />
{renderDelta(kpis.newLeadDelta)}
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.conversion']}</span>
<span className={styles.kpiIconWrapper}>
<IconIdcard className={styles.kpiIcon} />
</span>
</div>
<Statistic
value={kpis.conversionRate}
suffix="%"
precision={1}
/>
<div className={styles.kpiSubText}>
{t['workplace.kpi.conversionSub']}
</div>
</Card>
</Col>
</Row>
<Col xs={24} sm={12} md={6}>
<Card bordered={false} className={styles.kpiCard}>
<div className={styles.kpiHeader}>
<span className={styles.kpiTitle}>{t['workplace.kpi.conversion']}</span>
<span className={styles.kpiIconWrapper}>
<IconIdcard className={styles.kpiIcon} />
</span>
</div>
<Statistic
value={kpis.conversionRate}
suffix="%"
precision={1}
/>
<div className={styles.kpiSubText}>
{t['workplace.kpi.conversionSub']}
</div>
</Card>
</Col>
</Row>
{/* 运营官转化漏斗与渠道矩阵 */}
<Row gutter={[16, 16]} className={styles.middleRow}>
<Col xs={24} lg={16}>
<Card bordered={false} className={styles.panel} title={t['workplace.funnel.title']}>
{/* 出海转化漏斗 */}
<Card
bordered={false}
className={`${styles.panel} ${styles.funnelCard}`}
title={t['workplace.funnel.title']}
>
<div className={styles.funnelContainer}>
<div className={styles.funnelStep}>
<div className={styles.funnelLabel}>{t['workplace.funnel.tap']}</div>
@@ -459,43 +460,11 @@ function Workplace(): React.ReactElement {
</div>
</div>
</Card>
</Col>
<Col xs={24} lg={8}>
<Card bordered={false} className={styles.panel} title={t['workplace.channel.title']}>
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.nfc']}</span>
<span className={styles.channelPercent}>{channelStats.nfc}%</span>
</div>
<Progress percent={channelStats.nfc} color={lightColors.primary} showText={false} />
</div>
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.qr']}</span>
<span className={styles.channelPercent}>{channelStats.qr}%</span>
</div>
<Progress percent={channelStats.qr} color={lightColors.ai} showText={false} />
</div>
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.link']}</span>
<span className={styles.channelPercent}>{channelStats.link}%</span>
</div>
<Progress percent={channelStats.link} color={lightColors.text2} showText={false} />
</div>
</Card>
</Col>
</Row>
{/* 核心双栏:实时客商雷达流 VS 运营工具箱 */}
<Row gutter={[16, 16]} className={styles.main}>
<Col xs={24} lg={16}>
{/* 今日实时客商雷达流 */}
<Card
bordered={false}
className={styles.panel}
className={`${styles.panel} ${styles.radarCard}`}
title={
<div className={styles.panelHeader}>
<span>{t['workplace.radar.title']}</span>
@@ -520,7 +489,7 @@ function Workplace(): React.ReactElement {
</p>
}
/>
<Button type="text" onClick={handleOpenRadar}>
<Button type="text" onClick={() => handleNav('/dashboard/radar-map')}>
{t['workplace.radar.emptyAction']}
</Button>
</div>
@@ -568,88 +537,236 @@ function Workplace(): React.ReactElement {
</Card>
</Col>
{/* 运营工具箱 */}
<Col xs={24} lg={8}>
<Card
bordered={false}
className={styles.panel}
title={t['workplace.shortcut.title']}
>
<div className={styles.toolboxList}>
<button
type="button"
className={styles.shortcut}
onClick={handleIssueCards}
>
<div className={styles.shortcutIconBox}>
<IconIdcard className={styles.toolIcon} />
{/* 右侧出海运营快捷中枢 (7/24 栅格,完美填补用户红框空白) */}
<Col xs={24} xl={7}>
<div className={styles.hubContainer}>
{/* 模块 1:触达渠道健康度 */}
<Card bordered={false} className={styles.panel} title={t['workplace.channel.title']}>
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.nfc']}</span>
<span className={styles.channelPercent}>{channelStats.nfc}%</span>
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.issueCard']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.issueCardHint']}
</span>
</div>
</button>
<Progress percent={channelStats.nfc} color={lightColors.primary} showText={false} />
</div>
<button
type="button"
className={styles.shortcut}
onClick={handleExportLeads}
disabled={exporting}
>
<div className={styles.shortcutIconBox}>
<IconDownload className={styles.toolIcon} />
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.qr']}</span>
<span className={styles.channelPercent}>{channelStats.qr}%</span>
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.exportLeads']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.exportLeadsHint']}
</span>
</div>
</button>
<Progress percent={channelStats.qr} color={lightColors.ai} showText={false} />
</div>
<button
type="button"
className={styles.shortcut}
onClick={handleOpenRadar}
>
<div className={styles.shortcutIconBox}>
<IconCompass className={styles.toolIcon} />
<div className={styles.channelRow}>
<div className={styles.channelMeta}>
<span className={styles.channelName}>{t['workplace.channel.link']}</span>
<span className={styles.channelPercent}>{channelStats.link}%</span>
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.radarMap']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.radarMapHint']}
</span>
</div>
</button>
<Progress percent={channelStats.link} color={lightColors.text2} showText={false} />
</div>
</Card>
<button
type="button"
className={styles.shortcut}
onClick={handleOpenAiConfig}
>
<div className={styles.shortcutIconBox}>
<IconRobot className={styles.toolIcon} />
{/* 模块 2:高频业务快捷导航矩阵 (8大核心入口,2列微卡) */}
<Card
bordered={false}
className={styles.panel}
title={t['workplace.quickNav.title']}
>
<div className={styles.navGrid}>
{/* 1. 搭建微官网 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/card/builder')}
>
<div className={styles.navIconBox}>
<IconApps className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.builder']}</span>
<span className={styles.navSub}>{t['workplace.quick.builderHint']}</span>
</div>
</button>
{/* 2. 潜客线索 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/crm/leads')}
>
<div className={styles.navIconBox}>
<IconUserGroup className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.leads']}</span>
<span className={styles.navSub}>{t['workplace.quick.leadsHint']}</span>
</div>
</button>
{/* 3. 商机看板 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/crm/pipeline')}
>
<div className={styles.navIconBox}>
<IconSend className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.pipeline']}</span>
<span className={styles.navSub}>{t['workplace.quick.pipelineHint']}</span>
</div>
</button>
{/* 4. 批量发卡 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/nfc/batch')}
>
<div className={styles.navIconBox}>
<IconIdcard className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.batch']}</span>
<span className={styles.navSub}>{t['workplace.quick.batchHint']}</span>
</div>
</button>
{/* 5. 硬件台账 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/nfc/devices')}
>
<div className={styles.navIconBox}>
<IconDesktop className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.devices']}</span>
<span className={styles.navSub}>{t['workplace.quick.devicesHint']}</span>
</div>
</button>
{/* 6. 全球雷达大屏 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/dashboard/radar-map')}
>
<div className={styles.navIconBox}>
<IconCompass className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.radarMap']}</span>
<span className={styles.navSub}>{t['workplace.quick.radarMapHint']}</span>
</div>
</button>
{/* 7. AI 顾问接待 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/ai/concierge')}
>
<div className={styles.navIconBox}>
<IconRobot className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.aiConcierge']}</span>
<span className={styles.navSub}>{t['workplace.quick.aiConciergeHint']}</span>
</div>
</button>
{/* 8. 财务订阅看板 */}
<button
type="button"
className={styles.navCard}
onClick={() => handleNav('/dashboard/financial')}
>
<div className={styles.navIconBox}>
<IconSafe className={styles.navIcon} />
</div>
<div className={styles.navTextBox}>
<span className={styles.navTitle}>{t['workplace.quick.finance']}</span>
<span className={styles.navSub}>{t['workplace.quick.financeHint']}</span>
</div>
</button>
</div>
</Card>
{/* 模块 3:常用效率工具 */}
<Card
bordered={false}
className={styles.panel}
title={t['workplace.shortcut.title']}
>
<div className={styles.toolboxList}>
<button
type="button"
className={styles.shortcut}
onClick={handleExportLeads}
disabled={exporting}
>
<div className={styles.shortcutIconBox}>
<IconDownload className={styles.toolIcon} />
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.exportLeads']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.exportLeadsHint']}
</span>
</div>
</button>
<button
type="button"
className={styles.shortcut}
onClick={() => handleNav('/nfc/batch')}
>
<div className={styles.shortcutIconBox}>
<IconIdcard className={styles.toolIcon} />
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.issueCard']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.issueCardHint']}
</span>
</div>
</button>
</div>
</Card>
{/* 模块 4:出海待办预警 */}
<Card
bordered={false}
className={`${styles.panel} ${styles.alertPanel}`}
title={t['workplace.alerts.title']}
>
<div className={styles.alertContent}>
<div className={styles.alertItem}>
<div className={styles.alertDot} />
<div className={styles.alertText}>
{t['workplace.alerts.highIntentLead']}
</div>
</div>
<div className={styles.shortcutContent}>
<span className={styles.shortcutLabel}>
{t['workplace.shortcut.aiConfig']}
</span>
<span className={styles.shortcutHint}>
{t['workplace.shortcut.aiConfigHint']}
</span>
</div>
</button>
</div>
</Card>
<Button
type="outline"
size="small"
className={styles.alertActionBtn}
onClick={() => handleNav('/crm/leads')}
>
<span>{t['workplace.alerts.actionFollow']}</span>
<IconRight style={{ fontSize: 12, marginLeft: 4 }} />
</Button>
</div>
</Card>
</div>
</Col>
</Row>
</Spin>

查看文件

@@ -26,7 +26,25 @@ const i18n = {
'workplace.funnel.interact': 'Interactions',
'workplace.funnel.lead': 'CRM Leads',
'workplace.channel.title': 'Touch Channels',
'workplace.shortcut.title': 'Shortcuts',
'workplace.quickHub.title': 'Operations Command Hub',
'workplace.quickNav.title': 'Quick Navigation',
'workplace.quick.builder': 'Mini-site Builder',
'workplace.quick.builderHint': 'Craft Bento Grid mini-sites',
'workplace.quick.leads': 'Buyer Leads',
'workplace.quick.leadsHint': 'Follow up international clients',
'workplace.quick.pipeline': 'Deal Pipeline',
'workplace.quick.pipelineHint': 'Track stages and closed deals',
'workplace.quick.batch': 'Issue NFC',
'workplace.quick.batchHint': 'Batch print files and links',
'workplace.quick.devices': 'NFC Fleet',
'workplace.quick.devicesHint': 'Hardware device activations',
'workplace.quick.radarMap': 'Radar Map',
'workplace.quick.radarMapHint': 'Global 3D visitor heatmaps',
'workplace.quick.aiConcierge': 'AI Concierge',
'workplace.quick.aiConciergeHint': 'Multi-lingual greeting policy',
'workplace.quick.finance': 'Financials',
'workplace.quick.financeHint': 'Subscription metrics & MRR',
'workplace.shortcut.title': 'Operations Arsenal',
'workplace.shortcut.issueCard': 'Issue NFC cards',
'workplace.shortcut.issueCardHint': 'Generate short links and print files',
'workplace.shortcut.exportLeads': 'Export leads',
@@ -35,6 +53,9 @@ const i18n = {
'workplace.shortcut.radarMapHint': 'Explore real-time visitor geography and heatmaps',
'workplace.shortcut.aiConfig': 'AI Concierge Strategy',
'workplace.shortcut.aiConfigHint': 'Tune multi-lingual greeting and lead qualification',
'workplace.alerts.title': 'Actionable Alerts',
'workplace.alerts.highIntentLead': 'Buyer from Dubai stayed 210s in case studies without follow-up.',
'workplace.alerts.actionFollow': 'Follow Up Now',
'workplace.channel.nfc': 'NFC',
'workplace.channel.qr': 'QR Code',
'workplace.channel.link': 'Direct Link',
@@ -70,7 +91,25 @@ const i18n = {
'workplace.funnel.interact': '意向交互',
'workplace.funnel.lead': '商机留资',
'workplace.channel.title': '触达渠道分布',
'workplace.shortcut.title': '运营工具箱',
'workplace.quickHub.title': '出海运营快捷中枢',
'workplace.quickNav.title': '高频业务导航',
'workplace.quick.builder': '搭建微官网',
'workplace.quick.builderHint': '编辑便当盒微官网组件',
'workplace.quick.leads': '潜客线索',
'workplace.quick.leadsHint': '跟进出海海外意向买家',
'workplace.quick.pipeline': '商机看板',
'workplace.quick.pipelineHint': '推进出海商机全流程赢单',
'workplace.quick.batch': '批量制卡',
'workplace.quick.batchHint': '生成短链与批量印制物料',
'workplace.quick.devices': '硬件台账',
'workplace.quick.devicesHint': 'NFC 实体卡激活与状态',
'workplace.quick.radarMap': '雷达大屏',
'workplace.quick.radarMapHint': '全球客商访客实时热力图',
'workplace.quick.aiConcierge': 'AI 顾问',
'workplace.quick.aiConciergeHint': '多语言接待策略与留资阈值',
'workplace.quick.finance': '财务订阅',
'workplace.quick.financeHint': '订阅套餐与出海营收看板',
'workplace.shortcut.title': '运营效率工具箱',
'workplace.shortcut.issueCard': '批量发卡',
'workplace.shortcut.issueCardHint': '生成短链与制卡打印物料',
'workplace.shortcut.exportLeads': '导出线索',
@@ -79,6 +118,9 @@ const i18n = {
'workplace.shortcut.radarMapHint': '查看全球访客地理分布与实时热力图',
'workplace.shortcut.aiConfig': 'AI 顾问接待策略',
'workplace.shortcut.aiConfigHint': '配置多语言接待话术与自动留资意向阈值',
'workplace.alerts.title': '出海待办预警',
'workplace.alerts.highIntentLead': '迪拜客商在精选案例停留超过 210 秒,尚未安排专属跟进。',
'workplace.alerts.actionFollow': '立即跟进',
'workplace.channel.nfc': 'NFC',
'workplace.channel.qr': '二维码',
'workplace.channel.link': '直链',
@@ -114,7 +156,25 @@ const i18n = {
'workplace.funnel.interact': 'تفاعل مهتم',
'workplace.funnel.lead': 'عميل محتمل',
'workplace.channel.title': 'قنوات الاتصال',
'workplace.shortcut.title': 'صندوق أدوات التشغيل',
'workplace.quickHub.title': 'مركز قيادة العمليات',
'workplace.quickNav.title': 'الملاحة السريعة',
'workplace.quick.builder': 'منشئ الموقع المصغر',
'workplace.quick.builderHint': 'تصميم موقع نمط بينتو',
'workplace.quick.leads': 'العملاء المحتملون',
'workplace.quick.leadsHint': 'متابعة المشترين الدوليين',
'workplace.quick.pipeline': 'مراحل الصفقات',
'workplace.quick.pipelineHint': 'تتبع تقدم الصفقات المغلقة',
'workplace.quick.batch': 'إصدار NFC',
'workplace.quick.batchHint': 'توليد الروابط والطباعة',
'workplace.quick.devices': 'أجهزة NFC',
'workplace.quick.devicesHint': 'تنشيط الأجهزة والحالة',
'workplace.quick.radarMap': 'خريطة الرادار',
'workplace.quick.radarMapHint': 'خريطة حرارية للزوار عالمياً',
'workplace.quick.aiConcierge': 'المساعد الذكي',
'workplace.quick.aiConciergeHint': 'سياسة الترحيب متعددة اللغات',
'workplace.quick.finance': 'المالية والاشتراكات',
'workplace.quick.financeHint': 'مقاييس الاشتراكات والإيرادات',
'workplace.shortcut.title': 'صندوق أدوات العمليات',
'workplace.shortcut.issueCard': 'إصدار بطاقات NFC',
'workplace.shortcut.issueCardHint': 'إنشاء الروابط وملفات الطباعة للبطاقات',
'workplace.shortcut.exportLeads': 'تصدير العملاء',
@@ -123,6 +183,9 @@ const i18n = {
'workplace.shortcut.radarMapHint': 'استكشف التوزيع الجغرافي للزوار وخريطة الحرارة',
'workplace.shortcut.aiConfig': 'استراتيجية المساعد الذكي',
'workplace.shortcut.aiConfigHint': 'تكوين الترحيب متعدد اللغات وتأهيل العملاء المحتملين',
'workplace.alerts.title': 'تنبيهات قابلة للتنفيذ',
'workplace.alerts.highIntentLead': 'مشتري من دبي مكث 210 ثوانٍ في دراسات الحالة دون متابعة.',
'workplace.alerts.actionFollow': 'متابعة الآن',
'workplace.channel.nfc': 'NFC',
'workplace.channel.qr': 'رمز QR',
'workplace.channel.link': 'رابط مباشر',

查看文件

@@ -1,9 +1,12 @@
.page {
min-height: 100%;
max-width: 1200px;
width: 100%;
max-width: 1680px;
margin: 0 auto;
padding: var(--omni-space-24);
background: var(--omni-color-surface);
font-family: var(--omni-font-family);
box-sizing: border-box;
}
.header {
@@ -12,7 +15,7 @@
justify-content: space-between;
gap: var(--omni-space-16);
flex-wrap: wrap;
margin-bottom: var(--omni-space-24);
margin-bottom: var(--omni-space-20);
}
.headerInfo {
@@ -169,8 +172,8 @@
color: var(--omni-color-error);
}
/* 漏斗与渠道矩阵 */
.middleRow {
/* 漏斗与雷达卡片 */
.funnelCard {
margin-top: var(--omni-space-16);
}
@@ -223,35 +226,7 @@
background: var(--omni-color-success);
}
/* 渠道占比 */
.channelRow {
margin-bottom: var(--omni-space-16);
}
.channelRow:last-child {
margin-bottom: 0;
}
.channelMeta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--omni-space-8);
font-size: 13px;
}
.channelName {
color: var(--omni-color-text);
font-weight: 500;
}
.channelPercent {
color: var(--omni-color-text-2);
font-weight: 600;
}
/* 主内容区域 */
.main {
.radarCard {
margin-top: var(--omni-space-16);
}
@@ -296,11 +271,123 @@
line-height: 1.6;
}
/* 运营工具箱 */
/* ========================================================
右侧出海运营快捷中枢 (Command Hub)
======================================================== */
.hubContainer {
display: flex;
flex-direction: column;
gap: var(--omni-space-16);
}
/* 渠道占比 */
.channelRow {
margin-bottom: var(--omni-space-12);
}
.channelRow:last-child {
margin-bottom: 0;
}
.channelMeta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--omni-space-6);
font-size: 12px;
}
.channelName {
color: var(--omni-color-text);
font-weight: 500;
}
.channelPercent {
color: var(--omni-color-text-2);
font-weight: 600;
}
/* 8 大核心快捷入口网格 (2列) */
.navGrid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--omni-space-10, 10px);
}
.navCard {
display: flex;
align-items: flex-start;
gap: var(--omni-space-10, 10px);
padding: 10px;
border: 1px solid var(--omni-color-border);
border-radius: 12px;
background: var(--omni-color-surface);
text-align: start;
cursor: pointer;
transition: all 150ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.navCard:hover {
background: var(--omni-color-bg);
border-color: rgba(11, 92, 255, 0.35);
box-shadow: 0 2px 6px rgba(11, 92, 255, 0.08);
transform: translateY(-1px);
}
.navCard:focus-visible {
outline: 2px solid var(--omni-color-primary);
outline-offset: 2px;
}
.navIconBox {
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border-radius: 8px;
background: var(--omni-color-bg);
color: var(--omni-color-primary);
flex-shrink: 0;
border: 1px solid var(--omni-color-border);
}
.navIcon {
font-size: 15px;
}
.navTextBox {
flex: 1;
min-width: 0;
}
.navTitle {
display: block;
color: var(--omni-color-text);
font-size: 13px;
font-weight: 600;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.navSub {
display: block;
margin-top: 2px;
color: var(--omni-color-text-2);
font-size: 11px;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 效率工具箱 */
.toolboxList {
display: flex;
flex-direction: column;
gap: var(--omni-space-12);
gap: var(--omni-space-10, 10px);
}
.shortcut {
@@ -308,7 +395,7 @@
align-items: flex-start;
gap: var(--omni-space-12);
width: 100%;
padding: var(--omni-space-12);
padding: 10px 12px;
border: 1px solid var(--omni-color-border);
border-radius: 12px;
background: var(--omni-color-surface);
@@ -338,16 +425,17 @@
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
width: 30px;
height: 30px;
border-radius: 8px;
background: var(--omni-color-bg);
color: var(--omni-color-primary);
flex-shrink: 0;
border: 1px solid var(--omni-color-border);
}
.toolIcon {
font-size: 16px;
font-size: 15px;
}
.shortcutContent {
@@ -358,21 +446,68 @@
.shortcutLabel {
display: block;
color: var(--omni-color-text);
font-size: 14px;
font-size: 13px;
font-weight: 500;
line-height: 1.4;
}
.shortcutHint {
display: block;
margin-top: var(--omni-space-4);
margin-top: 2px;
color: var(--omni-color-text-2);
font-size: 12px;
font-size: 11px;
line-height: 1.4;
}
/* 待办预警卡片 */
.alertPanel {
border-color: rgba(247, 144, 9, 0.3) !important;
background: #FFFDF9 !important;
}
.alertContent {
display: flex;
flex-direction: column;
gap: var(--omni-space-12);
}
.alertItem {
display: flex;
align-items: flex-start;
gap: var(--omni-space-8);
}
.alertDot {
width: 6px;
height: 6px;
margin-top: 6px;
border-radius: 50%;
background-color: var(--omni-color-warning, #F79009);
flex-shrink: 0;
}
.alertText {
color: var(--omni-color-text);
font-size: 12px;
line-height: 1.5;
}
.alertActionBtn {
align-self: flex-start;
border-radius: var(--omni-radius-button);
color: var(--omni-color-text);
border-color: var(--omni-color-border);
font-size: 12px;
}
.alertActionBtn:hover {
border-color: var(--omni-color-primary);
color: var(--omni-color-primary);
}
@media (prefers-reduced-motion: reduce) {
.shortcut:hover {
.shortcut:hover,
.navCard:hover {
transform: none;
}
.pulseDot {