Files
zclaw_openfang/plans/zippy-brewing-zebra.md
iven d0c6319fc1
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
feat: 添加ESLint和Prettier配置并优化代码结构
style: 格式化代码文件并修复样式问题

docs: 新增部署文档和系统要求文档

test: 更新测试截图和覆盖率报告

refactor: 重构SchedulerPanel加载状态逻辑

ci: 添加lint和format脚本到package.json

build: 更新依赖项并添加开发工具

chore: 添加验证报告和上线审查计划
2026-03-26 08:02:23 +08:00

11 KiB
Raw Blame History

Pipeline 行业分类展示功能实现计划

问题描述

当前 Pipeline 列表仅支持功能分类筛选(教育、营销、法律、生产力、研究),用户期望能够按行业分类(互联网、金融、医疗等)筛选 Pipeline。

用户需求

  • 保留现有功能分类筛选
  • 添加行业分类维度
  • 支持双维度筛选(功能 + 行业)

根因分析

当前架构

层级 文件 现状
Pipeline YAML pipelines/**/*.yaml metadata.category = 功能分类education、marketing、legal 等)
后端类型 types.rs:29-44 PipelineMetadata 只有 category 字段
后端命令 pipeline_commands.rs:41-62 PipelineInfo 只有 category 字段
前端类型 pipeline-client.ts:26-36 PipelineInfo 只有 category 字段
前端 UI PipelinesPanel.tsx:34-44 CATEGORY_CONFIG 定义 8 个功能分类

问题根因

Pipeline 元数据中缺少 industry(行业)字段,无法按行业分类筛选。


解决方案

整体架构

┌─────────────────────────────────────────────────────────────┐
│                      PipelinesPanel                          │
├─────────────────────────────────────────────────────────────┤
│  [搜索框]                                                     │
│  功能分类: [全部][教育][营销][法律][生产力][研究]              │  ← 现有
│  行业分类: [全部][互联网][金融][医疗][教育][制造业]...        │  ← 新增
├─────────────────────────────────────────────────────────────┤
│  Pipeline 卡片                                                │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ 📚 互动课堂生成器          [教育] [互联网]             │   │
│  │ 生成结构化大纲、互动场景...                            │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

实现步骤

步骤 1后端类型定义

文件crates/zclaw-pipeline/src/types.rs

PipelineMetadata 结构体中添加 industry 字段:

/// Pipeline metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PipelineMetadata {
    pub name: String,
    pub display_name: Option<String>,
    pub category: Option<String>,

    /// Industry classification (e.g., "internet", "finance", "healthcare")
    #[serde(default)]
    pub industry: Option<String>,  // ← 新增

    pub description: Option<String>,
    pub tags: Vec<String>,
    pub icon: Option<String>,
    pub author: Option<String>,
    pub version: String,
}

步骤 2后端命令更新

文件desktop/src-tauri/src/pipeline_commands.rs

更新 PipelineInfo 结构体:

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PipelineInfo {
    pub id: String,
    pub display_name: String,
    pub description: String,
    pub category: String,
    pub industry: String,  // ← 新增
    pub tags: Vec<String>,
    pub icon: String,
    pub version: String,
    pub author: String,
    pub inputs: Vec<PipelineInputInfo>,
}

更新 pipeline_to_info 函数:

fn pipeline_to_info(pipeline: &Pipeline) -> PipelineInfo {
    PipelineInfo {
        // ...
        industry: pipeline.metadata.industry.clone().unwrap_or_default(),
        // ...
    }
}

更新 pipeline_list 命令支持行业筛选:

pub async fn pipeline_list(
    state: State<'_, Arc<PipelineState>>,
    category: Option<String>,
    industry: Option<String>,  // ← 新增
) -> Result<Vec<PipelineInfo>, String> {
    // ...
}

步骤 3前端类型定义

文件desktop/src/lib/pipeline-client.ts

更新 PipelineInfo 接口:

export interface PipelineInfo {
  id: string;
  displayName: string;
  description: string;
  category: string;
  industry: string;  // ← 新增
  tags: string[];
  icon: string;
  version: string;
  author: string;
  inputs: PipelineInputInfo[];
}

更新 listPipelines 方法:

static async listPipelines(options?: {
  category?: string;
  industry?: string;  // ← 新增
}): Promise<PipelineInfo[]> {
  const pipelines = await invoke<PipelineInfo[]>('pipeline_list', {
    category: options?.category || null,
    industry: options?.industry || null,  // ← 新增
  });
  return pipelines;
}

