工作流管理相关
This commit is contained in:
@@ -45,7 +45,6 @@
|
||||
v-model:current-page="pagination.pageNum"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
layout="total, prev, pager, next"
|
||||
small
|
||||
@current-change="handlePageChange"
|
||||
@@ -145,6 +144,11 @@ const fetchModelList = async () => {
|
||||
const res = await getWorkflowModelList(params);
|
||||
modelList.value = res.data?.list || [];
|
||||
pagination.total = res.data?.total || 0;
|
||||
// 预选项仅为部分信息(切换节点后无 id)时,按名称匹配当前页以高亮
|
||||
if (selectedModel.value && !selectedModel.value.id && selectedModel.value.modelName) {
|
||||
const matched = modelList.value.find((m) => m.modelName === selectedModel.value!.modelName);
|
||||
if (matched) selectedModel.value = matched;
|
||||
}
|
||||
} catch {
|
||||
modelList.value = [];
|
||||
pagination.total = 0;
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
<el-form-item label="节点名称">
|
||||
<el-input :model-value="selectedNode.data?.label" @update:model-value="updateNodeLabel" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!isStartNode" label="节点描述">
|
||||
<el-input
|
||||
:model-value="selectedNode.data?.desc || ''"
|
||||
placeholder="请输入节点描述"
|
||||
@update:model-value="updateNodeDesc"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="节点类型">
|
||||
<el-tag>{{ selectedNode.data?.nodeCode }}</el-tag>
|
||||
</el-form-item>
|
||||
@@ -74,7 +81,7 @@
|
||||
:placeholder="field.required ? '必填' : '选填'"
|
||||
class="w100"
|
||||
>
|
||||
<el-option v-for="opt in field.options" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||
<el-option v-for="opt in field.options" :key="opt.key || opt.value" :label="opt.value" :value="opt.value" />
|
||||
</el-select>
|
||||
<KeyValueEditor
|
||||
v-else-if="field.type === 'keyValue'"
|
||||
@@ -120,6 +127,7 @@ import { JsonEditor } from '/@/components/json-schema-editor';
|
||||
interface NodeData {
|
||||
label?: string;
|
||||
nodeCode?: string;
|
||||
desc?: string;
|
||||
formConfig?: any[];
|
||||
modelConfig?: any;
|
||||
skillName?: string;
|
||||
@@ -145,6 +153,9 @@ const isVideoModelSelected = computed(() => {
|
||||
return t >= 600 && t <= 605;
|
||||
});
|
||||
|
||||
// 开始节点不展示节点描述
|
||||
const isStartNode = computed(() => props.selectedNode?.data?.nodeCode === '__start__');
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:selectedNode', node: Node<NodeData, any, string>): void;
|
||||
(e: 'openModelSelector'): void;
|
||||
@@ -183,6 +194,18 @@ const updateNodeLabel = (newLabel: string) => {
|
||||
emit('update:selectedNode', updatedNode);
|
||||
};
|
||||
|
||||
const updateNodeDesc = (newDesc: string) => {
|
||||
if (!props.selectedNode?.data) return;
|
||||
const updatedNode = {
|
||||
...props.selectedNode,
|
||||
data: {
|
||||
...props.selectedNode.data,
|
||||
desc: newDesc,
|
||||
},
|
||||
};
|
||||
emit('update:selectedNode', updatedNode);
|
||||
};
|
||||
|
||||
const getFieldValue = (fieldName: string) => {
|
||||
if (!props.selectedNode?.data?.formConfig) return '';
|
||||
const field = props.selectedNode.data.formConfig.find((f: any) => f.field === fieldName);
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
v-model:current-page="pagination.pageNum"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50]"
|
||||
layout="total, prev, pager, next"
|
||||
small
|
||||
@current-change="handlePageChange"
|
||||
@@ -82,6 +81,7 @@ watch(
|
||||
visible.value = val;
|
||||
if (val) {
|
||||
selectedSkill.value = props.defaultSkill || null;
|
||||
pagination.pageNum = 1;
|
||||
fetchSkillList();
|
||||
}
|
||||
}
|
||||
@@ -100,6 +100,11 @@ const fetchSkillList = async () => {
|
||||
const res = await getWorkflowSkillList(params);
|
||||
skillList.value = res.data?.list || [];
|
||||
pagination.total = res.data?.total || 0;
|
||||
// 预选项仅为部分信息(切换节点后无 id)时,按名称匹配当前页以高亮
|
||||
if (selectedSkill.value && !selectedSkill.value.id && selectedSkill.value.name) {
|
||||
const matched = skillList.value.find((s) => s.name === selectedSkill.value!.name);
|
||||
if (matched) selectedSkill.value = matched;
|
||||
}
|
||||
} catch {
|
||||
skillList.value = [];
|
||||
pagination.total = 0;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<!-- 中间:VueFlow 画布(节点库在画布内) -->
|
||||
<div class="flow-wrapper">
|
||||
<NodeLibraryPanel
|
||||
:node-library-groups="filteredNodeLibraryGroups"
|
||||
:node-library-groups="nodeLibraryGroups"
|
||||
:collapsed="nodeLibraryCollapsed"
|
||||
@update:collapsed="nodeLibraryCollapsed = $event"
|
||||
@add-node="addNodeFromLibrary"
|
||||
@@ -108,6 +108,7 @@ import SkillSelector from './component/SkillSelector.vue';
|
||||
interface NodeData {
|
||||
label?: string;
|
||||
nodeCode?: string;
|
||||
desc?: string;
|
||||
formConfig?: any[];
|
||||
modelConfig?: any;
|
||||
skillName?: string;
|
||||
@@ -124,10 +125,6 @@ const JUDGE_KEYWORDS = ['判断', 'judge', 'condition', 'if', 'branch', 'gateway
|
||||
const nodeLibraryGroups = ref<NodeLibraryGroup[]>([]);
|
||||
const nodeLibraryCollapsed = ref(false);
|
||||
|
||||
const filteredNodeLibraryGroups = computed(() => {
|
||||
return nodeLibraryGroups.value;
|
||||
});
|
||||
|
||||
// 节点配置映射:nodeCode -> 节点配置
|
||||
const nodeConfigMap = computed(() => {
|
||||
const map = new Map<
|
||||
@@ -243,6 +240,11 @@ const onConnect = (connection: Connection) => {
|
||||
|
||||
const onNodeClick = (event: { node: Node<NodeData, any, string> }) => {
|
||||
selectedNode.value = event.node;
|
||||
// 同步选择器预选项,避免展示上一个节点的模型/技能
|
||||
const mc = event.node.data?.modelConfig;
|
||||
selectedModelData.value = mc?.modelName ? { modelName: mc.modelName, modelType: mc.modelType } : null;
|
||||
const sk = event.node.data?.skillName;
|
||||
selectedSkillData.value = sk ? { name: sk } : null;
|
||||
};
|
||||
|
||||
const updateSelectedNode = (updatedNode: Node<NodeData, any, string>) => {
|
||||
@@ -444,6 +446,7 @@ const getNodeLibrary = async () => {
|
||||
nodeLibraryGroups.value = res.data?.groups || [];
|
||||
} catch {
|
||||
nodeLibraryGroups.value = [];
|
||||
ElMessage.error('节点库加载失败');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -469,7 +472,7 @@ const addNodeFromLibrary = (nodeCode: string, nodeName: string) => {
|
||||
id: `node-${++nodeId}`,
|
||||
type: 'default',
|
||||
position: { x: spawnX, y: spawnY },
|
||||
data: { label: nodeName, nodeCode, patchLayout: false },
|
||||
data: { label: nodeName, nodeCode, desc: '', patchLayout: false },
|
||||
style: { background: '#fff', border: '2px solid #3b82f6', borderRadius: '8px', padding: '10px 20px' },
|
||||
},
|
||||
]);
|
||||
@@ -547,6 +550,7 @@ const loadWorkflowFromDsl = (dsl: any) => {
|
||||
data: {
|
||||
label: n.name || '',
|
||||
nodeCode: n.nodeCode,
|
||||
desc: n.desc || '',
|
||||
formConfig: n.formConfig || null,
|
||||
modelConfig: n.modelConfig || null,
|
||||
skillName: n.skillName || null,
|
||||
@@ -605,14 +609,16 @@ const confirmSaveWorkflow = async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const startNode = nodes.value.find((n) => isStartNode(n));
|
||||
const workflowDsl = {
|
||||
version: '1.0.0',
|
||||
startNodeId: nodes.value[0]?.id || '',
|
||||
startNodeId: startNode?.id || '',
|
||||
nodes: nodes.value.map((n) => ({
|
||||
id: n.id,
|
||||
nodeCode: n.data?.nodeCode || 'unknown',
|
||||
name: n.data?.label || '',
|
||||
type: n.type || 'default',
|
||||
desc: n.data?.desc || null,
|
||||
skillName: n.data?.skillName || null,
|
||||
patchLayout: n.data?.patchLayout || false,
|
||||
config: {
|
||||
|
||||
Reference in New Issue
Block a user