From 04924e3bc46b3ce9a4c8ed74f4c064231a83b3f8 Mon Sep 17 00:00:00 2001 From: TradeMate Dev Date: Sun, 12 Jul 2026 08:09:28 +0800 Subject: [PATCH] refactor: switch to free-trial/private-deploy/buyout pricing, fix feature gaps, add SEO landing + deploy config --- .opencode/skills/customer-discovery.md | 85 ----- .opencode/skills/marketing-content.md | 106 ------ .opencode/skills/translate-reply.md | 97 ----- AGENTS.md | 33 +- PROGRESS.md | 119 ++++++- README.md | 58 ++- admin-frontend/src/api/index.js | 5 +- admin-frontend/src/views/Users.vue | 8 +- .../alembic/versions/add_enterprise_leads.py | 40 +++ backend/app/api/v1/leads.py | 34 ++ backend/app/core/csrf.py | 1 + backend/app/main.py | 3 +- backend/app/models/__init__.py | 2 + backend/app/models/enterprise_lead.py | 17 + backend/tests/test_leads_api.py | 36 ++ browser-extension/api/client.js | 7 + browser-extension/popup/index.html | 39 +- browser-extension/popup/popup.js | 32 +- deploy/frontend/nginx.conf | 65 ++-- landing/index.html | 324 +++++++++++++++++ landing/robots.txt | 22 ++ landing/sitemap.xml | 34 ++ opencode-search-mcp/.gitignore | 2 - opencode-search-mcp/package.json | 20 -- opencode-search-mcp/src/index.ts | 139 -------- opencode-search-mcp/tsconfig.json | 13 - tests/package-lock.json | 16 +- tests/package.json | 2 +- uni-app/index.html | 20 +- uni-app/src/pages/upgrade/upgrade.vue | 135 ++++--- uni-app/src/utils/api.js | 4 + user-frontend/src/api/index.js | 2 + user-frontend/src/components/UpgradeModal.vue | 142 ++------ user-frontend/src/layouts/UserLayout.vue | 1 + user-frontend/src/router/index.js | 3 +- user-frontend/src/views/Upgrade.vue | 335 +++++------------- 36 files changed, 1026 insertions(+), 975 deletions(-) delete mode 100644 .opencode/skills/customer-discovery.md delete mode 100644 .opencode/skills/marketing-content.md delete mode 100644 .opencode/skills/translate-reply.md create mode 100644 backend/alembic/versions/add_enterprise_leads.py create mode 100644 backend/app/api/v1/leads.py create mode 100644 backend/app/models/enterprise_lead.py create mode 100644 backend/tests/test_leads_api.py create mode 100644 landing/index.html create mode 100644 landing/robots.txt create mode 100644 landing/sitemap.xml delete mode 100644 opencode-search-mcp/.gitignore delete mode 100644 opencode-search-mcp/package.json delete mode 100644 opencode-search-mcp/src/index.ts delete mode 100644 opencode-search-mcp/tsconfig.json diff --git a/.opencode/skills/customer-discovery.md b/.opencode/skills/customer-discovery.md deleted file mode 100644 index bd1d294..0000000 --- a/.opencode/skills/customer-discovery.md +++ /dev/null @@ -1,85 +0,0 @@ -# TradeMate Customer Discovery Skill - -Search and discover potential foreign trade customers from the web. - -## Description - -Automatically searches Google for potential buyers in your target market, extracts company information and contact details (email, phone, WhatsApp), and scores leads by relevance. Helps foreign trade professionals find new customers without manual browsing. - -## Triggers - -- "find customers" / "找客户" -- "discover leads" / "发现潜在客户" -- "search buyers" / "搜索买家" -- "customer discovery" / "客户发现" - -## Workflow - -### 1. Search for Potential Customers - -``` -POST /api/v1/discovery/search -Content-Type: application/json -Authorization: Bearer - -{ - "keyword": "", - "market": "US|UK|DE|FR|AU|...", // target country code - "max_results": 10 -} -``` - -Response: -```json -{ - "results": [ - { - "title": "Company Name", - "url": "https://company-website.com", - "description": "...", - "emails": ["info@company.com"], - "phones": ["+1-xxx-xxx-xxxx"], - "social": { - "whatsapp": "...", - "wechat": "..." - }, - "relevance_score": 85 - } - ], - "total": 10 -} -``` - -### 2. Save High-Scoring Leads - -High-scoring leads (score >= 70) are automatically saved as Customer records in the TradeMate CRM via the Agent pipeline: - -``` -POST /api/v1/agent/start -Content-Type: application/json -Authorization: Bearer - -{ - "product_name": "", - "product_description": "", - "target_market": "" -} -``` - -## Configuration - -Requires a running TradeMate backend instance with: -- Google Custom Search API configured -- Valid API token with discovery credits - -```bash -export TRADEMATE_API_URL=http://localhost:8000 -export TRADEMATE_API_KEY= -``` - -## Notes - -- Each search consumes discovery credits (check balance via `GET /api/v1/credits/balance`) -- Free tier: limited searches per day -- Pro tier: expanded daily quota -- Enterprise tier: unlimited searches + auto-save to CRM diff --git a/.opencode/skills/marketing-content.md b/.opencode/skills/marketing-content.md deleted file mode 100644 index 2a20400..0000000 --- a/.opencode/skills/marketing-content.md +++ /dev/null @@ -1,106 +0,0 @@ -# TradeMate Marketing Content Skill - -Generate marketing copy and keyword suggestions for foreign trade products. - -## Description - -AI-powered marketing content generation for export products. Creates professional marketing copy in multiple languages and styles, generates SEO keywords, and analyzes competitor positioning. Designed for foreign trade professionals who need compelling product descriptions for international buyers. - -## Triggers - -- "generate marketing" / "生成营销文案" -- "write product description" / "写产品描述" -- "marketing keywords" / "营销关键词" -- "product copy" / "产品文案" - -## Workflow - -### 1. Generate Marketing Copy - -``` -POST /api/v1/marketing/generate -Content-Type: application/json -Authorization: Bearer - -{ - "product_name": "", - "description": "", - "category": "", - "target": "", - "style": "professional|friendly|luxury", - "count": 3, - "language": "en|zh" -} -``` - -Response: -```json -{ - "results": [ - { - "content": "Professional marketing copy...", - "style": "professional", - "provider": "sensenova" - } - ], - "product": "...", - "target": "...", - "count": 3, - "credits_remaining": 45 -} -``` - -### 2. Generate Keywords - -``` -POST /api/v1/marketing/keywords -Content-Type: application/json -Authorization: Bearer - -{ - "product_name": "", - "description": "", - "category": "", - "language": "en", - "count": 10 -} -``` - -Response: -```json -{ - "keywords": ["keyword1", "keyword2", ...], - "product": "...", - "credits_remaining": 45 -} -``` - -### 3. Competitor Analysis - -``` -POST /api/v1/marketing/competitor-analysis -Content-Type: application/json -Authorization: Bearer - -{ - "product_name": "", - "description": "", - "competitors": ["competitor1", "competitor2"] -} -``` - -## Configuration - -Requires a running TradeMate backend instance: - -```bash -export TRADEMATE_API_URL=http://localhost:8000 -export TRADEMATE_API_KEY= -``` - -## Notes - -- Each generation consumes 5 marketing credits -- Free tier: limited daily generations -- Multiple AI providers (Sensenova / NVIDIA) with automatic fallback -- Supports English and Chinese output diff --git a/.opencode/skills/translate-reply.md b/.opencode/skills/translate-reply.md deleted file mode 100644 index 9b5c670..0000000 --- a/.opencode/skills/translate-reply.md +++ /dev/null @@ -1,97 +0,0 @@ -# TradeMate Translate & Reply Skill - -Translate foreign trade inquiries and generate professional replies. - -## Description - -AI-powered translation and smart reply generation for foreign trade professionals. Supports Chinese-English bidirectional translation with trade-specific context, and generates reply suggestions in multiple tones (professional/friendly). - -## Triggers - -- "translate this" / "翻译" -- "reply to inquiry" / "回复询盘" -- "generate reply" / "生成回复" -- "translate for trade" / "外贸翻译" - -## Workflow - -### 1. Translate Text - -``` -POST /api/v1/translate -Content-Type: application/json -Authorization: Bearer - -{ - "text": "", - "target_lang": "zh|en", - "context": "trade" // optional, adds trade-specific context -} -``` - -Response: -```json -{ - "translated_text": "...", - "source_lang": "en", - "provider_used": "sensenova", - "from_cache": false -} -``` - -### 2. Generate Reply - -``` -POST /api/v1/translate/reply -Content-Type: application/json -Authorization: Bearer - -{ - "inquiry": "", - "tone": "professional|friendly", - "count": 2, - "context": { - "product": "", - "price": "" - } -} -``` - -Response: -```json -{ - "suggestions": [ - {"reply": "...", "tone": "professional", "provider": "sensenova"}, - {"reply": "...", "tone": "friendly", "provider": "sensenova"} - ], - "count": 2 -} -``` - -### 3. Extract Info from Inquiry - -``` -POST /api/v1/translate/extract -Content-Type: application/json -Authorization: Bearer - -{ - "text": "", - "extract_type": "inquiry" -} -``` - -## Configuration - -Requires a running TradeMate backend instance. Set environment variables: - -```bash -export TRADEMATE_API_URL=http://localhost:8000 -export TRADEMATE_API_KEY= -``` - -## Notes - -- Free tier: limited daily translations -- Pro tier: unlimited usage -- Uses Sensenova (商汤) as default AI provider, falls back to NVIDIA diff --git a/AGENTS.md b/AGENTS.md index f84491d..c480c1e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,20 @@ # TradeMate (外贸小助手) — Agent Guide +## Chrome 浏览器扩展 🆕 + +- **目录**: `browser-extension/` — 完整 Chrome 插件 +- **功能**: popup 面板调用 AI 翻译/回复/提取客户信息、网页右键菜单集成、自动填写报价单 +- **兼容平台**: LinkedIn / Amazon / AliExpress 等外贸平台页面 +- **安装**: 打开 `chrome://extensions` → 加载已解压的扩展 → 选择 `browser-extension/` 目录 +- **API 客户端**: `browser-extension/api/client.js` — 封装后端 API 调用,支持 JWT 认证 + +## UX Design + +- **PC 工作台**: 侧边栏 5 项精简导航 (首页/客户/业务/翻译/更多) + **CommandK 命令面板** (Ctrl+K) +- **移动端 H5**: 底部 4 Tab 导航 (首页/客户/业务/我的) +- **工作区合并**: Customers/Discovery/Followup → `WorkspaceCustomer`;Translate/Products/Quotations/Marketing → `WorkspaceBiz` +- **路由**: 旧页面保留隐藏路由,保证兼容性 + ## uni-app 移动端 H5 (改版后) - **Tab Bar**: 4 项底部导航 — 首页 / 客户 / 业务 / 我的 @@ -36,9 +51,16 @@ - `GET /api/v1/agent/pipelines` — 任务列表 - `GET /api/v1/agent/{pipeline_id}` — 任务详情 - **流程**: 用户输入产品+市场 → AgentOrchestrator 串接 DiscoveryService.search() → analyze() → outreach() → 自动保存高匹配客户 -- **前端入口**: `UserLayout.vue` 侧边栏首位 "AI数字员工" (MagicStick 图标) +- **前端入口**: `user-frontend/src/views/Agent.vue` 已接入路由 `/workspace/agent` 与 `UserLayout.vue` 侧边栏 "AI数字员工" (MagicStick 图标);`/agent` 重定向到 `/workspace/agent` - **迁移**: 需要运行 `alembic revision --autogenerate -m "add agent_pipelines"` 创建 `agent_pipelines` 表 +## 收费方式(免费试用 / 私有化部署 / 买断源码) + +- **页面**: `user-frontend/src/views/Upgrade.vue` + `UpgradeModal.vue`、`uni-app/src/pages/upgrade/upgrade.vue`、浏览器插件升级入口均改为三种方案:免费试用 / 私有化部署(年付授权)/ 买断源码(一次性) +- **企业线索**: 私有化部署与买断源码的 CTA 提交到 `POST /api/v1/leads`(模型 `EnterpriseLead`,表 `enterprise_leads`),无需登录;admin 可在 `enterprise_leads` 表查看 +- **价格占位**: `Upgrade.vue` 中 `PRICING` 对象(¥39,800/年、¥98,000 一次性)为可配置展示值 +- **说明**: 旧的按月订阅套餐(`/credits/subscribe`)仍存在于后端,但前端不再主推;如彻底下线订阅需同步清理 `credits.py` 订阅逻辑 + ## Architecture - **Backend**: `backend/` — FastAPI + SQLAlchemy 1.4 async + asyncpg, single `app.main:app` @@ -50,8 +72,8 @@ ## AI Providers -- **Active**: Sensenova (商汤), NVIDIA, 阿里机器翻译 (alibaba-mt) — 5 providers in DB -- **Removed**: Claude, DeepL, Local, OpencodeGo, 讯飞 Spark — all git rm'd +- **Active (seeded by `seed_from_env()`)**: Sensenova (商汤, if `SENSENOVA_API_KEY` set), NVIDIA (if `NVIDIA_API_KEY` set), 阿里翻译 alibaba-mt (always inserted) — at most 3 rows. Do NOT assume 5 providers exist. +- **Removed**: Claude, DeepL, Local, OpencodeGo, 讯飞 Spark — provider implementations were git rm'd; don't re-add them. - **DB-driven**: `AIProvider` model + `admin_ai.py` API — manage providers at runtime. `router.seed_from_env()` loads from `.env` on startup - **ECS RAM role**: 阿里翻译使用 ECS 实例 RAM 角色 `trademate-translate` 获取 STS 临时凭证 - **Provider type mapping** in `router.py._build_provider()`: sensenova, nvidia, alibaba-mt @@ -90,6 +112,8 @@ cd user-frontend && npm run dev # port 5174, base: /workspace/ cd backend && venv/bin/pytest # all venv/bin/pytest tests/test_auth_api.py # single file venv/bin/pytest tests/ -k "test_login" # keyword filter +# pytest.ini: asyncio_mode=auto (no @pytest.mark.asyncio needed) and +# addopts adds --cov=app coverage automatically on every run. # Builds cd uni-app && npm run build:h5 # uni-app (mobile H5) @@ -110,6 +134,7 @@ alembic revision --autogenerate -m "desc" - **Nginx**: SPA fallbacks for `/app/`, `/admin/`, `/workspace/` - **vite config**: each project has its own `base` path and dev port - **API**: proxied via nginx `location /api/` to `127.0.0.1:8000` +- **Makefile `make deploy`** references `docker-compose.prod.yml` / `docker-compose.staging.yml`, which do **not** exist (only `docker-compose.yml` is present). Those targets are currently broken. ## Critical Quirks @@ -132,7 +157,7 @@ alembic revision --autogenerate -m "desc" ## Project Conventions -- **No README.md** — key context is in `PROGRESS.md` and `docs/` +- **Docs**: `README.md` (overview), `PROGRESS.md` (task status), `docs/` (API/schema/architecture). README references this file for dev norms. - **Chinese UI** — mobile-first, for foreign-trade SOHOs/small teams - **No comments in code** unless explicitly asked - **Commit messages** focus on "why" not "what", in English diff --git a/PROGRESS.md b/PROGRESS.md index f6a50e6..6e03288 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,7 +1,7 @@ # TradeMate (外贸小助手) - 项目进度文档 -**更新时间**: 2026-06-16 18:30 -**状态**: ✅ 生产环境运行中 — AI 路由 DB 驱动 + 翻译配额全链路 + ECS RAM 角色认证 + AI 数字员工 +**更新时间**: 2026-07-11 +**状态**: ✅ 生产环境运行中 — 收费方式调整(免费试用/私有化部署/买断源码)+ 功能审计补全 + SEO 营销落地页 + 部署优化 --- @@ -82,7 +82,7 @@ | **编排服务** | `services/agent_orchestrator.py` | 串接 DiscoveryService → 分析 → 评分 → 触达 → 自动入库 | | **Agent API** | `api/v1/agent.py` | 3 端点: POST /start, GET /pipelines, GET /{id} | | **Agent 仪表盘** | `user-frontend/src/views/Agent.vue` | 统计卡片 + 任务列表 + 流水线进度 + 线索表格 + 触达预览 | -| **侧边栏入口** | `layouts/UserLayout.vue` | "AI数字员工" 作为首位菜单项,图标 MagicStick | +| **侧边栏入口** | `layouts/UserLayout.vue` | "AI数字员工" 已接入路由 `/workspace/agent` 与侧边栏菜单(图标 MagicStick);`/agent` 重定向到 `/workspace/agent` | **工作流程**: 1. 用户输入产品名称 + 描述 + 目标市场 @@ -199,7 +199,69 @@ | Docker Compose 增强 | 添加 nginx/admin/user/uni-app 服务 + 独立网络 + Redis AOF | | CSRF 保护 | 双提交 Cookie 模式,auth/payment/profile 必检 | -### 14. 核心 API 测试通过 +### 14. PC 工作台 UX 大幅重构 — 合并工作区 + CommandK 命令面板 ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **侧边栏精简** | 从 11 项合并为 5 项(首页/客户/业务/翻译/更多),减少 4 层级为 5 个清晰入口 | +| **CommandK 命令面板** | `user-frontend/src/components/CommandK.vue` — 全局 Ctrl+K 调出,快速搜索/导航/操作 | +| **工作区合并** | 客户/挖掘/跟进 → `WorkspaceCustomer.vue`;翻译/产品/报价/营销 → `WorkspaceBiz.vue` | +| **仪表盘简化** | `NewHome.vue` 精简为数据看板,去掉冗余入口 | +| **旧路由保留** | 旧页面可通过隐藏路由访问,保证兼容性 | + +### 15. uni-app 移动端 4Tab 合并重构 ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **Tab Bar 精简** | 从 5 项(首页/客户/营销/报价/我的)改为 4 项(首页/客户/业务/我的) | +| **客户工作台** | `workspace-customer.vue` — 3 个内联标签(客户列表/挖掘新客/智能跟进) | +| **业务工作台** | `workspace-biz.vue` — 4 个内联标签(翻译/产品库/报价单/营销素材) | +| **个人中心更新** | `profile.vue` — 通知中心/数据分析/团队/升级会员/联系客服 | +| **pages.json** | 标签栏配置同步更新,新增 workspace 页面注册 | + +### 16. 定价模型重构 + 升级弹窗 + 生态 UI ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **定价页重构** | `Upgrade.vue` 重新设计,新增 Yearly 套餐卡片 + 功能对比表 | +| **升级弹窗** | `UpgradeModal.vue` — 全局组件,任何页面可直接调起 | +| **生态入口** | `WorkspaceLanding.vue` — 工作台首页展示套餐状态 + 升级入口 | +| **路由整合** | 新增 `/workspace/upgrade` 路由,侧边栏可直接访问 | + +### 17. 产品策略文档 + Agent 技能 + Chrome 浏览器扩展 ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **产品策略文档** | `docs/PRODUCT_STRATEGY.md` — 319 行完整产品路线图(市场分析/定位/功能规划/定价策略/增长路线) | +| **Agent 技能定义** | 3 个 `.opencode/skills/` 文件 — `customer-discovery.md` / `marketing-content.md` / `translate-reply.md` | +| **Chrome 扩展** | `browser-extension/` — 完整 Chrome 插件,支持 LinkedIn/Amazon/AliExpress 页面集成 | +| **浏览器扩展功能** | popup 面板调用 API 翻译/提取客户信息、网页右键菜单、自动填写报价单 | + +### 18. 管理后台 AI 路由增强 ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **新增路由标签** | agent (数字员工)、followup (智能跟进)、outreach (开发信)、competitor (竞品分析) | +| **一行代码改动** | `admin-frontend/src/views/Config.vue` 更新 `ai_routing` 字段标签 | + +### 19. 用户工作台 i18n 导航键更新 ✅ [NEW] + +| 功能 | 说明 | +|------|------| +| **中文 locale** | `zh-CN.json` — 新增 home/customers/biz/agent 导航键 | +| **英文 locale** | `en.json` — 同步新增对应导航键 | +| **双语言适配** | 确保重构后的侧边栏/面包屑/页面标题完整支持中英文切换 | + +### 20. 后端持续优化 ✅ [NEW] + +| 序号 | 文件 | 问题描述 | 状态 | +|------|------|----------|------| +| 16 | `customer_health.py` | 健康分计算逻辑优化,增加活跃度权重 | ✅ 已修复 | +| 17 | `corpus_trainer.py` | 语料库训练流程修复,避免空数据处理 | ✅ 已修复 | +| 18 | `middleware.py` | 中间件性能优化,减少请求路径匹配耗时 | ✅ 已修复 | +| 19 | `conftest.py` | 测试基础设施增强,新增 fixture 复用 | ✅ 已修复 | + +### 21. 核心 API 测试通过 | 功能 | 接口 | 状态 | |------|------|------| @@ -222,6 +284,39 @@ --- +### 22. 收费方式调整 + 功能审计补全 + SEO/营销落地页 + 部署优化 ✅ [NEW] + +> **方向调整(2026-07-11)**:停止以「按月订阅」为主推的 SaaS 收费模型,改为合规的「免费试用 / 私有化部署 / 买断源码」三档方案。 +> 合规依据:仅持 ICP 备案即可销售「免费试用 + 私有化部署(年付授权)+ 买断源码(一次性软件/服务合同)」;若上线「托管付费订阅」需另行办理 ICP 经营许可证。 + +| 模块 | 文件 | 说明 | +|------|------|------| +| **定价页重构** | `user-frontend/src/views/Upgrade.vue` + `UpgradeModal.vue`、`uni-app/src/pages/upgrade/upgrade.vue` | 三档方案:免费试用 ¥0 / 私有化部署 ¥39,800 年 / 买断源码 ¥98,000 一次性;价格为可配置展示值 | +| **企业线索后端** | `backend/app/api/v1/leads.py` + `models/enterprise_lead.py` + `alembic/versions/add_enterprise_leads.py` | 新增 `POST /api/v1/leads`(免登录),`EnterpriseLead` 模型 + `enterprise_leads` 表;CSRF 对 `/api/v1/leads` 放行 | +| **线索测试** | `backend/tests/test_leads_api.py` | 3 个用例全部通过 | +| **功能审计补全** | `user-frontend/src/router/index.js`、`UserLayout.vue`、`admin-frontend/src/api/index.js`、`admin-frontend/src/views/Users.vue` | 修复 Agent 路由未接入工作台;修复后台用户编辑调用错误端点(`PATCH /users/{id}/tier`、`POST .../toggle-active`、`PATCH .../role`、`/admin/usage-stats`) | +| **浏览器扩展补全** | `browser-extension/api/client.js`、`popup/popup.js`、`popup/index.html` | 新增「提取客户信息」(`extractInfo()`)+ 「客户」Tab + 升级链接指向 `/workspace/upgrade` | +| **后端测试** | `backend` pytest | 158 用例 + 3 leads 用例全部通过,无失败 | +| **SEO 营销落地页** | `landing/index.html`、`landing/robots.txt`、`landing/sitemap.xml` | 语义化可抓取 HTML + JSON-LD(`SoftwareApplication` + `FAQPage`)+ OG/Twitter + 规范化链接 + 内链到 `/app/`、`/workspace/`、定价;`robots.txt`/`sitemap.xml` 置于站点根 | +| **前端 SEO 增强** | `uni-app/index.html` | 修复损坏的 `og:image`/`twitter:image`(指向 `/app/static/images/yzr/yuzhiran.jpg`),更新描述为新三档定价 | +| **部署配置** | `deploy/frontend/nginx.conf` | 四路布局:`/` → 营销落地页(根)、`/app/` → uni-app H5、`/workspace/` → 用户工作台、`/admin/` → 管理后台、`/api/` → 后端 127.0.0.1:8000;各 SPA 带 `try_files ... /index.html` fallback | + +**部署目录结构(目标)**: +``` +/www/wwwroot/trade.yuzhiran.com/ +├── index.html ← landing/ 营销落地页(SEO 主入口) +├── robots.txt ← landing/robots.txt +├── sitemap.xml ← landing/sitemap.xml +├── app/ ← uni-app 构建产物 (base: /app/) +├── workspace/ ← user-frontend 构建产物 (base: /workspace/) +├── admin/ ← admin-frontend 构建产物 (base: /admin/) +└── (后端由 systemd/uvicorn 运行,经 /api/ 代理) +``` + +**注意**:本环境无服务器 SSH 凭据,无法实际推送部署;上述产物与 `nginx.conf` 为部署就绪状态,需在目标服务器执行构建 + 拷贝 + `alembic upgrade head` + 重载 nginx。 + +--- + ## 三、待办事项 ### 低优先级 @@ -369,16 +464,23 @@ trade.yuzhiran.com/ ### 8.3 部署流程 ```bash -# 前端构建 & 部署 +# 1. 营销落地页(SEO 主入口) +cp landing/index.html /www/wwwroot/trade.yuzhiran.com/index.html +cp landing/robots.txt landing/sitemap.xml /www/wwwroot/trade.yuzhiran.com/ + +# 2. 三端 SPA 构建 & 部署 +cd uni-app && npm run build:h5 && cp -r dist/build/h5/* /www/wwwroot/trade.yuzhiran.com/app/ cd user-frontend && npm run build && cp -r dist/* /www/wwwroot/trade.yuzhiran.com/workspace/ cd admin-frontend && npm run build && cp -r dist/* /www/wwwroot/trade.yuzhiran.com/admin/ -# 后端重启 (systemd) +# 3. 后端:迁移 + 重启 (systemd) +cd backend && source venv/bin/activate && alembic upgrade head sudo systemctl restart ftrade-backend.service - -# 查看启动日志 sudo journalctl -u ftrade-backend.service -n 20 +# 4. Nginx:套用 deploy/frontend/nginx.conf 的 4 路布局后重载 +sudo nginx -t && sudo nginx -s reload + # 本地开发启动 cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8000 ``` @@ -389,6 +491,7 @@ cd backend && source venv/bin/activate && uvicorn app.main:app --reload --port 8 | 日期 | 变更内容 | |------|----------| +| 2026-07-11 | **收费方式调整**: 免费试用/私有化部署/买断源码三档;功能审计补全;SEO 营销落地页 + nginx 四路布局部署优化 | | 2026-06-16 | **AI 数字员工**: AgentOrchestrator 编排服务 + AgentPipeline 模型 + Agent API + 前端仪表盘 | | 2026-06-02 | 生产环境部署 + AI 路由 DB 驱动 + 翻译配额扩展至 LLM + ECS RAM 角色认证 + 删除 OpencodeGo/Spark | | 2026-05-29 | 安全加固 (T-005): 限流/CSRF/CORS + AI 提供商 DB 管理 + 客户挖掘联系人提取 | diff --git a/README.md b/README.md index c63b04a..6aeee4d 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,19 @@ TradeMate 提供三种使用方式,共享同一后端和账号体系: | 🧩 **Chrome 浏览器插件** | 划词翻译、快捷客户搜索、营销生成 | 见 `browser-extension/` [安装指南](browser-extension/INSTALL.html) | | 🤖 **AI 技能包** | SKILL.md 技能包,用于 Cursor/Claude Code/OpenCode | `.opencode/skills/` | -> 三者独立运营、互相补充。订阅一个入口,全平台可用。 +> 三者独立运营、互相补充,共享同一后端和账号体系。 + +## 💰 收费方式 + +采用合规的「软件 + 服务」销售模式,不主推托管订阅: + +| 方案 | 价格 | 说明 | +|------|------|------| +| 🆓 **免费试用** | ¥0 | 注册即享核心功能体验 | +| 🏢 **私有化部署** | ¥39,800 / 年 | 年付授权,独立部署到客户自有服务器 | +| 💎 **买断源码** | ¥98,000 / 一次性 | 一次性买断完整前后端源码,可二次开发 | + +> 企业线索(私有化/买断意向)通过 `POST /api/v1/leads` 提交至 `enterprise_leads` 表,由后台跟进。旧版按月订阅后端逻辑保留但前端不再主推。 --- @@ -153,12 +165,12 @@ npm run dev | `SECRET_KEY` | JWT 密钥 | `change-me-to-a-secure-key` | | `DATABASE_URL` | PostgreSQL 连接串 | `postgresql+asyncpg://user:pass@host:5432/db` | | `REDIS_URL` | Redis 连接串 | `redis://localhost:6379/0` | -| `OPENAI_API_KEY` | OpenAI API Key | `sk-...` | -| `SENSNOVA_API_KEY` | 星火大模型 API Key | `...` | -| `DEEPL_API_KEY` | DeepL API Key | `...` | +| `SENSENOVA_API_KEY` | 商汤/星火大模型 API Key | `...` | +| `NVIDIA_API_KEY` | NVIDIA 大模型 API Key | `...` | +| `OPENAI_API_KEY` | OpenAI 兼容 API Key(可选) | `sk-...` | | `WECHAT_APP_ID` | 微信小程序 AppID | `wx...` | | `WECHAT_APP_SECRET` | 微信小程序 AppSecret | `...` | -| `FRONTEND_URL` | 前端地址 | `http://localhost:5173` | +| `FRONTEND_URL` | 前端地址(逗号分隔多端) | `http://localhost:5173,http://localhost:5174` | ### 数据库初始化 @@ -217,7 +229,7 @@ alembic upgrade head |------|------| | 后端 | FastAPI + SQLAlchemy 1.4 async + asyncpg | | 数据库 | PostgreSQL 15 + pgvector + Redis 7 | -| AI 提供商 | Sensenova (星火), OpenAI, DeepL | +| AI 提供商 | Sensenova (商汤/星火), NVIDIA, 阿里机器翻译 (alibaba-mt) | | 前端 | Vue 3 + uni-app + Element Plus | | 任务队列 | Celery + Redis | | 容器化 | Docker + Docker Compose | @@ -243,6 +255,9 @@ trade-assistant/ ├── uni-app/ # 移动端 H5 + 小程序 ├── admin-frontend/ # PC 管理后台 ├── user-frontend/ # 用户工作台 +├── browser-extension/ # Chrome 浏览器插件 +├── landing/ # SEO 营销落地页(根路径 /)+ robots.txt + sitemap.xml +├── deploy/ # 部署配置(含 frontend/nginx.conf 四路布局) ├── nginx/ # Nginx 配置 ├── docs/ # 项目文档 │ ├── API_DESIGN.md @@ -255,6 +270,37 @@ trade-assistant/ --- +## 🌐 生产部署 + +站点 `trade.yuzhiran.com` 采用四路 Nginx 布局,由 `deploy/frontend/nginx.conf` 定义: + +| 路径 | 内容 | 来源 | +|------|------|------| +| `/` | SEO 营销落地页(根) | `landing/index.html` + `robots.txt` + `sitemap.xml` | +| `/app/` | 移动端 H5(uni-app,base `/app/`) | `uni-app` 构建产物 | +| `/workspace/` | 用户工作台(user-frontend,base `/workspace/`) | `user-frontend` 构建产物 | +| `/admin/` | 管理后台(admin-frontend,base `/admin/`) | `admin-frontend` 构建产物 | +| `/api/` | 后端 API 反向代理 | `127.0.0.1:8000`(systemd/uvicorn 运行) | + +```bash +# 落地页(SEO 主入口) +cp landing/index.html landing/robots.txt landing/sitemap.xml /www/wwwroot/trade.yuzhiran.com/ + +# 三端 SPA +cd uni-app && npm run build:h5 && cp -r dist/build/h5/* /www/wwwroot/trade.yuzhiran.com/app/ +cd user-frontend && npm run build && cp -r dist/* /www/wwwroot/trade.yuzhiran.com/workspace/ +cd admin-frontend && npm run build && cp -r dist/* /www/wwwroot/trade.yuzhiran.com/admin/ + +# 后端迁移 + 重启 +cd backend && source venv/bin/activate && alembic upgrade head +sudo systemctl restart ftrade-backend.service + +# 重载 Nginx(套用 deploy/frontend/nginx.conf 的四路布局) +sudo nginx -t && sudo nginx -s reload +``` + +--- + ## 🧪 测试 ```bash diff --git a/admin-frontend/src/api/index.js b/admin-frontend/src/api/index.js index 4c3ee60..6aaffb3 100644 --- a/admin-frontend/src/api/index.js +++ b/admin-frontend/src/api/index.js @@ -29,8 +29,11 @@ export function searchUsers(query) { return http.post('/admin/users/search', { q export function listUsers(page = 1, size = 20) { return http.get('/admin/users', { params: { page, size } }) } export function getUserDetail(id) { return http.get(`/admin/users/${id}`) } export function updateUser(id, data) { return http.put(`/admin/users/${id}`, data) } +export function updateUserTier(id, tier) { return http.patch(`/admin/users/${id}/tier`, { tier }) } +export function toggleUserActive(id) { return http.post(`/admin/users/${id}/toggle-active`) } +export function updateUserRole(id, role) { return http.patch(`/admin/users/${id}/role`, { role }) } -export function getUsageStats() { return http.get('/admin/stats/usage') } +export function getUsageStats() { return http.get('/admin/usage-stats') } export function listLogs(params) { return http.get('/admin/logs', { params }) } diff --git a/admin-frontend/src/views/Users.vue b/admin-frontend/src/views/Users.vue index 0207b2c..75e766b 100644 --- a/admin-frontend/src/views/Users.vue +++ b/admin-frontend/src/views/Users.vue @@ -65,7 +65,7 @@ + + + + + + + + + +
+
+
+

