feat: 谱系
This commit is contained in:
@@ -13,16 +13,15 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else-if="currentNode === 'simParams'" class="detail-content sim-params-content">
|
||||
<div class="flow-section">
|
||||
<RunFlowPage
|
||||
ref="runFlowRef"
|
||||
:runInfo="runInfo"
|
||||
@change="flowNodeChangeFun"
|
||||
@update="flowUpdateFun"
|
||||
/>
|
||||
<div v-else-if="currentNode === 'simParams'" class="detail-content">
|
||||
<div class="sim-params-tabs">
|
||||
<el-radio-group v-model="currentFlowNodeId" @change="flowNodeRadioChangeFun">
|
||||
<el-radio-button v-for="item in flowNodeList" :key="item.uuid" :value="item.uuid">
|
||||
{{ item.nodeName }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="param-section">
|
||||
<div class="sim-params-content">
|
||||
<FlowNodeParamTable
|
||||
ref="paramTableRef"
|
||||
:nodeParams="currentNodeParams"
|
||||
@@ -138,24 +137,28 @@ import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
import { getSimulationTaskFileApi } from '@/api/data/dataAnalysis';
|
||||
import { getRunPerformanceApi } from '@/api/task/taskpool';
|
||||
import { FILE_TYPE } from '@/utils/enum/file';
|
||||
import RunFlowPage from '@/views/task/execution/components/runDetailPage/runPagecomponent/flow/runFlowPage.vue';
|
||||
import FlowNodeParamTable from '@/components/flow/flowNodeParamTable.vue';
|
||||
import { listSimulationFlowNodeApi } from '@/api/project/run';
|
||||
import { getRunListByRunIdListApi } from '@/api/project/node';
|
||||
import { queryFlowTemplateDetailApi } from '@/api/capability/flow';
|
||||
import { useDict } from '@/utils/useDict';
|
||||
import FilePreview from '@/components/common/filePreview/index.vue';
|
||||
import csvFileReview from '@/views/data/analysis/components/csvFileReview.vue';
|
||||
import { downloadFileById } from '@/utils/file';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
interface Props {
|
||||
currentNode?: string;
|
||||
runId?: string;
|
||||
rowData?: Record<string, any>;
|
||||
defaultKeyResultType?: '1' | '2' | '3';
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
currentNode: 'inputModel',
|
||||
runId: '',
|
||||
rowData: () => ({}),
|
||||
defaultKeyResultType: '1',
|
||||
});
|
||||
const { PERFORMANCE_UNIT } = useDict('PERFORMANCE_UNIT');
|
||||
|
||||
@@ -182,9 +185,7 @@ const modelActionList = [
|
||||
{ title: '预览', type: 'primary', click: previewFileFun },
|
||||
{ title: '下载', type: 'primary', click: downloadFileFun },
|
||||
];
|
||||
const calcFileActionList = [
|
||||
{ title: '下载', type: 'primary', click: downloadFileFun },
|
||||
];
|
||||
const calcFileActionList = [{ title: '下载', type: 'primary', click: downloadFileFun }];
|
||||
const cloudImageActionList = [
|
||||
{ title: '预览', type: 'primary', click: previewFileFun },
|
||||
{ title: '下载', type: 'primary', click: downloadFileFun },
|
||||
@@ -200,23 +201,61 @@ const reportActionList = [
|
||||
|
||||
const keyResultType = ref('1');
|
||||
|
||||
const runFlowRef = ref();
|
||||
const flowNodeList = ref<any[]>([]);
|
||||
const currentFlowNodeId = ref<string>('');
|
||||
const runInfo = ref<any>({});
|
||||
const paramTableRef = ref();
|
||||
const currentFlowNode = ref<any>(null);
|
||||
const currentPageInfo = ref<any>({});
|
||||
const nodeConfigList = ref<any>({});
|
||||
const userDetailParams = ref<any>({});
|
||||
const nodeDatas = ref<any>([]);
|
||||
|
||||
const runInfo = ref<any>({});
|
||||
|
||||
const fetchRunInfoFun = async () => {
|
||||
const fetchFlowNodesFun = async () => {
|
||||
if (!props.runId) {
|
||||
flowNodeList.value = [];
|
||||
runInfo.value = {};
|
||||
nodeConfigList.value = {};
|
||||
return;
|
||||
}
|
||||
const res: any = await getRunListByRunIdListApi({ runIdList: [props.runId] });
|
||||
if (res?.code === 200 && res.data?.length > 0) {
|
||||
runInfo.value = res.data[0];
|
||||
const [nodesRes, runInfoRes]: any = await Promise.all([
|
||||
listSimulationFlowNodeApi({ runId: props.runId }),
|
||||
getRunListByRunIdListApi({ runIdList: [props.runId] }),
|
||||
]);
|
||||
if (runInfoRes?.code === 200 && runInfoRes.data?.length > 0) {
|
||||
runInfo.value = runInfoRes.data[0];
|
||||
if (runInfo.value.flowTemplate) {
|
||||
const templateRes: any = await queryFlowTemplateDetailApi({
|
||||
uuid: runInfo.value.flowTemplate,
|
||||
status: 1,
|
||||
});
|
||||
if (templateRes?.code === 200 && templateRes.data?.viewContent) {
|
||||
try {
|
||||
const viewData = JSON.parse(templateRes.data.viewContent);
|
||||
const nodes = viewData.cells?.filter((item: any) => item.type) || [];
|
||||
const configMap: any = {};
|
||||
nodes.forEach((node: any) => {
|
||||
if (node.data?.label && node.data?.pageConfigList) {
|
||||
configMap[node.data.label] = node.data.pageConfigList;
|
||||
}
|
||||
});
|
||||
nodeConfigList.value = configMap;
|
||||
} catch {
|
||||
nodeConfigList.value = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nodesRes?.code === 200 && nodesRes.data?.flowNodeDtoList) {
|
||||
const allNodes = nodesRes.data.flowNodeDtoList || [];
|
||||
flowNodeList.value = allNodes.filter((node: any) => {
|
||||
const nodeType = node.nodeDetailInfo?.type;
|
||||
return nodeType !== 'StartEvent' && nodeType !== 'EndEvent';
|
||||
});
|
||||
if (flowNodeList.value.length > 0 && !currentFlowNodeId.value) {
|
||||
currentFlowNodeId.value = flowNodeList.value[0].uuid;
|
||||
flowNodeRadioChangeFun(flowNodeList.value[0].uuid);
|
||||
}
|
||||
} else {
|
||||
flowNodeList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -236,13 +275,21 @@ const fetchPerformanceListFun = async () => {
|
||||
|
||||
const currentNodeParams = ref<any>([]);
|
||||
|
||||
const updateCurrentNodeParamsFun = () => {
|
||||
if (!currentFlowNode.value) {
|
||||
currentNodeParams.value = [];
|
||||
return;
|
||||
const mergeUserParamsFun = (list: any[], userParams: any): any[] => {
|
||||
const result = cloneDeep(list);
|
||||
for (const item of result) {
|
||||
if (item.englishLabel && userParams?.[item.englishLabel] !== undefined) {
|
||||
item.defaultValue = userParams[item.englishLabel];
|
||||
}
|
||||
if (item.children?.length) {
|
||||
const childParams =
|
||||
item.tagType === 'view' && item.tagIcon === 'row'
|
||||
? userParams?.[item.vModel] || {}
|
||||
: userParams;
|
||||
item.children = mergeUserParamsFun(item.children, childParams);
|
||||
}
|
||||
}
|
||||
const nodeName = currentFlowNode.value?.store?.data?.data?.label || '';
|
||||
currentNodeParams.value = nodeConfigList.value[nodeName] || [];
|
||||
return result;
|
||||
};
|
||||
|
||||
const getFileListApiFun = async (params: any) => {
|
||||
@@ -259,40 +306,44 @@ const keyResultTypeChangeFun = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const flowNodeChangeFun = (data: any) => {
|
||||
currentFlowNode.value = data.node;
|
||||
const nodeData = data.data || {};
|
||||
currentPageInfo.value = {
|
||||
userParams: nodeData.userParams || {},
|
||||
inputDirId: nodeData.inputDirId || '',
|
||||
};
|
||||
updateCurrentNodeParamsFun();
|
||||
};
|
||||
|
||||
const flowUpdateFun = (data: any) => {
|
||||
nodeConfigList.value = data.list || {};
|
||||
userDetailParams.value = data.param || {};
|
||||
nodeDatas.value = data.nodeDatas || [];
|
||||
updateCurrentNodeParamsFun();
|
||||
const flowNodeRadioChangeFun = (uuid: string) => {
|
||||
const selectedNode = flowNodeList.value.find((node: any) => node.uuid === uuid);
|
||||
if (selectedNode) {
|
||||
currentFlowNode.value = selectedNode;
|
||||
const userParams = selectedNode.userParams || {};
|
||||
currentPageInfo.value = {
|
||||
userParams,
|
||||
inputDirId: selectedNode.inputDirId || '',
|
||||
};
|
||||
const nodeName = selectedNode.nodeName || '';
|
||||
const templateConfig = nodeConfigList.value[nodeName] || [];
|
||||
currentNodeParams.value = mergeUserParamsFun(templateConfig, userParams);
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.currentNode,
|
||||
(newVal) => {
|
||||
if (newVal === 'keyResult') {
|
||||
keyResultType.value = '1';
|
||||
}
|
||||
if (newVal === 'simParams') {
|
||||
fetchRunInfoFun();
|
||||
currentFlowNodeId.value = '';
|
||||
fetchFlowNodesFun();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.defaultKeyResultType,
|
||||
(newVal) => {
|
||||
keyResultType.value = newVal;
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.runId,
|
||||
(newVal) => {
|
||||
if (newVal && props.currentNode === 'simParams') {
|
||||
fetchRunInfoFun();
|
||||
currentFlowNodeId.value = '';
|
||||
fetchFlowNodesFun();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
@@ -309,25 +360,17 @@ watch(
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sim-params-content {
|
||||
.sim-params-tabs {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.flow-section {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.param-section {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.sim-params-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
<span class="title-text">{{ currentNodeLabel }}</span>
|
||||
</div>
|
||||
<div class="detail-wrapper">
|
||||
<PedigreeDetail :currentNode="currentNodeId" :runId="runId" :rowData="rowData" />
|
||||
<PedigreeDetail
|
||||
:currentNode="currentNodeId"
|
||||
:runId="runId"
|
||||
:rowData="rowData"
|
||||
:defaultKeyResultType="defaultKeyResultType"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,7 +41,7 @@ const { t } = useI18n();
|
||||
interface Props {
|
||||
modelValue?: boolean;
|
||||
rowData?: Record<string, any>;
|
||||
dataType?: string;
|
||||
dataType?: '模型文件' | '仿真报告' | '计算文件' | '结果曲线' | '结果云图' | '';
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -67,6 +72,27 @@ const nodeLabelsKey: Record<string, string> = {
|
||||
|
||||
const currentNodeLabel = computed(() => t(nodeLabelsKey[currentNodeId.value]) || '');
|
||||
|
||||
const dataTypeToNodeIdMap: Record<string, string> = {
|
||||
模型文件: 'inputModel',
|
||||
仿真报告: 'simReport',
|
||||
计算文件: 'calcModel',
|
||||
结果曲线: 'keyResult',
|
||||
结果云图: 'keyResult',
|
||||
};
|
||||
|
||||
const dataTypeToKeyResultTypeMap: Record<string, string> = {
|
||||
结果云图: '1',
|
||||
结果曲线: '2',
|
||||
};
|
||||
|
||||
const getDefaultNodeIdFun = () => {
|
||||
return dataTypeToNodeIdMap[props.dataType] || 'inputModel';
|
||||
};
|
||||
|
||||
const defaultKeyResultType = computed(() => {
|
||||
return dataTypeToKeyResultTypeMap[props.dataType] || '1';
|
||||
});
|
||||
|
||||
const runId = computed(() => {
|
||||
return props.rowData?.ownRunId;
|
||||
});
|
||||
@@ -79,9 +105,10 @@ watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentNodeId.value = 'inputModel';
|
||||
const defaultNodeId = getDefaultNodeIdFun();
|
||||
currentNodeId.value = defaultNodeId;
|
||||
nextTick(() => {
|
||||
flowRef.value?.setSelectedNodeFun('inputModel');
|
||||
flowRef.value?.setSelectedNodeFun(defaultNodeId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,6 +564,9 @@ const modeChangeFun = () => {
|
||||
currentPedigreeRow.value = row;
|
||||
pedigreeVisible.value = true;
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return !row.ownRunId;
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
|
||||
Reference in New Issue
Block a user