This commit is contained in:
2026-03-17 11:40:54 +08:00
29 changed files with 1447 additions and 165 deletions

View File

@@ -608,6 +608,7 @@ const actionClickFun = (row: any, action: any, index: number) => {
const exportFun = () => {
exportFile(props.exportApi, props.tableName, props.exportFileName, {
...reqParams,
...props.exportParams,
size: null,
current: null,
});

View File

@@ -13,6 +13,7 @@
<slot name="otherLeftOptions"></slot>
<div v-if="!readonly">
<el-button
v-if="props.showAddCategoryButton"
:icon="Plus"
@click="addRowFun(NODE_TYPE.CATEGORY)"
:disabled="addNodeDisabled[NODE_TYPE.CATEGORY]"
@@ -42,120 +43,6 @@
{{ disposeMemberList(row,'pMemberList') }}
</template> -->
</TreeCaseTable>
<!-- <Dialog v-model="modalVisible" destroy-on-close :diaTitle="modalTitle" show-footer :height=" formData.nodeType===NODE_TYPE.TASK? 700 : 'auto'">
<template #default>
<el-form ref="modalFormRef" :model="formData" label-width="auto">
<template v-for="item in formItemList" :key="item.field">
<el-form-item
:label="item.title + ':'"
:prop="item.field"
:rules="
(!item.formConfig?.excludeRequiredType ||
!item.formConfig?.excludeRequiredType.includes(formData.type)) &&
item.formConfig?.rules
? item.formConfig.rules
: []
"
>
<template v-if="item.formConfig?.type === 'textInput'">
<el-input
v-model="formData[item.field]"
:placeholder="`${$t('工况库.请输入')}${item.title}`"
></el-input>
</template>
<template v-if="item.formConfig?.type === 'numberInput'">
<el-input
v-model="formData[item.field]"
:placeholder="`${$t('工况库.请输入')}${item.title}`"
type="number"
:precision="2"
:step="0.1"
@focus="formData[`old_${item.field}`] = formData[item.field]"
@blur="(e:any)=>valueModelInput(e,formData, item)"
></el-input>
</template>
<template v-if="item.formConfig?.type === 'dateSelect'">
<el-date-picker
v-model="formData[item.field]"
type="datetime"
:placeholder="`${$t('工况库.请选择')}${item.title}`"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
class="full-width"
:clearable="false"
:editable="false"
:disabled-date="(time:any)=>item.params?.disabledDate(time,formData,item)"
/>
</template>
<template v-if="item.formConfig?.type === 'select'">
<el-select
v-model="formData[item.field]"
:placeholder="`${$t('工况库.请选择')}${item.title}`"
class="full-width"
@change="selectChange(formData, item)"
:disabled="isFunction(item.formConfig?.disabled) ? item.formConfig?.disabled(formData, operationType) : item.formConfig?.disabled"
:multiple="item.formConfig?.multiple"
:value-key="item.formConfig?.valueKey"
>
<el-option
v-for="(item_2) in getSelectOptionsFun(item, formData)"
:key="item_2.value"
:label="item_2.label"
:value="item_2.value"
/>
</el-select>
</template>
<template v-if="item.formConfig?.type === 'upload_img'">
<div class="upload">
<UploadImg v-model="formData[item.field]" />
</div>
</template>
<template v-if="item.formConfig?.type === 'cascader'">
<el-cascader
v-if="!item.params?.isLazyLoad"
clearable
class="full-width"
v-model="formData[item.field]"
:options="item.formConfig?.options"
:props="{
label: 'name',
value: 'folderName',
emitPath: false,
}"
filterable
:show-all-levels="false"
>
<template #default="{ data }">
<el-icon v-if="data.dataType === 1"><Folder /></el-icon>
<el-icon v-else><Document /></el-icon>
<span class="cascader-label">{{ data.originalName }}</span>
</template>
</el-cascader>
<el-cascader
v-else
clearable
class="full-width"
v-model="formData[item.field]"
:props="item.params?.props"
filterable
:show-all-levels="false"
>
<template #default="{ data }">
<el-icon v-if="data.dataType === 1"><Folder /></el-icon>
<el-icon v-else><Document /></el-icon>
<span class="cascader-label">{{ data.originalName }}</span>
</template>
</el-cascader>
</template>
</el-form-item>
</template>
</el-form>
</template>
<template #footer>
<el-button @click="cancelForm">取消</el-button>
<el-button type="primary" @click="confirmForm">确定</el-button>
</template>
</Dialog> -->
<nodeDetailDialog
v-model="modalVisible"
:modalTableNameList="props.modalTableNameList"
@@ -233,6 +120,8 @@ interface Props {
needTagKey?: boolean; // 是否需要处理tagKey
showNodeCompleteNum?: boolean; // 是否显示节点完成数量
checkMethod?: any; // 处理勾选逻辑
showAddCategoryButton?: boolean; // 是否显示添加分类按钮
allowRootAddTask?: boolean; // 是否允许在根节点添加任务
}
const props = withDefaults(defineProps<Props>(), {
@@ -263,6 +152,8 @@ const props = withDefaults(defineProps<Props>(), {
needTagKey: false,
showNodeCompleteNum: false,
checkMethod: null,
showAddCategoryButton: true,
allowRootAddTask: false,
});
if (props?.checkMethod) {
@@ -522,7 +413,11 @@ const canAddChildFun = (checkRowData: any, nodeType: string) => {
}
let canAdd = true;
if (checkRowData.length === 0) {
canAdd = canAddChild({ nodeType: NODE_TYPE.ROOT }, nodeType);
if (props.allowRootAddTask && nodeType === NODE_TYPE.TASK) {
canAdd = true;
} else {
canAdd = canAddChild({ nodeType: NODE_TYPE.ROOT }, nodeType);
}
} else if (checkRowData.length === 1) {
canAdd = canAddChild(checkRowData[0], nodeType);
} else {

View File

@@ -15,7 +15,7 @@
resultValue: {
step: 0.01,
},
targetValue: {
highValue: {
step: 0.01,
},
}"

View File

@@ -15,7 +15,7 @@
resultValue: {
step: 0.01,
},
targetValue: {
highValue: {
step: 0.01,
},
}"

View File

@@ -221,6 +221,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.PNG_FILE,
};
const runList = await queryTaskRunFun(newVal);
exampleList.value = task.concat(runList);

View File

@@ -191,6 +191,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.REVIEW_FILE,
};
}
},

View File

@@ -203,6 +203,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.MODEL_3D_FILE,
};
}
},

