Research Platform — EUJ 端到端用户旅程

DAG Workflow Campaign System | 更新时间: 2026-02-24

模块定位:Research Platform 是一个基于 DAG(有向无环图)的营销自动化和 A/B 测试平台。用户通过可视化画布设计 Campaign 工作流,配置受众定位、多渠道触达(SMS/Email/Voice)、事件监听和转化追踪。
TOUCHES (Pages — 8): admin/marketing/research/page.tsx (列表 + 发送历史 2 tabs), admin/marketing/research/new/page.tsx (旧创建表单), admin/marketing/research/[id]/page.tsx (仪表板详情), admin/marketing/research/[id]/workflow/page.tsx (DAG 编辑器), admin/marketing/research/[id]/participants/page.tsx (参与者列表), admin/marketing/research/[id]/outreach/page.tsx (触达历史), admin/marketing/research/[id]/analytics/page.tsx (分析面板), admin/marketing/research/new/workflow → id=new 模式 (新创建入口)

TOUCHES (Components — 20+): WorkflowCanvas.tsx, ResearchNode.tsx, NodePalette.tsx, ConfigPanel.tsx, CustomerSelectorForm.tsx, SplitGroupForm.tsx, AiVoiceForm.tsx, AiSmsForm.tsx, AiEmailForm.tsx, ManualTaskForm.tsx, EventGateForm.tsx, ConditionCheckForm.tsx, WaitDelayForm.tsx, RecordConversionForm.tsx, CampaignAnalytics.tsx, ConversionFunnel.tsx, GroupComparison.tsx, StatisticalSignificance.tsx, ParticipantTable.tsx, SendHistoryTable.tsx

TOUCHES (Hooks — 3): useResearchApi.ts, useOutreachApi.ts, useAudienceApi.ts

TOUCHES (Backend): backend/api/research.js (~2400 行), backend/services/research/ (12 个 service 模块), backend/services/research/dagExecutor.js (DAG 执行引擎)

PERMISSION: marketing:view (读) / marketing:manage (写)

1. EUJ 健康度评分卡

功能完整性
85%
导航连贯性
40%
操作流畅性
55%
状态可见性
75%
代码整洁度
50%

2. 全局导航入口

flowchart LR
  A[侧边栏 Marketing] --> B[Marketing 主页]
  B --> C["Research Platform 卡片"]
  C --> D["/research 列表页"]

  style A fill:#334155,stroke:#00d4ff,color:#fff
  style B fill:#334155,stroke:#00d4ff,color:#fff
  style C fill:#4c1d95,stroke:#a78bfa,color:#fff
  style D fill:#4c1d95,stroke:#a78bfa,color:#fff
入口权限路径状态
侧边栏 → Marketing marketing:view /admin/marketing OK
Marketing 主页 → Research 卡片 marketing:view /admin/marketing/research OK

3. 端到端用户旅程

flowchart TD
  L["列表页 /research"] -->|"新建 Campaign"| W1["Workflow 编辑器 (new)"]
  L -->|"点击项目名"| W2["Workflow 编辑器 (existing)"]

  W1 -->|"保存"| W2
  W2 -->|"??? 缺少启动入口"| X["需返回列表/详情页"]

  L -->|"下拉菜单 Start"| RUN["执行中"]
  X -->|"详情页 Start"| RUN

  RUN -->|"查看"| MON["监控子页面"]
  MON --> P["参与者列表"]
  MON --> O["触达历史"]
  MON --> AN["分析面板"]

  RUN -->|"暂停/完成"| DONE["已完成"]
  DONE --> AN

  style W1 fill:#4c1d95,stroke:#a78bfa,color:#fff
  style W2 fill:#4c1d95,stroke:#a78bfa,color:#fff
  style RUN fill:#166534,stroke:#4ade80,color:#fff
  style DONE fill:#1e3a5f,stroke:#60a5fa,color:#fff
  style X fill:#7f1d1d,stroke:#ef4444,color:#fff

3.1 Step 1 — 创建 Campaign

