From 5562148327888b00c9af2020bd2a6444de981277 Mon Sep 17 00:00:00 2001 From: HYana Date: Mon, 28 Apr 2025 02:49:11 +0800 Subject: [PATCH] feat: change pipeline form --- .../home/bots/components/bot-form/BotForm.tsx | 3 +- .../pipeline-card/PipelineCardComponent.tsx | 33 ++ .../pipeline-card/PipelineCardVO.ts | 23 ++ .../pipeline-card/pipelineCard.module.css | 59 +++ .../pipeline-form/PipelineFormComponent.tsx | 379 ++++++++++++------ web_ui/src/app/home/pipelines/page.tsx | 27 +- 6 files changed, 393 insertions(+), 131 deletions(-) create mode 100644 web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardComponent.tsx create mode 100644 web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardVO.ts create mode 100644 web_ui/src/app/home/pipelines/components/pipeline-card/pipelineCard.module.css diff --git a/web_ui/src/app/home/bots/components/bot-form/BotForm.tsx b/web_ui/src/app/home/bots/components/bot-form/BotForm.tsx index fa60fde6..4ab9d608 100644 --- a/web_ui/src/app/home/bots/components/bot-form/BotForm.tsx +++ b/web_ui/src/app/home/bots/components/bot-form/BotForm.tsx @@ -134,6 +134,7 @@ export default function BotForm({ httpClient.updateBot(initBotId, updateBot).then(res => { // TODO success toast console.log("update bot success", res) + onFormSubmit(form.getFieldsValue()) }).catch(err => { // TODO error toast console.log("update bot error", err) @@ -150,13 +151,13 @@ export default function BotForm({ httpClient.createBot(newBot).then(res => { // TODO success toast console.log(res) + onFormSubmit(form.getFieldsValue()) }).catch(err => { // TODO error toast console.log(err) }) } setShowDynamicForm(false) - onFormSubmit(form.getFieldsValue()) form.resetFields() dynamicForm.resetFields() } diff --git a/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardComponent.tsx b/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardComponent.tsx new file mode 100644 index 00000000..124e1d02 --- /dev/null +++ b/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardComponent.tsx @@ -0,0 +1,33 @@ +import styles from "./pipelineCard.module.css"; +import {PipelineCardVO} from "@/app/home/pipelines/components/pipeline-card/PipelineCardVO"; + +export default function PipelineCardComponent({ + cardVO +}: { + cardVO: PipelineCardVO +}) { + return ( +
+ {/* icon和基本信息 */} +
+ {/* icon */} +
+ ICO +
+ {/* 基本信息 */} +
+
+ {cardVO.name} +
+
+ 描述:{cardVO.description} +
+
+
+ {/* URL和创建时间 */} +
+ 版本:{cardVO.version} +
+
+ ); +} \ No newline at end of file diff --git a/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardVO.ts b/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardVO.ts new file mode 100644 index 00000000..03dbeb53 --- /dev/null +++ b/web_ui/src/app/home/pipelines/components/pipeline-card/PipelineCardVO.ts @@ -0,0 +1,23 @@ +export interface IPipelineCardVO { + id: string; + name: string; + description: string; + createTime: string; + version: string; +} + +export class PipelineCardVO implements IPipelineCardVO { + createTime: string; + description: string; + id: string; + name: string; + version: string; + + constructor(props: IPipelineCardVO) { + this.id = props.id; + this.name = props.name; + this.description = props.description; + this.createTime = props.createTime; + this.version = props.version; + } +} \ No newline at end of file diff --git a/web_ui/src/app/home/pipelines/components/pipeline-card/pipelineCard.module.css b/web_ui/src/app/home/pipelines/components/pipeline-card/pipelineCard.module.css new file mode 100644 index 00000000..33fe3aa5 --- /dev/null +++ b/web_ui/src/app/home/pipelines/components/pipeline-card/pipelineCard.module.css @@ -0,0 +1,59 @@ +.iconBasicInfoContainer { + width: 300px; + height: 100px; + margin-left: 20px; + display: flex; + flex-direction: row; +} + +.cardContainer { + width: 360px; + height: 200px; + background-color: #FFF; + border-radius: 9px; + box-shadow: rgba(0, 0, 0, 0.4) 0 1px 1px -1px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: space-evenly; +} + +.icon { + width: 90px; + height: 90px; + border-radius: 5px; + font-size: 40px; + line-height: 90px; + text-align: center; + color: #ffffff; + background: rgba(96, 149, 209, 0.31); + border: 1px solid rgba(96, 149, 209, 0.31); +} + +.basicInfoContainer { + width: 200px; + height: 90px; + padding-left: 20px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: space-between; +} + +.basicInfoText { + +} + +.bigText { + font-size: 20px; +} + +.urlAndUpdateText { + margin-left: 20px; +} + +.createCardContainer { + font-size: 90px; + background: #6062E7; + color: white; +} \ No newline at end of file diff --git a/web_ui/src/app/home/pipelines/components/pipeline-form/PipelineFormComponent.tsx b/web_ui/src/app/home/pipelines/components/pipeline-form/PipelineFormComponent.tsx index 5eec0ebf..5e81219f 100644 --- a/web_ui/src/app/home/pipelines/components/pipeline-form/PipelineFormComponent.tsx +++ b/web_ui/src/app/home/pipelines/components/pipeline-form/PipelineFormComponent.tsx @@ -1,7 +1,11 @@ -import {Form, Button, Switch, Select, Input, InputNumber} from "antd"; +import {Form, Button, Switch, Select, Input, InputNumber, SelectProps} from "antd"; import { CaretLeftOutlined, CaretRightOutlined } from '@ant-design/icons'; -import {useState} from "react"; +import {useEffect, useState} from "react"; import styles from "./pipelineFormStyle.module.css" +import {httpClient} from "@/app/infra/http/HttpClient"; +import {LLMModel, Pipeline} from "@/app/infra/api/api-types"; +import {LLMCardVO} from "@/app/home/models/component/llm-card/LLMCardVO"; +import {UUID} from "uuidjs"; export default function PipelineFormComponent({ onFinish, @@ -11,13 +15,38 @@ export default function PipelineFormComponent({ onCancel: () => void; }) { const [nowFormIndex, setNowFormIndex] = useState(0) + const [nowAIRunner, setNowAIRunner] = useState("") + const [llmModelList, setLlmModelList] = useState([]) // 这里不好,可以改成enum等 const formLabelList: FormLabel[] = [ + {label: "基础", name: "basic"}, {label: "AI能力", name: "ai"}, {label: "触发条件", name: "trigger"}, {label: "安全能力", name: "safety"}, {label: "输出处理", name: "output"}, ] + const [basicForm] = Form.useForm() + const [aiForm] = Form.useForm() + const [triggerForm] = Form.useForm() + const [safetyForm] = Form.useForm() + const [outputForm] = Form.useForm() + + useEffect(() => { + getLLMModelList() + }, []) + + function getLLMModelList() { + httpClient.getProviderLLMModels().then((resp) => { + setLlmModelList(resp.models.map((model: LLMModel) => { + return { + value: model.uuid, + label: model.name, + } + })) + }).catch((err) => { + console.error("get LLM model list error", err) + }) + } function getNowFormLabel() { return formLabelList[nowFormIndex] @@ -52,6 +81,50 @@ export default function PipelineFormComponent({ } } + function handleCommit() { + Promise.all([ + basicForm.validateFields(), + aiForm.validateFields(), + triggerForm.validateFields(), + safetyForm.validateFields(), + outputForm.validateFields(), + ]).then(() => { + const pipeline = assembleForm() + httpClient.createPipeline(pipeline).then(r => + onFinish() + ) + }).catch(e => { + console.error(e) + }) + } + + // TODO 类型混乱,需要优化 + function assembleForm(): Pipeline { + console.log("basicForm:", basicForm.getFieldsValue()) + console.log("aiForm:", aiForm.getFieldsValue()) + console.log("triggerForm:", triggerForm.getFieldsValue()) + console.log("safetyForm:", safetyForm.getFieldsValue()) + console.log("outputForm:", outputForm.getFieldsValue()) + const config: object = { + ai: aiForm.getFieldsValue(), + trigger: triggerForm.getFieldsValue(), + safety: safetyForm.getFieldsValue(), + output: outputForm.getFieldsValue(), + } + + return { + config, + created_at: "", + description: basicForm.getFieldsValue().description, + for_version: "", + name: basicForm.getFieldsValue().name, + stages: [], + updated_at: "", + uuid: UUID.generate(), + } + } + + return (
{getNowFormLabel().label} +
+ + + + + + + +
{/* AI能力表单 ai */}
{/* Runner 配置区块 */}
运行器
@@ -77,163 +175,179 @@ export default function PipelineFormComponent({ { label: "Dify 服务 API", value: "dify-service-api" }, { label: "阿里云百炼平台 API", value: "dashscope-app-api" } ]} + onChange={value => setNowAIRunner(value)} /> {/* 内置 Agent 配置区块 */} -
配置内置Agent
- {/* TODO 这里要拉模型 */} - - + + + + + {/* TODO 这里要做转换处理 */} + + + + + } {/* Dify 服务 API 区块 */} -
配置Dify服务API
- - - - - ...\<\/think\>", value: "plain" }, - { label: "原始", value: "original" }, - { label: "移除", value: "remove" } - ]} - /> - - + { + nowAIRunner === "dify-service-api" && + <> +
配置Dify服务API
+ + + + + ...\<\/think\>", value: "plain"}, + {label: "原始", value: "original"}, + {label: "移除", value: "remove"} + ]} + /> + + + } {/* 阿里云百炼区块 */} -
配置阿里云百炼平台 API
- - - - - - + { + nowAIRunner === "dashscope-app-api" && + <> +
配置阿里云百炼平台 API
+ + + + + + + + }
{/* 触发条件表单 trigger */}
{/* 群响应规则块 */} -
群响应规则
+
群响应规则
- + {/* 内容过滤块 content-filter */}
内容过滤
@@ -382,6 +497,7 @@ export default function PipelineFormComponent({ {/* 长文本处理区块 */}
长文本处理
@@ -486,7 +602,7 @@ export default function PipelineFormComponent({ @@ -510,3 +626,8 @@ interface FormLabel { label: string, name: string, } + +interface LLMSelectList { + label: string, + name: string, +} \ No newline at end of file diff --git a/web_ui/src/app/home/pipelines/page.tsx b/web_ui/src/app/home/pipelines/page.tsx index f9363e2e..c9be078a 100644 --- a/web_ui/src/app/home/pipelines/page.tsx +++ b/web_ui/src/app/home/pipelines/page.tsx @@ -3,13 +3,33 @@ import {Modal} from "antd"; import {useState} from "react"; import CreateCardComponent from "@/app/infra/basic-component/create-card-component/CreateCardComponent"; import PipelineFormComponent from "./components/pipeline-form/PipelineFormComponent"; +import {httpClient} from "@/app/infra/http/HttpClient"; +import {PipelineCardVO} from "@/app/home/pipelines/components/pipeline-card/PipelineCardVO"; export default function PluginConfigPage() { const [modalOpen, setModalOpen] = useState(false); const [isEditForm, setIsEditForm] = useState(false) + const [pipelineList, setPipelineList] = useState([]) + function getPipelines() { + httpClient.getPipelines().then(value => { + value.pipelines.map(pipeline => { + return new PipelineCardVO({ + createTime: pipeline.created_at, + description: pipeline.description, + id: pipeline.uuid, + name: pipeline.name, + version: pipeline.for_version + }) + }) + }).catch(error => { + // TODO toast + console.log(error) + }) + } + return (
- {}} onCancel={() => {}}/> + { + getPipelines() + setModalOpen(false) + }} + onCancel={() => {}}/> {setModalOpen(true)}}/>