From eb39cc1baa0506b0909dd68bc34f2d56f270ef96 Mon Sep 17 00:00:00 2001 From: wlt Date: Wed, 24 Jun 2026 10:38:11 +0800 Subject: [PATCH] feat: restructure pricing models, add upgrade modal and ecosystem UI --- user-frontend/src/api/index.js | 4 + user-frontend/src/components/UpgradeModal.vue | 242 +++++++++++ user-frontend/src/layouts/UserLayout.vue | 27 +- user-frontend/src/router/index.js | 1 + user-frontend/src/views/NewHome.vue | 86 +++- user-frontend/src/views/Upgrade.vue | 384 +++++++++++++----- user-frontend/src/views/WorkspaceLanding.vue | 149 +++++++ 7 files changed, 782 insertions(+), 111 deletions(-) create mode 100644 user-frontend/src/components/UpgradeModal.vue diff --git a/user-frontend/src/api/index.js b/user-frontend/src/api/index.js index 41531da..d569057 100644 --- a/user-frontend/src/api/index.js +++ b/user-frontend/src/api/index.js @@ -18,6 +18,10 @@ http.interceptors.response.use( const path = window.location.pathname.replace('/workspace', '') || '/' window.location.href = '/workspace/login?redirect=' + encodeURIComponent(path) } + if (err.response?.status === 402) { + const detail = err.response?.data?.detail || '次数不足' + window.dispatchEvent(new CustomEvent('trademate:upgrade', { detail: { message: detail } })) + } return Promise.reject(err.response?.data || err) } ) diff --git a/user-frontend/src/components/UpgradeModal.vue b/user-frontend/src/components/UpgradeModal.vue new file mode 100644 index 0000000..3c27cb7 --- /dev/null +++ b/user-frontend/src/components/UpgradeModal.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/user-frontend/src/layouts/UserLayout.vue b/user-frontend/src/layouts/UserLayout.vue index 45526e4..9d20ed8 100644 --- a/user-frontend/src/layouts/UserLayout.vue +++ b/user-frontend/src/layouts/UserLayout.vue @@ -30,6 +30,7 @@ {{ $t('nav.more') || '更多' }} + {{ $t('nav.upgrade') || '升级套餐' }} {{ $t('nav.profile') }} {{ $t('nav.team') }} @@ -47,9 +48,12 @@
{{ currentLang }} - + - {{ creditBalance }} {{ $t('topbar.credits') }} + + {{ creditBalance }} {{ $t('topbar.credits') }} + · 升级 + @@ -80,6 +84,8 @@
+ + @@ -90,6 +96,8 @@ import { useI18n } from 'vue-i18n' import { useAuthStore } from '@/stores/auth' import { getUnreadCount, getCreditBalance } from '@/api' import CommandK from '@/components/CommandK.vue' +import AiAssistant from '@/components/AiAssistant.vue' +import UpgradeModal from '@/components/UpgradeModal.vue' import { switchLang } from '@/i18n' const route = useRoute() @@ -100,6 +108,9 @@ const collapsed = ref(window.innerWidth < 1024) const showMobileMenu = ref(false) const unread = ref(0) const creditBalance = ref(null) +const showUpgradeModal = ref(false) + +const creditLow = computed(() => creditBalance.value !== null && creditBalance.value < 10) function handleResize() { const w = window.innerWidth @@ -121,6 +132,14 @@ function toggleLang() { switchLang(next) } +function onCreditClick() { + if (creditLow.value) { + showUpgradeModal.value = true + } else { + router.push('/workspace/profile/credits') + } +} + async function loadCreditBalance() { try { const res = await getCreditBalance() @@ -180,6 +199,10 @@ function handleLogout() { .topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-shrink: 0; } .notif-badge :deep(.el-badge__content) { top: 8px; right: 4px; } .credit-btn { display: flex; align-items: center; gap: 4px; color: #e6a23c !important; font-weight: 600; } +.credit-btn.credit-low { color: #dc2626 !important; animation: pulse-warn 2s infinite; } +@keyframes pulse-warn { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } +.credit-text { font-size: 13px; } +.credit-warn { font-size: 12px; font-weight: 400; } /* ===== Desktop: > 1024px ===== */ @media (min-width: 1025px) { diff --git a/user-frontend/src/router/index.js b/user-frontend/src/router/index.js index 6592e64..7fa2181 100644 --- a/user-frontend/src/router/index.js +++ b/user-frontend/src/router/index.js @@ -9,6 +9,7 @@ const routes = [ meta: { requiresAuth: true }, children: [ { path: '', name: 'Home', component: () => import('@/views/NewHome.vue'), meta: { title: '首页' } }, + { path: 'upgrade', name: 'Upgrade', component: () => import('@/views/Upgrade.vue'), meta: { title: '升级套餐' } }, { path: 'customers', name: 'Customers', component: () => import('@/views/WorkspaceCustomer.vue'), meta: { title: '客户工作台' } }, { path: 'biz', name: 'Biz', component: () => import('@/views/WorkspaceBiz.vue'), meta: { title: '业务工作台' } }, { path: 'analytics', name: 'Analytics', component: () => import('@/views/Analytics.vue'), meta: { title: '数据分析' } }, diff --git a/user-frontend/src/views/NewHome.vue b/user-frontend/src/views/NewHome.vue index 330a26c..5e92e73 100644 --- a/user-frontend/src/views/NewHome.vue +++ b/user-frontend/src/views/NewHome.vue @@ -14,6 +14,66 @@ + + +
+
+ 网页端 + 全功能工作台 +
+
+
+ 插件 + Chrome 浏览器扩展 +
+
+
+ 技能 + AI 技能包 (SKILL.md) +
+ 了解更多 → +
+ + + + +
+
+
+ +
+
+

网页工作台

+

你现在正在使用。所有功能都在这里:翻译、客户管理、营销、AI 数字员工

+
+
+
+
+ +
+
+

Chrome 浏览器插件

+

划词翻译、一键客户搜索、快捷回复。项目目录 browser-extension/ 加载到 chrome://extensions/ 即可使用

+ 下载插件 +
+
+
+
+ +
+
+

AI 技能包 (SKILL.md)

+

安装到 Cursor / Claude Code / OpenCode 后,用自然语言触发 TradeMate 能力。项目目录 .opencode/skills/

+ translate-reply + customer-discovery + marketing-content +
+
+ +

三者共享同一账号和数据,订阅任意入口即全平台可用

+
+
+ @@ -107,13 +167,20 @@ import { ref, computed, onMounted } from 'vue' import { useAuthStore } from '@/stores/auth' import { useI18n } from 'vue-i18n' -import { User, ChatLineSquare, DocumentCopy, EditPen, CircleCheck, CircleClose, Loading } from '@element-plus/icons-vue' +import { User, ChatLineSquare, DocumentCopy, EditPen, CircleCheck, CircleClose, Loading, Monitor, ChromeFilled, Tools } from '@element-plus/icons-vue' import { getCreditBalance, getAnalyticsOverview, listAgentPipelines, getAgentPipeline } from '@/api' const { t } = useI18n() const auth = useAuthStore() const creditBalance = ref(null) const stats = ref([]) + +// Ecosystem modal +const showEcoModal = ref(false) +function downloadExtension() { + window.open('https://github.com/wlt/trade-assistant/tree/main/browser-extension', '_blank') +} + const pipelines = ref([]) const selectedPipeline = ref(null) const selectedId = ref(null) @@ -205,6 +272,23 @@ onMounted(async () => { .credit-amount { font-size: 24px; font-weight: 700; } .credit-amount small { font-size: 13px; font-weight: 400; opacity: 0.8; } +.ecosystem-card { margin-bottom: 16px; } +.eco-inner { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } +.eco-item { display: flex; align-items: center; gap: 6px; cursor: pointer; padding: 2px 4px; border-radius: 6px; transition: background 0.2s; } +.eco-item:hover { background: #f0f4ff; } +.eco-tag { font-weight: 600; font-size: 11px; } +.eco-label { font-size: 13px; color: #475569; white-space: nowrap; } +.eco-divider { width: 1px; height: 20px; background: #e5e7eb; } +.eco-more { margin-left: auto; } +.eco-modal-body { padding: 8px 0; } +.eco-modal-item { display: flex; gap: 14px; margin-bottom: 20px; } +.eco-modal-icon { width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } +.eco-modal-text h4 { margin: 0 0 4px; font-size: 15px; color: #1e293b; } +.eco-modal-text p { margin: 0; font-size: 13px; color: #64748b; line-height: 1.5; } +.eco-modal-text code { background: #f0f4ff; color: #1890ff; padding: 1px 5px; border-radius: 4px; font-size: 12px; } +.eco-modal-text .el-tag { margin-right: 4px; } +.eco-modal-foot { text-align: center; font-size: 13px; color: #94a3b8; } + .stats-row { margin-bottom: 20px; } .stat-card { cursor: pointer; text-align: center; transition: all 0.25s; } .stat-card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.08); } diff --git a/user-frontend/src/views/Upgrade.vue b/user-frontend/src/views/Upgrade.vue index b846ae1..e9f4eee 100644 --- a/user-frontend/src/views/Upgrade.vue +++ b/user-frontend/src/views/Upgrade.vue @@ -1,137 +1,305 @@ diff --git a/user-frontend/src/views/WorkspaceLanding.vue b/user-frontend/src/views/WorkspaceLanding.vue index 20f11e6..f949b27 100644 --- a/user-frontend/src/views/WorkspaceLanding.vue +++ b/user-frontend/src/views/WorkspaceLanding.vue @@ -74,6 +74,117 @@
+ +
+

TradeMate 产品生态

+

一个账号,三种方式使用。网页端、浏览器插件、AI 编程技能包,覆盖所有场景

+
+
+
+

网页工作台

+

全功能外贸工作台:翻译、客户管理、营销生成、报价单、AI 数字员工。浏览器打开即用

+
    +
  • 智能翻译 · 20+ 语言
  • +
  • CRM 客户管理 + 健康评分
  • +
  • AI 营销文案 + 报价单
  • +
  • AI 数字员工自动化
  • +
+
当前产品
+
+
+
+

浏览器插件

+

Chrome 扩展,可在任何网页上使用 TradeMate 功能。划词翻译、快速客户搜索、营销生成

+
    +
  • 右键划词翻译
  • +
  • 一键搜索潜在客户
  • +
  • AI 回复建议生成
  • +
  • 与网页工作台数据互通
  • +
+ 安装说明 +
+
+
+

AI 技能包

+

开源 SKILL.md 技能包,安装到 Cursor、Claude Code、OpenCode 等 AI 编程工具中直接调用

+
    +
  • 翻译 + 回复生成
  • +
  • 客户发现 + 信息提取
  • +
  • 营销内容生成
  • +
  • 跨平台兼容(Cursor / Claude / OpenCode)
  • +
+ 查看技能 +
+
+ + + +
+

安装方式

+
+ 1 + 下载项目中的 browser-extension 目录到本地 +
+
+ 2 + 打开 Chrome 浏览器,进入 chrome://extensions/ +
+
+ 3 + 开启"开发者模式"(右上角开关) +
+
+ 4 + 点击"加载已解压的扩展程序",选择 browser-extension 目录 +
+
+ 5 + 点击浏览器工具栏的 TradeMate 图标,输入 API 地址和登录凭据即可使用 +
+ +

功能预览

+
+
🌐 翻译 输入文本翻译、右键划词翻译
+
💬 回复 根据询盘生成专业/友好的回复建议
+
🔍 发现 Google 搜索潜在客户,提取联系方式
+
📝 营销 生成产品营销文案和关键词
+
+

注意:需要先登录 TradeMate 工作台获取 Token

+
+
+ + + +
+

可用的技能包

+ + + + + + +

安装方式

+
+ 1 + 确认你使用的工具支持 SKILL.md(Cursor / Claude Code / OpenCode 等) +
+
+ 2 + .opencode/skills/ 目录下的 .md 文件放入工具的技能目录 +
+
+ 3 + 在工具中通过关键词触发(如"翻译这段"、"找客户"、"生成营销文案") +
+
+ 4 + 需要配置 TRADEMATE_API_URLTRADEMATE_API_KEY +
+

技能包不消耗额外费用,使用你的 TradeMate 账号积分。

+
+
+
+