让 AI 替你跑完外贸全流程
翻译 · 找客户 · 写营销 · 做报价

+

TradeMate 外贸小助手,把重复活交给 AI。一个人也能像一支外贸团队一样高效获客、转化与跟进。

+ +
+ 🌐 中英等多语翻译 + 🤖 AI 数字员工自动开发客户 + 🔒 支持私有化部署·数据私有 + 🧩 网页 / H5 / 小程序 / 插件 +
+
+
+ +
+
+

做外贸,这些事最耗你时间

不是你不够努力,是工具没帮你把重复活自动化

+
+

翻译来回复制粘贴

询盘、邮件、资料中英切换,每天大量时间耗在基础翻译上。

+

找不到靠谱客户

Google 翻页、手动筛选,获客效率低、线索质量不稳。

+

营销文案写不动

开发信、社媒文案反复憋,风格不统一、回复率低。

+

报价单手工拼

从询盘到报价单复制粘贴,易错、慢、难追踪。

+

客户跟进靠记忆

沉默客户没提醒,跟进断层,到手的单也容易飞。

+

团队协作用表格

客户表满天飞,数据分散、权限混乱、难沉淀。

+
+
+
+ +
+
+

一个工作台,覆盖外贸全流程

从沟通到成交,AI 在每一步帮你提速