两套创建入口并存: 正常用户路径不会触及旧页面,但 URL 直接可访问。
1
用户点击"新建 Campaign"
research/page.tsx:230 → href="/research/new/workflow"
进入 DAG 编辑器 new 模式,左侧节点面板、中央空白画布、右侧配置面板
2
在顶栏输入名称 + 选择场景
research/[id]/workflow/page.tsx:268-287
内联 input + select,无需独立表单页
3
点击 Save 保存
workflow/page.tsx:134-209 → POST /api/research
先执行 DAG 验证 (validateWorkflowGraph),错误阻止保存,警告提示但允许保存。创建成功后 URL 切换为 /research/:id/workflow
层级文件状态
前端页面workflow/page.tsx (new 模式)OK
React HookuseCreateCampaign()OK
APIPOST /api/researchOK
ServicecampaignService.createCampaign()OK
DBINSERT INTO research_campaignsOK

3.2 Step 2 — 设计 Workflow (DAG)

4
从节点面板拖拽节点到画布
NodePalette.tsx → WorkflowCanvas.tsx (ReactFlow)
可用节点类型:Customer Selector, Split Group, AI SMS, AI Email, AI Voice, Manual Task, Event Gate, Condition Check, Wait/Delay, Record Conversion
5
连接节点 + 配置参数
ConfigPanel.tsx → ConfigForms/*.tsx
点击节点 → 右侧面板显示对应配置表单。每种节点类型有独立的 ConfigForm
6
保存 Workflow
workflow/page.tsx:185 → PUT /api/research/:id
workflow_graph (nodes + edges + viewport) 存入 research_campaigns.workflow_graph JSONB 列
层级文件状态
DAG 画布WorkflowCanvas.tsx (ReactFlow)OK
节点类型注册NODE_TYPE_REGISTRYOK
节点配置表单ConfigForms/*.tsx (10 种)OK
DAG 验证validateWorkflowGraph()OK
APIPUT /api/research/:idOK

3.3 Step 3 — 启动 Campaign

GAP: Workflow 编辑器缺少启动入口
用户在 Workflow 编辑器中完成 DAG 设计后,没有 Start 按钮。必须先导航回列表页或详情页才能启动。这是一个明显的 UX 断裂。
7
从 Workflow 页启动 Campaign
workflow/page.tsx — 无 Start 按钮
用户被迫:点击 "Back" → 回到列表页 → 找到项目 → 下拉菜单 → Start
或:手动修改 URL 为 /research/:id → 仪表板页面 → Start 按钮
启动入口所在页面状态
列表页下拉菜单 → Startresearch/page.tsx:341OK
详情仪表板页 → Startresearch/[id]/page.tsx:188OK
Workflow 编辑器 → Startworkflow/page.tsxMISSING
APIPOST /api/research/:id/startOK
执行引擎dagExecutor.startCampaign()OK

3.4 Step 4 — 监控执行

8
Workflow 画布实时指标
workflow/page.tsx:74 → useNodeMetrics(campaignId, isRunning)
运行态每 5s 轮询 GET /api/research/:id/node-metrics,DAG 节点上覆盖 metrics overlay(processed / success_rate / waiting)
9
详情仪表板 Quick Stats
research/[id]/page.tsx:253-284
5 张统计卡片:Total Participants / Reached / Responded / Converted / Revenue
10
触达历史
research/[id]/outreach/page.tsx
按渠道/状态筛选,展开行查看 OutreachTimeline,统计卡片显示发送/投递/打开/失败率
监控维度数据来源状态
DAG 节点实时指标GET /api/research/:id/node-metricsOK
Campaign 整体统计GET /api/research/:id/statsOK
触达历史日志useOutreachHistory(campaignId)OK
触达 CSV 导出outreach/page.tsx:381TODO

3.5 Step 5 — 查看分析

11
分析面板
research/[id]/analytics/page.tsx
CampaignAnalytics 组件:组别对比、转化漏斗、统计显著性检验。可导出 PDF/CSV 报告
分析功能组件/API状态
组别对比表GroupComparison.tsxOK
转化漏斗ConversionFunnel.tsx / GET .../conversions/funnelOK
统计显著性StatisticalSignificance.tsxOK
报告生成POST /api/research/:id/reports/generateOK
时间序列GET /api/research/:id/stats/timeseriesOK

3.6 Step 6 — 平台级发送历史

12
跨 Campaign 发送历史
research/page.tsx:421-442 (第二个 Tab)
列表页 "发送历史" Tab → SendHistoryTable 组件,跨所有 Campaign 的发送记录,支持筛选 + CSV 导出
功能Hook / API状态
发送日志列表useSendHistory() / GET /api/research/send-historyOK
统计汇总useSendHistoryStats()OK
CSV 导出useExportSendHistory()OK

4. 页面导航结构

flowchart TD
  LIST["/research 列表页
Tab: 项目列表 | 发送历史"] LIST -->|"创建"| NEW_WF["Workflow 编辑器 (new)"] LIST -->|"点击项目名"| EXIST_WF["Workflow 编辑器 (existing)"] subgraph "Campaign 子页面 (无统一导航栏)" DETAIL["/research/:id 仪表板
Tab: overview | groups | participants"] EXIST_WF["/research/:id/workflow
DAG 编辑器"] PART["/research/:id/participants
参与者列表"] OUT["/research/:id/outreach
触达历史"] ANA["/research/:id/analytics
分析面板"] end EXIST_WF -.->|"Back 按钮"| LIST DETAIL -.->|"Back"| LIST DETAIL -->|"participants tab 链接"| PART PART -.->|"Back"| DETAIL style LIST fill:#334155,stroke:#00d4ff,color:#fff style EXIST_WF fill:#4c1d95,stroke:#a78bfa,color:#fff style NEW_WF fill:#4c1d95,stroke:#a78bfa,color:#fff style DETAIL fill:#334155,stroke:#60a5fa,color:#fff style PART fill:#334155,stroke:#60a5fa,color:#fff style OUT fill:#334155,stroke:#60a5fa,color:#fff style ANA fill:#334155,stroke:#60a5fa,color:#fff
GAP: 子页面之间缺乏统一 Tab 导航
进入某个 Campaign 后,5 个子页面(Workflow / Detail / Participants / Outreach / Analytics)之间 没有横向 Tab 栏 进行快速切换。

5. 关键 GAP 汇总

#GAP 描述影响建议优先级
G1 缺少统一子导航栏
Campaign 子页面之间无横向 Tab 切换
用户在 Workflow/Detail/Outreach/Analytics 之间切换极其不便 P0
G2 Workflow 页缺少 Start 按钮
完成 DAG 设计后无法直接启动
核心操作链路断裂,强制用户跳转 P0
G3 两套创建流程并存
/research/new(旧表单)与 /research/new/workflow(新入口)同时存在
代码冗余,旧页面可直接访问但不在正常流程中 P1
G4 Outreach 页 CSV 导出是 TODO
按钮存在但点击只弹 alert
功能承诺但未交付 P1
G5 详情页 "Configure" 链接指向不存在的 /edit 页面
详情页:179 → /research/:id/edit
点击后 404 P0
G6 参与者分配无前端入口
POST /api/research/:id/allocate API 存在但前端无触发按钮
API 可用但用户无法操作 P1
G7 详情页硬编码 Channel 标签
CHANNEL_LABELS 对象未使用 i18n
违反 i18n 规范 P2

6. 理想 EUJ 流程(建议改进后)

flowchart TD
  LIST["列表页 /research"] -->|"新建"| WF_NEW["Workflow 编辑器 (new)"]
  LIST -->|"点击项目"| WF_EXIST["Workflow 编辑器 (existing)"]
  WF_NEW -->|"Save"| WF_EXIST

  subgraph "Campaign 统一子导航栏"
    direction LR
    TAB_WF["Workflow"]
    TAB_PART["Participants"]
    TAB_OUT["Outreach"]
    TAB_ANA["Analytics"]
    TAB_SET["Settings"]
  end

  WF_EXIST -->|"顶栏 Start 按钮"| RUNNING["执行中"]

  TAB_WF --- TAB_PART
  TAB_PART --- TAB_OUT
  TAB_OUT --- TAB_ANA
  TAB_ANA --- TAB_SET

  RUNNING --> TAB_WF
  RUNNING --> TAB_PART
  RUNNING --> TAB_OUT
  RUNNING --> TAB_ANA

  style LIST fill:#334155,stroke:#00d4ff,color:#fff
  style WF_NEW fill:#4c1d95,stroke:#a78bfa,color:#fff
  style WF_EXIST fill:#4c1d95,stroke:#a78bfa,color:#fff
  style RUNNING fill:#166534,stroke:#4ade80,color:#fff
  style TAB_WF fill:#1e3a5f,stroke:#60a5fa,color:#fff
  style TAB_PART fill:#1e3a5f,stroke:#60a5fa,color:#fff
  style TAB_OUT fill:#1e3a5f,stroke:#60a5fa,color:#fff
  style TAB_ANA fill:#1e3a5f,stroke:#60a5fa,color:#fff
  style TAB_SET fill:#1e3a5f,stroke:#60a5fa,color:#fff
改进方向:
  1. 添加 Campaign 级统一 Tab 导航栏,连接所有子页面
  2. 在 Workflow 编辑器顶栏增加 Start/Pause/Complete 按钮
  3. 移除旧创建表单 /research/new,统一用 Workflow 编辑器 new 模式
  4. 修复详情页 "Configure" 链接(指向 /edit → 应改为 /workflow)
  5. 在参与者页面增加 "Allocate" 按钮,或在 Workflow 中集成分配操作

7. 数据库表结构

erDiagram
  research_campaigns ||--o{ campaign_groups : "has"
  research_campaigns ||--o{ campaign_participants : "has"
  research_campaigns ||--o{ campaign_audience_criteria : "has"
  research_campaigns ||--o{ campaign_outreach_logs : "has"
  research_campaigns ||--o{ campaign_stats : "has"
  research_campaigns ||--o{ campaign_node_metrics : "has"
  research_campaigns ||--o{ campaign_event_listeners : "has"
  research_campaigns ||--o| campaign_delivery_config : "has"

  campaign_groups ||--o{ campaign_participants : "contains"
  campaign_participants ||--o{ campaign_outreach_logs : "sent to"
  campaign_participants ||--o{ campaign_conversions : "converted"

  research_campaigns {
    uuid id PK
    text name
    text scenario
    text status
    jsonb workflow_graph
  }
  campaign_groups {
    uuid id PK
    uuid campaign_id FK
    text channel
    int allocation_percent
  }
  campaign_participants {
    uuid id PK
    uuid guest_id FK
    uuid group_id FK
    text status
  }
  campaign_outreach_logs {
    uuid id PK
    text channel
    text status
    text rendered_content
  }
  campaign_conversions {
    uuid id PK
    uuid participant_id FK
    text conversion_type
    numeric revenue
  }

8. API 端点清单

方法端点用途前端调用
GET/api/research列表(分页+筛选)useCampaigns
POST/api/research创建 CampaignuseCreateCampaign
GET/api/research/:id详情useCampaign
PUT/api/research/:id更新(含 workflow_graph)useUpdateCampaign
DELETE/api/research/:id删除useDeleteCampaign
POST/api/research/:id/duplicate克隆useDuplicateCampaign
POST/api/research/:id/start启动 DAGuseStartCampaign
POST/api/research/:id/pause暂停usePauseCampaign
POST/api/research/:id/complete标记完成useCompleteCampaign
POST/api/research/:id/cancel取消useCancelCampaign
GET/api/research/:id/groups分组列表useCampaignGroups
GET/api/research/:id/participants参与者(分页)useParticipants
POST/api/research/:id/allocate分配参与者无前端入口
GET/api/research/:id/node-metrics节点实时指标useNodeMetrics
GET/api/research/:id/statsCampaign 统计useCampaignStats
GET/api/research/:id/conversions/funnel转化漏斗useConversionFunnel
POST/api/research/:id/reports/generate生成报告useGenerateReport
GET/api/research/send-history跨项目发送历史useSendHistory
GET/api/research/send-history/export发送历史 CSVuseExportSendHistory