412 lines
12 KiB
Vue
412 lines
12 KiB
Vue
<template>
|
|
<div class="pedigree-detail">
|
|
<div v-if="currentNode === 'inputModel'" class="detail-content">
|
|
<BaseTable
|
|
ref="inputModelTableRef"
|
|
tableName="RESULT_MODEL"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.MODEL_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="modelActionList"
|
|
/>
|
|
</div>
|
|
|
|
<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="sim-params-content">
|
|
<FlowNodeParamTable
|
|
ref="paramTableRef"
|
|
:nodeParams="currentNodeParams"
|
|
:pageInfo="currentPageInfo"
|
|
:currentNode="currentFlowNode"
|
|
:runInfo="runInfo"
|
|
:hideButtons="true"
|
|
:readonly="true"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else-if="currentNode === 'calcModel'" class="detail-content">
|
|
<BaseTable
|
|
ref="calcModelTableRef"
|
|
tableName="RESULT_FILE"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.CALCULATION_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="calcFileActionList"
|
|
/>
|
|
</div>
|
|
|
|
<div v-else-if="currentNode === 'calcResult'" class="detail-content">
|
|
<BaseTable
|
|
ref="calcResultTableRef"
|
|
tableName="RESULT_FILE"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.CALCULATION_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="calcFileActionList"
|
|
/>
|
|
</div>
|
|
|
|
<div v-else-if="currentNode === 'keyResult'" class="detail-content">
|
|
<div class="key-result-tabs">
|
|
<el-radio-group v-model="keyResultType" @change="refreshKeyResultTableFun">
|
|
<el-radio-button value="1">{{ $t('数据谱系.云图结果') }}</el-radio-button>
|
|
<el-radio-button value="2">{{ $t('数据谱系.曲线结果') }}</el-radio-button>
|
|
<el-radio-button value="3">{{ $t('数据谱系.数值指标') }}</el-radio-button>
|
|
</el-radio-group>
|
|
</div>
|
|
<div class="key-result-content">
|
|
<BaseTable
|
|
v-if="keyResultType === '1'"
|
|
ref="cloudImageTableRef"
|
|
tableName="RESULT_PNG"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.PNG_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="cloudImageActionList"
|
|
/>
|
|
<BaseTable
|
|
v-else-if="keyResultType === '2'"
|
|
ref="curveTableRef"
|
|
tableName="RESULT_CURVE"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.CANVAS_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="curveActionList"
|
|
/>
|
|
<BaseTable
|
|
v-else-if="keyResultType === '3'"
|
|
ref="performanceTableRef"
|
|
tableName="TASK_RUN_PERFORMANCE"
|
|
:data="performanceList"
|
|
:params="{ runId: runId }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
hidePagination
|
|
>
|
|
<template #unit="{ row }">
|
|
{{ PERFORMANCE_UNIT.O[row.unit] }}
|
|
</template>
|
|
</BaseTable>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else-if="currentNode === 'simReport'" class="detail-content">
|
|
<BaseTable
|
|
ref="reportTableRef"
|
|
tableName="RESULT_REPORT"
|
|
:api="getFileListApiFun"
|
|
:params="{ uuid: runId, fileBizType: FILE_TYPE.REPORT_FILE }"
|
|
showIndex
|
|
:fullHeight="true"
|
|
hideSearch
|
|
:actionList="reportActionList"
|
|
/>
|
|
</div>
|
|
|
|
<FilePreview v-model="previewVisible" :fileId="currentRow?.id" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, watch } from 'vue';
|
|
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 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 { downloadFileById } from '@/utils/file';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
interface Props {
|
|
currentNode?: string;
|
|
runId?: string;
|
|
rowData?: Record<string, any>;
|
|
defaultKeyResultType?: '1' | '2' | '3' | string;
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
currentNode: 'inputModel',
|
|
runId: '',
|
|
rowData: () => ({}),
|
|
defaultKeyResultType: '1',
|
|
});
|
|
const { PERFORMANCE_UNIT } = useDict('PERFORMANCE_UNIT');
|
|
|
|
const previewVisible = ref(false);
|
|
const currentRow = ref<any>(null);
|
|
|
|
const previewFileFun = (row: any) => {
|
|
currentRow.value = row;
|
|
previewVisible.value = true;
|
|
};
|
|
|
|
const downloadFileFun = (row: any) => {
|
|
downloadFileById(row.id);
|
|
};
|
|
|
|
const modelActionList = [
|
|
{ title: '预览', type: 'primary', click: previewFileFun },
|
|
{ title: '下载', type: 'primary', click: downloadFileFun },
|
|
];
|
|
const calcFileActionList = [{ title: '下载', type: 'primary', click: downloadFileFun }];
|
|
const cloudImageActionList = [
|
|
{ title: '预览', type: 'primary', click: previewFileFun },
|
|
{ title: '下载', type: 'primary', click: downloadFileFun },
|
|
];
|
|
const curveActionList = [
|
|
{ title: '预览', type: 'primary', click: previewFileFun },
|
|
{ title: '下载', type: 'primary', click: downloadFileFun },
|
|
];
|
|
const reportActionList = [
|
|
{ title: '预览', type: 'primary', click: previewFileFun },
|
|
{ title: '下载', type: 'primary', click: downloadFileFun },
|
|
];
|
|
|
|
const keyResultType = ref('1');
|
|
|
|
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 fetchFlowNodesFun = async () => {
|
|
if (!props.runId) {
|
|
flowNodeList.value = [];
|
|
runInfo.value = {};
|
|
nodeConfigList.value = {};
|
|
return;
|
|
}
|
|
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 = [];
|
|
}
|
|
};
|
|
|
|
const performanceList = ref<any>([]);
|
|
const fetchPerformanceListFun = async () => {
|
|
if (!props.runId) {
|
|
performanceList.value = [];
|
|
return;
|
|
}
|
|
const res: any = await getRunPerformanceApi({ runId: props.runId });
|
|
if (res?.code === 200) {
|
|
performanceList.value = res.data || [];
|
|
} else {
|
|
performanceList.value = [];
|
|
}
|
|
};
|
|
|
|
const currentNodeParams = ref<any>([]);
|
|
|
|
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);
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
const getFileListApiFun = async (params: any) => {
|
|
const res: any = await getSimulationTaskFileApi({
|
|
...params,
|
|
runId: props.runId,
|
|
});
|
|
return res;
|
|
};
|
|
|
|
const cloudImageTableRef = ref();
|
|
const curveTableRef = ref();
|
|
const performanceTableRef = ref();
|
|
|
|
const refreshKeyResultTableFun = () => {
|
|
const tableRefMap: Record<string, any> = {
|
|
'1': cloudImageTableRef,
|
|
'2': curveTableRef,
|
|
'3': performanceTableRef,
|
|
};
|
|
if (keyResultType.value === '3') {
|
|
fetchPerformanceListFun();
|
|
}
|
|
tableRefMap[keyResultType.value]?.value?.resetFun(true);
|
|
};
|
|
|
|
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 === 'simParams') {
|
|
currentFlowNodeId.value = '';
|
|
fetchFlowNodesFun();
|
|
} else if (newVal === 'keyResult' && props.defaultKeyResultType) {
|
|
keyResultType.value = props.defaultKeyResultType;
|
|
refreshKeyResultTableFun();
|
|
}
|
|
}
|
|
);
|
|
|
|
watch(
|
|
() => props.defaultKeyResultType,
|
|
(newVal) => {
|
|
if (props.currentNode === 'keyResult' && newVal) {
|
|
keyResultType.value = newVal;
|
|
refreshKeyResultTableFun();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
watch(
|
|
() => props.runId,
|
|
(newVal, oldVal) => {
|
|
if (newVal && newVal !== oldVal && props.currentNode === 'keyResult') {
|
|
keyResultType.value = props.defaultKeyResultType || '1';
|
|
refreshKeyResultTableFun();
|
|
}
|
|
}
|
|
);
|
|
|
|
watch(
|
|
() => props.runId,
|
|
(newVal) => {
|
|
if (newVal && props.currentNode === 'simParams') {
|
|
currentFlowNodeId.value = '';
|
|
fetchFlowNodesFun();
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.pedigree-detail {
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
.detail-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.sim-params-tabs {
|
|
width: 100%;
|
|
height: 50px;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 10px;
|
|
}
|
|
|
|
.sim-params-content {
|
|
width: 100%;
|
|
height: calc(100% - 50px);
|
|
}
|
|
|
|
.empty-tip {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.key-result-tabs {
|
|
width: 100%;
|
|
height: 50px;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 10px;
|
|
}
|
|
|
|
.key-result-content {
|
|
width: 100%;
|
|
height: calc(100% - 50px);
|
|
}
|
|
}
|
|
</style>
|