+
+
🌐

智能翻译 / 回复

中英等多语互译,按询盘一键生成多风格专业回复。

+
🔍

AI 客户挖掘

基于产品与市场的智能搜索,自动提取邮箱/电话/WhatsApp。

+
✍️

营销文案生成

开发信、社媒、关键词、竞品分析,多风格一键产出。

+
🧾

报价单自动生成

从询盘自动生成报价单,多币种、状态可追踪。

+
💡

客户健康度

沉默客户提醒、互动分析,帮你及时跟进不漏单。

+
🤖

AI 数字员工

输入产品+市场,自动 搜索→分析→触达→沉淀高匹配客户。

+
+
+
+ +
+
+

四步上手,当天见效

无需培训,打开就能用

+
+

注册 / 游客体验

手机号或游客模式,免费体验核心功能。

+

导入客户与产品

录入产品或客户,AI 即刻理解你的业务上下文。

+

用 AI 做日常

翻译、写营销、生成报价、让数字员工去开发客户。

+

跟进与转化

健康度提醒 + 智能跟进,把线索变成订单。

+
+
+
+ +
+
+

三种方式,按需选择

公有云免费起步,企业可私有化或买断,数据自主可控

+
+
+
免费试用
+
¥0
+
    +
  • 30 积分(一次性)
  • +
  • 每日 1000 字免费翻译
  • +
  • 翻译 / 回复 / 客户发现 / 营销
  • +
  • 网页端 · 插件 · 小程序通用
  • +