View File

@@ -376,6 +376,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.CANVAS_FILE,
};
}
},

View File

@@ -189,6 +189,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.CALCULATION_FILE,
};
}
},

View File

@@ -137,7 +137,7 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ref, onMounted, watch } from 'vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import { ElMessage } from 'element-plus';
import {
@@ -360,18 +360,18 @@ const getFormConfigureFun = async () => {
title: item.title,
};
});
}
if (props.paramType === 'run') {
excelParams.value = {
runId: props.runInfo.uuid,
taskNodeId: props.runInfo.taskId,
taskId: props.runInfo?.taskId || props.runInfo?.parentId,
};
} else {
excelParams.value = {
taskNodeId: props.taskInfo.uuid,
};
}
if (props.paramType === 'run') {
excelParams.value = {
runId: props.runInfo.uuid,
taskNodeId: props.runInfo.taskId,
taskId: props.runInfo?.taskId || props.runInfo?.parentId,
};
} else {
excelParams.value = {
taskNodeId: props.taskInfo.uuid,
};
}
};
@@ -541,8 +541,22 @@ const inputFileFun = async (data: any) => {
} catch {}
};
// watch(
// () => props.runInfo,
// async (newVal) => {
// if (newVal) {
// await getFormConfigureFun();
// }
// },
// {
// immediate: true,
// deep: true,
// }
// );
onMounted(async () => {
await getTaskPerformanceDataFun();
console.log(1111111111);
await getFormConfigureFun();
});

View File

@@ -196,6 +196,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.REPORT_FILE,
};
}
},

View File

@@ -192,6 +192,9 @@ watch(
taskId: newVal,
taskName: null,
},
fileTypeDictClass: 'ALL_FILE_TYPE',
dictTags: ['fileTypeDictClass', 'fileTypeDictValue'],
fileTypeDictValue: FILE_TYPE.VIDEO_FILE,
};
}
},

View File