步骤 4前端行业配置

文件desktop/src/components/PipelinesPanel.tsx

添加行业配置:

// 行业分类配置
const INDUSTRY_CONFIG: Record<string, { label: string; className: string }> = {
  internet: { label: '互联网', className: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400' },
  finance: { label: '金融', className: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400' },
  healthcare: { label: '医疗', className: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400' },
  education: { label: '教育', className: 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400' },
  manufacturing: { label: '制造业', className: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400' },
  retail: { label: '零售', className: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400' },
  realestate: { label: '房地产', className: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400' },
  energy: { label: '能源', className: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400' },
  government: { label: '政府', className: 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-400' },
  other: { label: '其他', className: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400' },
};

添加行业筛选状态和 UI

// 状态
const [selectedIndustry, setSelectedIndustry] = useState<string | null>(null);

// 获取唯一行业列表
const industries = Array.from(
  new Set(pipelines.map((p) => p.industry).filter(Boolean))
);

// 行业筛选按钮组
<div className="flex items-center gap-2 flex-wrap">
  <Building className="w-4 h-4 text-gray-400" />
  <button onClick={() => setSelectedIndustry(null)} ...>全部</button>
  {industries.map((ind) => (
    <button key={ind} onClick={() => setSelectedIndustry(ind)} ...>
      {INDUSTRY_CONFIG[ind]?.label || ind}
    </button>
  ))}
</div>

更新 usePipelines hook 支持行业筛选:

const { pipelines, loading, error, refresh } = usePipelines({
  category: selectedCategory ?? undefined,
  industry: selectedIndustry ?? undefined,  // ← 新增
});

步骤 5更新 Pipeline YAML 文件

为每个 Pipeline 添加 industry 字段:

pipelines/education/classroom.yaml:

metadata:
  name: classroom-generator
  category: education
  industry: education  # ← 新增

pipelines/marketing/campaign.yaml:

metadata:
  name: marketing-campaign
  category: marketing
  industry: internet  # ← 新增(营销主要面向互联网)

pipelines/legal/contract-review.yaml:

metadata:
  name: contract-review
  category: legal
  industry: other  # ← 新增(合同审查适用于所有行业)

pipelines/research/literature-review.yaml:

metadata:
  name: literature-review
  category: research
  industry: other  # ← 新增(学术研究适用于所有领域)

pipelines/productivity/meeting-summary.yaml:

metadata:
  name: meeting-summary
  category: productivity
  industry: other  # ← 新增(会议纪要适用于所有行业)

文件修改清单

文件 修改类型 说明
crates/zclaw-pipeline/src/types.rs 修改 添加 industry 字段
desktop/src-tauri/src/pipeline_commands.rs 修改 更新 PipelineInfo 和筛选逻辑
desktop/src/lib/pipeline-client.ts 修改 更新类型和 API 调用
desktop/src/components/PipelinesPanel.tsx 修改 添加行业筛选 UI
pipelines/education/classroom.yaml 修改 添加 industry 字段
pipelines/marketing/campaign.yaml 修改 添加 industry 字段
pipelines/legal/contract-review.yaml 修改 添加 industry 字段
pipelines/research/literature-review.yaml 修改 添加 industry 字段
pipelines/productivity/meeting-summary.yaml 修改 添加 industry 字段

验证清单

  • 后端编译通过:cargo build
  • 前端类型检查通过:pnpm tsc --noEmit
  • Pipeline 列表正确显示功能分类和行业分类
  • 功能分类筛选正常工作
  • 行业分类筛选正常工作
  • 双维度筛选(功能 + 行业)正常工作
  • Pipeline 卡片显示行业标签

验证命令

# 后端编译
cd desktop/src-tauri && cargo build

# 前端类型检查
cd desktop && pnpm tsc --noEmit

# 启动应用
pnpm start:dev

风险评估

风险 影响 缓解措施
现有 Pipeline 无 industry 字段 显示为空 后端使用 unwrap_or_default() 提供默认值
行业列表不完整 用户找不到对应行业 添加"其他"作为兜底
前后端类型不一致 运行时错误 先修改后端,再修改前端

预定义行业列表

ID 中文标签 说明
internet 互联网 互联网/科技公司
finance 金融 银行、保险、证券
healthcare 医疗 医疗、医药、健康
education 教育 学校、培训、教育科技
manufacturing 制造业 工厂、制造业
retail 零售 电商、零售
realestate 房地产 房地产、建筑
energy 能源 能源、电力、环保
government 政府 政府、公共服务
other 其他 通用/跨行业