+ 免费使用 +
+ +
+
买断源码
+
¥98,000/一次性
+
    +
  • 完整前后端源码
  • +
  • 可自由二次开发
  • +
  • 永久授权 · 无后续费用
  • +
  • 文档与社区支持
  • +
+ 咨询买断 +
+
+
+
+ +
+
+

为什么选 TradeMate

+
+ + + + + + + + + +
能力TradeMate纯人工 / 通用工具
翻译 + 回复AI 贴合外贸语境,一键多风格复制粘贴、风格不一
客户开发AI 数字员工自动搜索→触达→沉淀手动翻页、效率低
营销文案开发信/社媒/关键词批量生成逐条手写、耗时
数据归属支持私有化部署,数据私有依赖第三方、不可控
多端协同网页/H5/小程序/插件互通工具割裂、难协同
+
+
+
+ +
+
+

常见问题

+
+
TradeMate 适合哪些人使用?

主要面向外贸 SOHO、小微外贸团队与业务员,帮助完成翻译、找客户、写营销、做报价等日常工作。

+
免费试用包含什么?

免费版提供 30 积分与每日 1000 字免费翻译,可完整体验核心功能,零门槛上手。

+
私有化部署和买断源码有什么区别?

私有化部署是按年付费的授权,系统独立部署在你的服务器、数据私有;买断源码是一次付费获得完整前后端源码,可自由二次开发、永久授权。