@@ -224,7 +224,7 @@ export default [
icon: Icons['Cpu'],
children: [
{
title: '仿真工况库',
title: '仿真地图库',
path: '/competenceCenter/condition',
name: 'CompetenceCenterCondition',
},

View File

@@ -245,7 +245,7 @@ export default [
name: 'CompetenceCenter',
children: [
{
title: '仿真工况库',
title: '仿真地图库',
path: '/competenceCenter/condition',
name: 'CompetenceCenterCondition',
component: () => import('@/views/competenceCenter/condition/index.vue'),

View File

@@ -3,6 +3,7 @@ import { ref, computed } from 'vue';
import { queryFlowTemplateApi } from '@/api/capability/flow';
import { getAllTaskPoolApi, getTaskPoolApi } from '@/api/task/taskpool';
import { FLOW_TEMPLATE_PUBLIC_STATUS, FLOW_USE_STATUS } from '@/utils/enum/flow';
import { filterExcludeStandardScene } from '@/utils/node';
interface Template {
templateName?: string;
@@ -16,16 +17,24 @@ const fetchPoolData = async () => {
if (poolRes.code !== 200 || !Array.isArray(poolRes.data) || poolRes.data.length === 0) {
return { pools: [], versions: [], data: null };
}
const pools = poolRes.data.reverse().map((pool: any) => {
return {
...pool,
versions: (pool.versions || []).reverse().map((v: string) => ({
poolName: pool.poolName,
poolVersion: v,
value: v,
})),
};
});
const pools = poolRes.data
.filter(filterExcludeStandardScene)
.reverse()
.map((pool: any) => {
return {
...pool,
versions: (pool.versions || []).reverse().map((v: string) => ({
poolName: pool.poolName,
poolVersion: v,
value: v,
})),
};
});
if (pools.length === 0) {
return { pools: [], versions: [], data: null };
}
const firstPool = pools[0];
if (!Array.isArray(firstPool.versions) || firstPool.versions.length === 0) {

View File

@@ -230,10 +230,15 @@ export default [
icon: Icons['Cpu'],
children: [
{
title: '仿真工况库',
title: '仿真地图库',
path: '/competenceCenter/condition',
name: 'CompetenceCenterCondition',
},
{
title: '标准场景库',
path: '/competenceCenter/standardScene',
name: 'CompetenceCenterStandardScene',
},
{
title: '仿真指标库',
path: '/competenceCenter/indicator',

View File

@@ -251,11 +251,18 @@ export default [
name: 'CompetenceCenter',
children: [
{
title: '仿真工况库',
title: '仿真地图库',
path: '/competenceCenter/condition',
name: 'CompetenceCenterCondition',
component: () => import('@/views/competenceCenter/condition/index.vue'),
},
{
title: '标准场景库',
path: '/competenceCenter/standardScene',
name: 'CompetenceCenterStandardScene',
component: () =>
import('@/tenants/lyric/views/competenceCenter/standardScene/index.vue'),
},
{
title: '仿真指标库',
path: '/competenceCenter/indicator',

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,7 @@ const lang = {
: 'Create Demand',
: 'Approval Preview',
: 'Simulation Management',
仿: 'Working Condition Library',
仿: 'Condition Map Library',
: 'Standard Scene Library',
仿: 'Indicator Library',
仿: 'Knowledge Base',

View File

@@ -52,7 +52,7 @@ const lang = {
: '首页',
: '审核预览',
: '能力中心',
仿: '仿真工况库',
仿: '仿真地图库',
: '标准场景库',
仿: '仿真指标库',
仿: '仿真标准库',

View File

@@ -443,17 +443,17 @@ export const collectNodeCodes = (nodes: TreeNode[], excludeFakeId?: string): str
return codes;
};
export const FIXED_POOL_NAME = '标准场景库';
export const STANDARD_SCENE_POOL_NAME = '标准场景库';
export const VIRTUAL_NODE_NAME = '__VIRTUAL_ROOT__';
export const VIRTUAL_NODE_CODE = '__VIRTUAL__';
export const filterExcludeStandardScene = (pool: any): boolean => {
return pool.poolName !== FIXED_POOL_NAME;
return pool.poolName !== STANDARD_SCENE_POOL_NAME;
};
export const filterOnlyStandardScene = (pool: any): boolean => {
return pool.poolName === FIXED_POOL_NAME;
return pool.poolName === STANDARD_SCENE_POOL_NAME;
};
export const filterVirtualNode = (tree: any[]): any[] => {

View File

@@ -57,10 +57,12 @@ import type { Pool } from './types.ts';
interface Props {
modelValue: boolean;
filterFn?: (pool: Pool) => boolean;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
filterFn: undefined,
});
const emits = defineEmits(['update:modelValue', 'confirm']);
@@ -87,7 +89,13 @@ const queryListFun = async () => {
const req = { bCurrent: false };
const res: any = await getAllTaskPoolApi(req);
if (res.code === 200 && Array.isArray(res.data)) {
poolList.value = res.data.reverse();
let list = res.data.reverse();
if (props.filterFn) {
list = list.filter(props.filterFn);
}
poolList.value = list;
} else {
poolList.value = [];
}

View File

@@ -199,7 +199,11 @@
detail="{}"
@confirm="onAddPoolConfirmFun"
/>
<DelPoolModal v-model="delPoolModalVisible" @confirm="onDelPoolConfirmFun" />
<DelPoolModal
v-model="delPoolModalVisible"
:filterFn="filterExcludeStandardScene"
@confirm="onDelPoolConfirmFun"
/>
<ImportPoolModal
v-model="importPoolModalVisible"
:poolList="poolList"
@@ -224,6 +228,7 @@ import {
getNodeExtras,
canAddChild,
extractLeafNodesWithParentTypes,
filterExcludeStandardScene,
} from '@/utils/node';
import { poolNodeExtraPropPickMap } from '@/utils/enum/node';
import {
@@ -1033,6 +1038,8 @@ const dict = computed(() => ({
department: commonStore.getDictData('DEPARTMENT_LIST').A,
section: commonStore.getDictData('SECTION_LIST').A,
group: commonStore.getDictData('GROUP_LIST').A,
sceneType: commonStore.getDictData('SCENE_TYPE').A,
algorithm: commonStore.getDictData('SIMULATION_ALGORITHM').A,
}));
const getFilterColumnsFun = async () => {
const res: any = await getFormConfigureApi({ formName: 'TASK_POOL' });

View File

@@ -19,10 +19,10 @@
/>
</template>
</el-checkbox-group>
<el-button v-if="false" @click="exportPdfFun">{{ $t('通用.导出PDF') }}</el-button>
<el-button @click="exportPdfFun">{{ $t('通用.导出PDF') }}</el-button>
</div>
<el-space v-else class="top-toolbar">
<el-button v-if="false" @click="exportPdfFun">{{ $t('通用.导出PDF') }}</el-button>
<el-button @click="exportPdfFun">{{ $t('通用.导出PDF') }}</el-button>
</el-space>
<div

View File

@@ -1,7 +1,7 @@
<template>
<Dialog v-model="diaVisible" diaTitle="数据分析" width="90%" height="90%" @close="closeFun">
<div class="analysis-container">
<div class="analysis-header" v-if="false">
<div class="analysis-header">
<el-button @click="exportPdfFun">{{ $t('通用.导出PDF') }}</el-button>
</div>
<div class="analysis-wrap" ref="analysisRef">

View File

@@ -84,7 +84,7 @@
:zIndex="100"
>
<div class="compare-wrapper">
<div class="compare-header" v-if="false">
<div class="compare-header">
<el-button @click="exportCurvePdfFun">{{ $t('通用.导出PDF') }}</el-button>
</div>
<div class="compare-container compare-flex-item" ref="curveCompareRef">
@@ -153,7 +153,7 @@
:zIndex="100"
>
<div class="compare-wrapper">
<div class="compare-header" v-if="false">
<div class="compare-header">
<el-button @click="exportCloudPdfFun">{{ $t('通用.导出PDF') }}</el-button>
</div>
<div class="compare-container compare-flex-item" ref="cloudCompareRef">

View File

@@ -12,6 +12,7 @@
<div class="dir-content" v-if="currentDirName === 'performance'">
<taskPerformance
v-if="currentDirName === 'performance'"
:full-height="true"
:show-save-button="true"
:param-type="'run'"
@@ -523,7 +524,7 @@ const baseTableRef = ref();
const tableFormRef = ref();
const visible = ref(false);
const runInfo = ref<any>({});
const currentDirName = ref<any>();
const currentDirName = ref<any>('');
const currentFileInfo = ref<any>({});
const diaPngVisible = ref(false);
const columnPngData = ref<number>(1);
@@ -619,7 +620,6 @@ const runResultDirChangeFun = () => {
accept.value = '.csv';
fileType.value = FILE_TYPE.CANVAS_FILE;
formData.fileType = [`${FILE_TYPE.CANVAS_FILE}`];
tableShow.value = true;
}
if (name === '报告结果') {

View File

@@ -330,7 +330,13 @@
<script lang="ts" setup>
import Dialog from '@/components/common/dialog/index.vue';
import { computed, nextTick, onMounted, ref } from 'vue';
import { canAddChild, transformPoolNodesToTree, flatNode } from '@/utils/node';
import {
canAddChild,
transformPoolNodesToTree,
flatNode,
STANDARD_SCENE_POOL_NAME,
filterVirtualNode,
} from '@/utils/node';
import { ElMessage, ElMessageBox } from 'element-plus';
import { cloneDeep } from 'lodash-es';
import { v4 as uuidv4 } from 'uuid';
@@ -1163,7 +1169,13 @@ const queryTaskPoolFun = async () => {
};
const res: any = await getTaskPoolApi(req);
if (res.code === 200 && res.data.poolBrief && res.data && res.data.nodes) {
leftPoolTableDataList.value = transformPoolNodesToTree(res.data.nodes);
let tree = transformPoolNodesToTree(res.data.nodes);
if (currentLoadcaseLib.value.poolName === STANDARD_SCENE_POOL_NAME) {
tree = filterVirtualNode(tree);
}
leftPoolTableDataList.value = tree;
nextTick(() => {
// 待修改
// leftPoolTableRef.value?.changeLevel('全部展开');
@@ -1220,6 +1232,8 @@ const uploadExcelFileFun = async (file: any) => {
department: commonStore.getDictData('DEPARTMENT_LIST').A,
section: commonStore.getDictData('SECTION_LIST').A,
group: commonStore.getDictData('GROUP_LIST').A,
sceneType: commonStore.getDictData('SCENE_TYPE').A,
algorithm: commonStore.getDictData('SIMULATION_ALGORITHM').A,
};
const req = {
poolName: '外部临时表单',

View File

@@ -93,12 +93,21 @@
</template>
</BaseTable>
<attachments :demandId="demandInfo.uuid" v-model:visible="attachmentsVisible"></attachments>
<TaskListDialog
<!-- <TaskListDialog
v-model:showDialog="showTaskListDialog"
:demandUid="demandInfo.uuid"
:projectUid="demandInfo.projectUid"
:phaseUid="demandInfo.phaseUid"
></TaskListDialog>
></TaskListDialog> -->
<taskDetail
v-if="showTaskDetailDialog"
:taskId="currentTaskInfo.id"
:currentTaskInfo="currentTaskInfo"
@closeFn="showTaskDetailDialog = false"
:show-footer="false"
:showLeftOptions="true"
>
</taskDetail>
</template>
<script setup lang="ts">
@@ -116,7 +125,13 @@ import { setDemandSearchOptions } from '../taskPage';
import { exportDemandApi } from '@/api/project/demand';
import StatusDot from '@/components/common/statusDot/index.vue';
import { demandStatus, getTaskAchieveStyleClass } from '@/components/common/statusDot/statusMap';
import TaskListDialog from './taskListDialog.vue';
// import TaskListDialog from './taskListDialog.vue';
import { getIdMap } from '../../projectDetail/components/project';
import { getSeeDisciplines } from '@/tenants/lyric/views/task/lyricTask';
import { getTagMapList } from '@/utils/task';
import { getTaskListByDemandIdApi } from '@/api/project/task';
import taskDetail from '@/views/task/projectDetail/components/taskDetail.vue';
import { ElMessage } from 'element-plus';
const props = defineProps({
params: {
@@ -219,13 +234,37 @@ const tableOnLoadFun = () => {
setDemandSearchOptions(tableRef.value);
};
const showTaskListDialog = ref(false);
// const showTaskListDialog = ref(false);
const showTaskDetailDialog = ref(false);
const currentTaskInfo = ref({ id: '', uuid: '' });
const showTaskListDialogFun = (row: any) => {
demandInfo.uuid = row.uuid;
demandInfo.projectUid = row.projectId;
demandInfo.phaseUid = row.phaseId;
showTaskListDialog.value = true;
// showTaskListDialog.value = true;
// 获取需求下的任务,再打开任务详情弹窗
const params = {
demandId: demandInfo.uuid,
type: 2,
idMap: getIdMap(demandInfo.projectUid, demandInfo.phaseUid),
filterDiscipline: getSeeDisciplines(),
sortOrder: 1,
nodeTypeMap: getTagMapList(),
size: 10,
current: 1,
};
getTaskListByDemandIdApi(params).then((res) => {
if (res.code === 200) {
const data = res.data?.data || [];
if (data.length > 0) {
showTaskDetailDialog.value = true;
currentTaskInfo.value = data[0];
} else {
ElMessage.warning('当前需求下没有任务');
}
}
});
};
const nameClickFun = (row: any) => {