update:更新生成报告界面,修复算例相关界面功能

This commit is contained in:
2025-11-26 17:18:25 +08:00
parent 9fe11ed556
commit 7fa68f5190
10 changed files with 402 additions and 40 deletions

View File

@@ -98,7 +98,7 @@ export const addSimulationKeyResultApi = (params: any) => {
* @param params runId keyResultType size current
* @returns
*/
export const listSimulationKeyResult = (params: any) => {
export const listSimulationKeyResultApi = (params: any) => {
return post(`${PREFIX}run/listSimulationKeyResult`, params);
};
@@ -112,3 +112,12 @@ export const deleteSimulationKeyResultApi = (params: any) => {
return post(`${PREFIX}run/deleteSimulationKeyResult`, params);
};
/**
* 生成自动化报告
* @param params imageFileIdList 图片文件id列表 performanceList 性能指标列表 parentNodeInfoList
* @returns
*/
export const generateReportApi = (params: any) => {
return post(`${PREFIX}run/generateReport`, params);
};

View File

@@ -436,6 +436,7 @@ const exportFileFn = () => {
defineExpose({
saveFn,
baseTableRef,
});
const actionList = ref([

View File

@@ -5,7 +5,7 @@
ref="tableRef"
:searchItems="searchItems"
:searchParams="{model:'仿真工况'}"
:api="getTaskListApi"
:api="getTaskListFn"
:searchLimitNum="3"
tableName="SIMULATION_TASK_ANALYSIS"
showIndex
@@ -31,7 +31,7 @@
ref="tableRef"
:searchItems="searchItems"
:searchParams="{model:'仿真算例'}"
:api="getRunListApi"
:api="getRunListFn"
:searchLimitNum="3"
tableName="SIMULATION_RUN_ANALYSIS"
showIndex
@@ -57,7 +57,7 @@
ref="tableRef"
:searchItems="searchItems"
:searchParams="{model:'数据指标'}"
:api="getPerformanceListApi"
:api="getPerformanceListFn"
:searchLimitNum="3"
tableName="SIMULATION_PERFORMANCE_ANALYSIS"
showIndex
@@ -819,6 +819,12 @@ const getSimulationTaskFileFn = async (param:any) => {
})?.uuid;
}
// if (params?.dateRange) {
// params.beginTime = params?.dateRange[0];
// params.endTime = params?.dateRange[1];
// delete params?.dateRange;
// }
const res:any = await getSimulationTaskFileApi(params);
if (res && res.code === 200) {
return res;
@@ -826,6 +832,59 @@ const getSimulationTaskFileFn = async (param:any) => {
};
const getTaskListFn = async (param:any) => {
console.log(param, 'param');
const params:any = {
...param,
};
setParamFn(params);
const res:any = await getTaskListApi(params);
return res;
};
const getRunListFn = async (param:any) => {
const params:any = {
...param,
};
setParamFn(params);
const res:any = await getRunListApi(params);
return res;
};
const getPerformanceListFn = async (param:any) => {
const params:any = {
...param,
};
setParamFn(params);
const res:any = await getPerformanceListApi(params);
return res;
};
const setParamFn = (params:any) => {
if (params?.project) {
params.projectNodeId = params?.project;
delete params.project;
}
if (params?.phase) {
params.phaseNodeId = params?.phase;
delete params.phase;
}
if (params?.discipline) {
params.disciplineNodeId = params?.discipline;
delete params.discipline;
}
if (params?.dateRange) {
params.beginTime = params?.dateRange[0];
params.endTime = params?.dateRange[1];
delete params?.dateRange;
}
};
onMounted(() => {
getProjectOptionsFun();
});

View File

@@ -1,6 +1,5 @@
<template>
<div class="task-tree-content" @contextmenu.prevent="">
<div class="filter-content">
<filterProject @filter-param-change-fn="filterParamChangeFn" @expand-tree="changeExpendTypeFn"></filterProject>
</div>
@@ -64,6 +63,10 @@
></createRunDiv>
<runVersionTreeDiv v-if="showRunVersionTreeWindow" @close="showRunVersionTreeWindow = false" :current-node-info="rightClickNode"></runVersionTreeDiv>
<taskRunPerformance v-if="showTaskRunPerformanceWindow" @close="showTaskRunPerformanceWindow=false" :current-node-info="rightClickNodeInfo"></taskRunPerformance>
<createRunReport v-if="showCreateRunReporteWindow" @close="showCreateRunReporteWindow=false" :current-node-info="rightClickNodeInfo" :parent-node-info="rightClickNodeParentInfo"></createRunReport>
</div>
<Teleport to="body">
<div class="fileMenu" ref="fileMenuRef" :id="'fileMenu' + tableId" @contextmenu.stop="" @contextmenu.prevent="">
@@ -77,11 +80,11 @@
<Operation />
</el-icon>状态修改
</p>
<p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.TASK" @click="showDiaFn('inputParam')">
<!-- <p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.TASK" @click="showDiaFn('inputParam')">
<el-icon>
<SetUp />
</el-icon>输入参数
</p>
</p> -->
<p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.TASK" @click="showDiaFn('focukTask')">
<el-icon>
<StarFilled />
@@ -107,10 +110,16 @@
<Edit />
</el-icon>编辑说明
</p>
<p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.RUN" @click="showDiaFn('shareRun')">
<!-- <p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.RUN" @click="showDiaFn('shareRun')">
<el-icon>
<CopyDocument />
</el-icon>共享算例
</p> -->
<p class="menuButton" v-if="rightClickNodeInfo?.nodeType === NODE_TYPE.RUN" @click="showDiaFn('createReport')">
<el-icon>
<Tickets />
</el-icon>生成报告
</p>
<p class="menuButton" @click="showDiaFn('showPerformance')">
<el-icon>
@@ -160,12 +169,16 @@ import { Folder, Document, ScaleToOriginal } from '@element-plus/icons-vue';
import createRunDiv from './operateComponent/createRunDiv.vue';
import { addTaskRunApi, createRunDirApi, deleteTaskRunApi, getTaskRunTreeApi, queryTaskRunApi } from '@/api/project/run';
import runVersionTreeDiv from './operateComponent/runVersionTreeDiv.vue';
import taskRunPerformance from './operateComponent/taskRunPerformance.vue';
import createRunReport from './operateComponent/createRunReport.vue';
const emits = defineEmits(['nodeClickFn']);
const tableId = ref(new Date().getTime());
const showFileMenu = ref(false);
const showRunCreateOrEditWindow = ref(false);
const showRunVersionTreeWindow = ref(false);
const showTaskRunPerformanceWindow = ref(false);
const showCreateRunReporteWindow = ref(false);
const taskTreeRef = ref();
const defaultExpandKeys = ref<any>([]);
@@ -329,6 +342,7 @@ const nodeChangeClickFn = (data: any, node:any) => {
*/
const rightClickNodeInfo = ref<any>(null);
const rightClickNode = ref<any>(null);
const rightClickNodeParentInfo = ref<any>(null);
// 右键菜单
const rowRightClickFn = (e: any, data: any, node: any) => {
// clearTreeMenuFn();
@@ -337,7 +351,7 @@ const rowRightClickFn = (e: any, data: any, node: any) => {
console.log('1234', node);
rightClickNodeInfo.value = data;
rightClickNode.value = data;
rightClickNodeParentInfo.value = node.parent.data;
if (rightClickNodeInfo.value.nodeType != NODE_TYPE.TASK && rightClickNodeInfo.value.nodeType != NODE_TYPE.RUN) {
return;
}
@@ -394,8 +408,6 @@ const showDiaFn = (flag: string) => {
// 新建算例
case 'createRun':
showRunCreateOrEditWindow.value = true;
console.log(showRunCreateOrEditWindow.value, 'showRunCreateOrEditWindow.value');
break;
// 状态修改
case 'updateTask':
@@ -430,7 +442,7 @@ const showDiaFn = (flag: string) => {
break;
// 查看指标
case 'showPerformance':
showTaskRunPerformanceWindow.value = true;
break;
// 算例版本
@@ -452,6 +464,10 @@ const showDiaFn = (flag: string) => {
case 'delRun':
deleteTaskRunFn();
break;
// 生成报告
case 'createReport':
showCreateRunReporteWindow.value = true;
break;
}
};
@@ -567,9 +583,6 @@ const restoreSelectionFn = () => {
defaultExpandKeys.value = [resetData.id];
taskTreeRef.value.setCurrentKey(resetData.id);
console.log(resetData, 'resetDataresetDataresetDataresetData');
// emits('nodeClickFn', { node: resetData });
}
};

View File

@@ -65,6 +65,7 @@ import Dialog from '@/components/common/dialog/index.vue';
import { NODE_TYPE } from '@/utils/enum/node';
import { ElMessage } from 'element-plus';
import { queryFlowTemplateApi } from '@/api/capability/flow';
import { queryTaskRunApi } from '@/api/project/run';
const props = defineProps({
divInfo: {
@@ -142,8 +143,30 @@ const changeJoinFn = () => {
}
};
watch(() => props.operateFlag, (newVal) => {
const getRunDetailInfoFn = async (id: any, flag:any) => {
const param:any = {
};
if (flag === 'createRun' || flag === 'copyRun') {
param.taskId = id;
} else {
param.runId = id;
}
const res: any = await queryTaskRunApi({
taskId: id,
});
if (res && res.code === 200) {
const length = res.data.length || 1;
return length;
}
};
watch(() => props.operateFlag, async (newVal) => {
if (newVal) {
let version:any = 1;
operateType.value = newVal;
if (newVal === 'createRun') {
pageTitle.value = '创建算例';
@@ -168,22 +191,30 @@ watch(() => props.operateFlag, (newVal) => {
if (newVal === 'editRun') {
pageTitle.value = '编辑算例信息';
}
console.log(props.divInfo, 'props.divInfo');
// 如果是新增算例
if (props.divInfo && props.divInfo?.nodeType === NODE_TYPE.TASK) {
if (runInfoFormData.isJointProjectInfo) {
runInfoFormData.runNames = props.divInfo.nodeName + '_算例V1' ;
}
runInfoFormData.runNames = props.divInfo.nodeName || props.divInfo.runName;
runInfoFormData.templateName = props.divInfo.flowTemplateName;
}
// 如果是新增子算例或者复制算例
if (props.divInfo && props.divInfo?.nodeType === NODE_TYPE.RUN) {
if (runInfoFormData.isJointProjectInfo) {
runInfoFormData.runNames = props.divInfo.runName + '_算例V1';
} else {
version = await getRunDetailInfoFn(props.divInfo.uuid, operateType.value);
// 如果是新增算例
if (props.divInfo && props.divInfo?.nodeType === NODE_TYPE.TASK) {
if (runInfoFormData.isJointProjectInfo) {
runInfoFormData.runNames = props.divInfo.nodeName + '_V' + version ;
}
runInfoFormData.templateName = props.divInfo.flowTemplateName;
}
// 如果是新增子算例或者复制算例
if (props.divInfo && props.divInfo?.nodeType === NODE_TYPE.RUN) {
if (runInfoFormData.isJointProjectInfo) {
runInfoFormData.runNames = props.divInfo.runName + '_V' + version ;
}
runInfoFormData.templateName = props.divInfo.flowTemplateName;
}
runInfoFormData.templateName = props.divInfo.flowTemplateName;
}
}

View File

@@ -0,0 +1,187 @@
<template>
<Dialog
v-model="visible"
diaTitle="生成报告"
:width="'80%'"
:height="'80%'"
:zIndex="100"
@close="handleCloseFn"
>
<div class="report-page">
<div class="form-box">
<el-form :model="reportFormData" inline>
<el-form-item label="报告名称:">
<el-input v-model="reportFormData.reportName"></el-input>
</el-form-item>
<el-form-item >
<el-button type="primary" @click="createSuccessFn">生成</el-button>
<el-button type="">刷新</el-button>
</el-form-item>
</el-form>
</div>
<div class="content-box">
<el-form>
<el-form-item label="图片选择:">
<div class="img-content">
<div class="img-item" v-for="item in resultImgList" :key="item.id">
<el-checkbox v-model="item.checkImg" class="check-style" size="large" />
<el-image
class="img-style"
title="点击预览图片"
:src="item.url"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="[item.url]"
show-progress
:initial-index="4"
fit="cover"
/>
</div>
</div>
</el-form-item>
<el-form-item label="指标选择:">
<taskPerformance ref="taskPerformanceRef" :task-info="currentNodeInfo" :run-info="currentNodeInfo" :param-type="currentNodeInfo?.nodeType"></taskPerformance>
</el-form-item>
</el-form>
</div>
</div>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive, defineProps, defineEmits, onMounted } from 'vue';
import Dialog from '@/components/common/dialog/index.vue';
import dayjs from 'dayjs';
import taskPerformance from '@/components/taskDetail/taskPerformance.vue';
import { generateReportApi, listSimulationKeyResultApi } from '@/api/project/run';
const env = import.meta.env;
const props = defineProps({
currentNodeInfo: {
type: Object,
default: () => {},
},
parentNodeInfo: {
type: Object,
default: () => {},
},
});
const emits = defineEmits(['close']);
const visible = ref(true);
const taskPerformanceRef = ref();
const reportFormData = reactive<any>({
reportName: '',
});
const handleCloseFn = () => {
emits('close');
};
const createSuccessFn = async () => {
console.log(props.currentNodeInfo);
const performanceList = taskPerformanceRef.value.baseTableRef.tableRef.getCheckboxRecords();
const chcekImgs = resultImgList.value.filter((item:any) => {
return item.checkImg;
});
const imageFileIdList = chcekImgs.map((item:any) => {
return item.fileId;
});
console.log(performanceList, 'performanceList');
console.log(imageFileIdList, 'imageFileIdList');
const taskInfo = props.parentNodeInfo;
delete taskInfo.children;
const parentNodeInfoList = [taskInfo];
const res:any = await generateReportApi({
performanceList,
imageFileIdList,
parentNodeInfoList,
});
};
const resultImgList = ref<any>([]);
const queryDirDataFn = async () => {
const res: any = await listSimulationKeyResultApi({
keyResultType: '1',
runId: props.currentNodeInfo?.uuid,
current: 1,
size: 999,
});
if (res && res.code === 200) {
resultImgList.value = res.data.data.map((item:any) => {
return {
...item,
url: `${env.VITE_API_IMAGE_PREVIEW_URL}/data/previewImage?fileId=${item.fileId}`,
};
});
}
};
onMounted(async () => {
await queryDirDataFn();
reportFormData.reportName = '算例报告_' + dayjs().format('YYYY_MM_DD_HH_mm');
});
</script>
<style lang="scss" scoped>
.report-page{
width: 100%;
height: 100%;
min-height: 500px;
.form-box{
width: 100%;
height: 50px;
}
.content-box{
.img-content{
width: 100%;
min-height: 200px;
padding: 5px;
display: flex;
flex-wrap: wrap;
.img-item{
width: 150px;
height: 150px;
margin-right: 20px;
margin-bottom: 20px;
position: relative;
box-sizing: content-box;
border: 1px dashed var(--el-color-primary);
.check-style{
position: absolute;
top: 0px;
left: 5px;
}
.img-style{
width: 150px;
height: 150px;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,63 @@
<template>
<Dialog
v-model="visible"
diaTitle="指标详情"
:width="'80%'"
:height="'80%'"
:zIndex="100"
@close="handleCloseFn"
show-footer
>
<div class="performance-page">
<taskPerformance ref="taskPerformanceRef" :task-info="currentNodeInfo" :run-info="currentNodeInfo" :param-type="currentNodeInfo?.nodeType"></taskPerformance>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCloseFn">取消</el-button>
<el-button type="primary" @click="createSuccessFn">确认</el-button>
</span>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, defineProps, defineEmits } from 'vue';
import taskPerformance from '@/components/taskDetail/taskPerformance.vue';
import Dialog from '@/components/common/dialog/index.vue';
const props = defineProps({
currentNodeInfo: {
type: Object,
default: () => {},
},
});
const emits = defineEmits(['close']);
const visible = ref(true);
const taskPerformanceRef = ref();
const handleCloseFn = () => {
emits('close');
};
const createSuccessFn = async () => {
console.log(props.currentNodeInfo);
await taskPerformanceRef.value.saveFn();
emits('close');
};
</script>
<style lang="scss" scoped>
.performance-page{
width: 100%;
height: 100%;
min-height: 500px;
}
</style>

View File

@@ -40,7 +40,7 @@
</template>
<script setup lang="ts">
import { queryRunDirApi, listSimulationKeyResult, addSimulationKeyResultApi, deleteSimulationKeyResultApi } from '@/api/project/run';
import { queryRunDirApi, listSimulationKeyResultApi, addSimulationKeyResultApi, deleteSimulationKeyResultApi } from '@/api/project/run';
import { ref, defineProps, watch, nextTick, onMounted } from 'vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import { ElMessage } from 'element-plus';
@@ -78,7 +78,7 @@ const getRunInfoDirsFn = async () => {
if (res && res.code === 200) {
runDirs.value = res.data?.data.filter((item:any) => {
return item.dataType === 1;
return item.dataType === 1 && ['图片结果', '曲线结果', '报告结果'].includes(item.originalName);
}) || [];
runDirNameList.value = runDirs.value.map((item: any) => {
return { name: item.originalName, id: item.id };
@@ -95,7 +95,7 @@ const getRunInfoDirsFn = async () => {
};
const queryDirDataFn = async (param: any) => {
const res: any = await listSimulationKeyResult({
const res: any = await listSimulationKeyResultApi({
...param,
});
if (res && res.code === 200) {

View File

@@ -13,8 +13,8 @@
</el-icon>
</div>
<div class="right-content">
<taskDetailPage v-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.TASK && showPage" :task-info="treeCurrentNodeInfo"></taskDetailPage>
<runDetailPage v-else-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.RUN && showPage" :run-info="treeCurrentNodeInfo"></runDetailPage>
<taskDetailPage v-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.TASK " :task-info="treeCurrentNodeInfo"></taskDetailPage>
<runDetailPage v-else-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.RUN " :run-info="treeCurrentNodeInfo"></runDetailPage>
<el-empty v-else class="empty-style" description="" />
</div>
</div>
@@ -23,27 +23,26 @@
</template>
<script setup lang="ts">
import { ref, defineProps, defineEmits } from 'vue';
import { ref, defineProps, defineEmits, nextTick } from 'vue';
import { NODE_TYPE } from '@/utils/enum/node';
import leftTaskTree from './components/leftTaskTree/index.vue';
import taskDetailPage from './components/taskDetailPage/index.vue';
import runDetailPage from './components/runDetailPage/index.vue';
const isToggleShow = ref(true);
const showPage = ref(true);
const toggleFun = () => {
isToggleShow.value = !isToggleShow.value;
};
const treeCurrentNodeInfo = ref<any>(null);
const getTreeCurrentNodeFn = (data: any) => {
showPage.value = false;
// treeCurrentNodeInfo.value = {};
console.log(data, 'datadatadata');
treeCurrentNodeInfo.value = {};
const { node }: any = data;
treeCurrentNodeInfo.value = node;
showPage.value = true;
setTimeout(() => {
const { node }: any = data;
treeCurrentNodeInfo.value = node;
}, 1000);
};