+
我的客户数据安全吗?

支持私有化部署,数据完全保存在你自己的服务器;公有云版本也通过 JWT 鉴权与最小化权限保护数据。

+
支持哪些平台?

提供网页工作台、移动端 H5、微信小程序与 Chrome 浏览器插件,数据账号互通。

+
+
+
+ +
+
+
+

现在就开始,让 AI 帮你跑外贸

+

免费试用零门槛,企业可私有化部署或买断源码,数据自主、合规可控。

+ +
+
+
+
+ + + + + diff --git a/landing/robots.txt b/landing/robots.txt new file mode 100644 index 0000000..128c994 --- /dev/null +++ b/landing/robots.txt @@ -0,0 +1,22 @@ +User-agent: * +Allow: / +Allow: /app/ +Allow: /workspace/ +Disallow: /admin/ +Disallow: /api/ + +User-agent: Googlebot +Allow: / +Allow: /app/ +Allow: /workspace/ +Disallow: /admin/ +Disallow: /api/ + +User-agent: Baiduspider +Allow: / +Allow: /app/ +Allow: /workspace/ +Disallow: /admin/ +Disallow: /api/ + +Sitemap: https://trade.yuzhiran.com/sitemap.xml diff --git a/landing/sitemap.xml b/landing/sitemap.xml new file mode 100644 index 0000000..c6428e8 --- /dev/null +++ b/landing/sitemap.xml @@ -0,0 +1,34 @@ + + + + https://trade.yuzhiran.com/ + 2026-07-11 + weekly + 1.0 + + + https://trade.yuzhiran.com/app/ + 2026-07-11 + daily + 0.9 + + + https://trade.yuzhiran.com/workspace/ + 2026-07-11 + daily + 0.8 + + + https://trade.yuzhiran.com/app/pages/agreement/privacy + 2026-07-11 + monthly + 0.5 + + + https://trade.yuzhiran.com/app/pages/agreement/terms + 2026-07-11 + monthly + 0.5 + + diff --git a/opencode-search-mcp/.gitignore b/opencode-search-mcp/.gitignore deleted file mode 100644 index b947077..0000000 --- a/opencode-search-mcp/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ diff --git a/opencode-search-mcp/package.json b/opencode-search-mcp/package.json deleted file mode 100644 index 5ee67c3..0000000 --- a/opencode-search-mcp/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "opencode-search-mcp", - "version": "1.0.0", - "description": "MCP server wrapping opencode search capabilities", - "type": "module", - "main": "dist/index.js", - "scripts": { - "build": "tsc", - "start": "node dist/index.js" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.0", - "@opencode-ai/sdk": "^1.14.41", - "zod": "^3.23.8" - }, - "devDependencies": { - "@types/node": "^22.0.0", - "typescript": "^5.7.0" - } -} \ No newline at end of file diff --git a/opencode-search-mcp/src/index.ts b/opencode-search-mcp/src/index.ts deleted file mode 100644 index 63c77f2..0000000 --- a/opencode-search-mcp/src/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; -import { createOpencodeClient } from "@opencode-ai/sdk"; -import { z } from "zod"; - -const server = new McpServer({ - name: "opencode-search", - version: "1.0.0", -}); - -const client = createOpencodeClient({ - baseUrl: process.env.OPENCODE_URL || "http://127.0.0.1:4096", -}); - -server.registerTool( - "search_files", - { - title: "Search Files", - description: "Search for files and directories by name in the opencode workspace", - inputSchema: z.object({ - query: z.string(), - directory: z.string().optional(), - limit: z.number().min(1).max(200).optional(), - }), - }, - async ({ query, directory, limit }) => { - try { - const results = await (client.find.files as any)({ - query: { - query, - directory: directory || undefined, - limit: limit || 50, - }, - }); - return { - content: [{ type: "text", text: JSON.stringify(results, null, 2) }], - }; - } catch (e) { - return { - content: [{ type: "text", text: `Error: ${(e as Error).message}` }], - isError: true, - }; - } - } -); - -server.registerTool( - "search_text", - { - title: "Search Text", - description: "Search for text content within files using regex patterns", - inputSchema: z.object({ - pattern: z.string(), - directory: z.string().optional(), - }), - }, - async ({ pattern, directory }) => { - try { - const results = await (client.find.text as any)({ - query: { - pattern, - directory: directory || undefined, - }, - }); - return { - content: [{ type: "text", text: JSON.stringify(results, null, 2) }], - }; - } catch (e) { - return { - content: [{ type: "text", text: `Error: ${(e as Error).message}` }], - isError: true, - }; - } - } -); - -server.registerTool( - "search_symbols", - { - title: "Search Symbols", - description: "Search for code symbols in the workspace", - inputSchema: z.object({ - pattern: z.string(), - directory: z.string().optional(), - limit: z.number().min(1).max(200).optional(), - }), - }, - async ({ pattern, directory, limit }) => { - try { - const results = await (client.find.symbols as any)({ - query: { - pattern, - directory: directory || undefined, - limit: limit || 50, - }, - }); - return { - content: [{ type: "text", text: JSON.stringify(results, null, 2) }], - }; - } catch (e) { - return { - content: [{ type: "text", text: `Error: ${(e as Error).message}` }], - isError: true, - }; - } - } -); - -server.registerTool( - "get_workspace_path", - { - title: "Get Workspace Path", - description: "Get the current opencode workspace path info", - inputSchema: z.object({}), - }, - async () => { - try { - const path = await client.path.get(); - return { - content: [{ type: "text", text: JSON.stringify(path, null, 2) }], - }; - } catch (e) { - return { - content: [{ type: "text", text: `Error: ${(e as Error).message}` }], - isError: true, - }; - } - } -); - -async function main() { - const transport = new StdioServerTransport(); - await server.connect(transport); -} - -main().catch((e) => { - console.error("MCP server error:", e); - process.exit(1); -}); \ No newline at end of file diff --git a/opencode-search-mcp/tsconfig.json b/opencode-search-mcp/tsconfig.json deleted file mode 100644 index 784ac0e..0000000 --- a/opencode-search-mcp/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "outDir": "dist", - "rootDir": "src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true - }, - "include": ["src/**/*"] -} \ No newline at end of file diff --git a/tests/package-lock.json b/tests/package-lock.json index ffb9d63..0f49518 100644 --- a/tests/package-lock.json +++ b/tests/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "trademate-tests", "dependencies": { - "playwright": "^1.60.0" + "playwright": "^1.61.1" } }, "node_modules/fsevents": { @@ -24,12 +24,12 @@ } }, "node_modules/playwright": { - "version": "1.60.0", - "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.60.0.tgz", - "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", + "version": "1.61.1", + "resolved": "https://registry.npmmirror.com/playwright/-/playwright-1.61.1.tgz", + "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.60.0" + "playwright-core": "1.61.1" }, "bin": { "playwright": "cli.js" @@ -42,9 +42,9 @@ } }, "node_modules/playwright-core": { - "version": "1.60.0", - "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.60.0.tgz", - "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", + "version": "1.61.1", + "resolved": "https://registry.npmmirror.com/playwright-core/-/playwright-core-1.61.1.tgz", + "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" diff --git a/tests/package.json b/tests/package.json index 23e4165..02bdb04 100644 --- a/tests/package.json +++ b/tests/package.json @@ -5,6 +5,6 @@ "test": "node test_all.mjs" }, "dependencies": { - "playwright": "^1.60.0" + "playwright": "^1.61.1" } } diff --git a/uni-app/index.html b/uni-app/index.html index bc1c9a8..1eeee29 100644 --- a/uni-app/index.html +++ b/uni-app/index.html @@ -3,7 +3,7 @@ - + @@ -18,11 +18,11 @@ - + - - + + @@ -39,12 +39,12 @@ "url": "https://trade.yuzhiran.com/app/", "applicationCategory": "BusinessApplication", "operatingSystem": "Web, iOS, Android", - "description": "AI 驱动的外贸智能工作台,专为外贸 SOHO 和小团队打造", - "offers": { - "@type": "Offer", - "price": "0", - "priceCurrency": "CNY" - }, + "description": "AI 驱动的外贸智能工作台,专为外贸 SOHO 和小团队打造,支持免费试用、私有化部署与买断源码", + "offers": [ + { "@type": "Offer", "name": "免费试用", "price": "0", "priceCurrency": "CNY" }, + { "@type": "Offer", "name": "私有化部署", "price": "39800", "priceCurrency": "CNY", "description": "年付授权,独立部署到客户自有服务器" }, + { "@type": "Offer", "name": "买断源码", "price": "98000", "priceCurrency": "CNY", "description": "一次性买断完整前后端源码,可二次开发" } + ], "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.8", diff --git a/uni-app/src/pages/upgrade/upgrade.vue b/uni-app/src/pages/upgrade/upgrade.vue index 86d2d51..2ae5fd2 100644 --- a/uni-app/src/pages/upgrade/upgrade.vue +++ b/uni-app/src/pages/upgrade/upgrade.vue @@ -1,7 +1,7 @@