wujingjing
2025-02-18 67e50265b5cdae1c28f39b924ccb277857f4acea
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
<template>
    <div class="absolute bottom-0 left-0 right-0 top-0 bg-page text-base">
        <div class="relative flex h-full w-full flex-col">
            <Header :isViewMode="isViewMode" v-if="flowAgent" :flowAgent="flowAgent" :queryId="queryId" @saveClick="saveClick" />
            <main class="relative flex h-full w-full flex-1">
                <Sidebar v-if="!isViewMode" class="w-52" @dragstart="handleOnDragStart" />
                <div class="relative h-full flex-1 overflow-hidden" v-if="flowJson">
                    <MainCanvas
                        ref="mainCanvasRef"
                        :isViewMode="isViewMode"
                        :flowJson="flowJson"
                        :agentNames="agentNames"
                        :funcNames="funcNames"
                        :llmInfoList="llmInfoList"
                    />
                </div>
            </main>
        </div>
    </div>
    <!-- <Toaster /> -->
</template>
<script setup lang="ts">
// import { PlusIcon, GhostIcon } from 'lucide-vue-next'
import { useVueFlow } from '@vue-flow/core';
import { useClipboard } from '@vueuse/core';
// import MainCanvas from '@/components/vue-flow/MainCanvas.vue';
import { ElMessage } from 'element-plus';
import { computed, h, onMounted, ref } from 'vue';
import Header from './components/Header.vue';
import Sidebar from './components/Sidebar.vue';
import {
    get_agent_names,
    get_flow_func_names,
    get_llm_info_list,
    get_workflow_agent_list,
    get_workflow_json_flow,
    update_workflow_json_flow,
} from '/@/api/workflow';
import MainCanvas from '/@/components/vue-flow/MainCanvas.vue';
import router from '/@/router';
import { useCompRef } from '/@/utils/types';
const props = defineProps<{
    isViewMode: {
        type: Boolean;
        default: false;
    };
}>();
// import { Button } from '@/components/ui/button';
// import { Toaster, useToast } from '@/components/ui/toast';
function handleOnDragStart(event: DragEvent, nodeType: any) {
    if (event.dataTransfer) {
        event.dataTransfer.setData('application/vueflow', nodeType);
        event.dataTransfer.effectAllowed = 'move';
    }
}
 
const queryId = computed(() => router.currentRoute.value.query.id as string);
 
const { toObject } = useVueFlow();
const { copy } = useClipboard();
 
const flowJson = ref(null);
 
const flowAgent = ref(null);
 
const handleGetJSON = async (id: string) => {
    const res = await get_workflow_json_flow({
        agent_id: id,
    });
    flowJson.value = res.json_ok ? res.json_flow ?? {} : {};
};
 
const getFlowAgent = async () => {
    const res = await get_workflow_agent_list();
    const flowAgentList = res.values ?? [];
    const currentFlowAgent = flowAgentList.find((item: any) => item.id === queryId.value);
    flowAgent.value = currentFlowAgent;
};
 
const agentNames = ref([]);
const getAgentNames = async () => {
    const res = await get_agent_names();
    agentNames.value = res.agents ?? [];
};
const funcNames = ref([]);
 
const getFuncNames = async () => {
    const res = await get_flow_func_names();
    funcNames.value = res.funcs ?? [];
};
 
const llmInfoList = ref([]);
const getLlmInfoList = async () => {
    const res = await get_llm_info_list();
    const factorys = res.factorys ?? [];
    const connections = res.connections ?? [];
    const logicTree = [];
    factorys.forEach((factory: any) => {
        logicTree.push({
            id: factory.factory_id,
            name: factory.factory_name,
            type: 'factory',
            model: factory,
            children: connections
                .filter((connection: any) => connection.factory_id === factory.factory_id)
                .map((item: any) => ({
                    id: item.connect_id,
                    name: item.connect_title,
                    type: 'connection',
                    model: item,
                })),
        });
    });
    llmInfoList.value = logicTree;
};
 
const mainCanvasRef = useCompRef(MainCanvas);
const saveClick = async (jsonStr: string) => {
    const results = await mainCanvasRef.value.validateForm();
    const isValid = results.every((item) => item.isValid);
    if (!isValid) {
        const messageSet = new Set();
        const invalidFields = results.filter((item) => !item.isValid);
        for (const item of invalidFields) {
            for (const fieldArray of Object.values(item.invalidFields) as any[]) {
                for (const field of fieldArray) {
                    field.message && messageSet.add(field.message);
                }
            }
        }
        // 使用 h 方法创建带换行的消息内容
        ElMessage({
            type: 'error',
            message: h(
                'div',
                {
                    style: {
                        color: '#f56c6c', // Element Plus 默认错误消息的红色
                        fontSize: '14px',
                        lineHeight: '21px',
                    },
                },
                [
                    ...Array.from(messageSet).slice(0, 5).map((msg) =>
                        h(
                            'div',
                            {
                                style: {
                                    marginBottom: '4px',
                                },
                            },
                            msg as any
                        )
                    ),
                ]
            ),
            duration: 3000,
        });
        // ElMessage.error('cesadfsadf')
        return;
    }
 
    const res = await update_workflow_json_flow({
        agent_id: queryId.value,
        json_flow: jsonStr,
    });
 
    ElMessage.success('保存成功!');
};
 
onMounted(() => {
    if (!queryId.value) return;
    handleGetJSON(queryId.value);
    getFlowAgent();
    getAgentNames();
    getFuncNames();
    getLlmInfoList();
});
</script>