批量分发优化

This commit is contained in:
weibl
2025-12-02 17:00:07 +08:00
parent 26abf5f76f
commit b441be9bdf

View File

@@ -9,6 +9,7 @@
show-footer
>
<BaseTable
:loading="loadingInterface"
ref="tableRef"
showIndex
:headData="headData"
@@ -16,87 +17,103 @@
tableName="BATCH_SEND_TASK"
:searchLimitNum="3"
>
<template #leftOptions>
<template #insertLevel="{ row }">
<div class="last-insert-node">
<span class="required-tag" v-if="row.insertMode === 'lib'">*</span>
<el-tree-select
:ref="
(el: any) => {
if (el) taskTreeRefs[row.uuid] = el;
}
"
filterable
:check-strictly="true"
v-model="row.insertIndex"
:data="row.indexTreeData"
node-key="uuid"
:props="{ label: 'nodeName', value: 'uuid' }"
default-expand-all
:render-after-expand="false"
>
<template #default="{ data: { nodeName } }">
{{ nodeName }}
</template>
</el-tree-select>
</div>
</template>
<template #insertLevel="{row}">
<el-tree-select
:ref="(el:any) => {if(el) taskTreeRefs[row.uuid] = el}"
filterable
:check-strictly="true"
v-model="row.insertIndex"
:data="row.indexTreeData"
node-key="uuid"
:props="{label:'nodeName',value:'uuid'}"
default-expand-all
:render-after-expand="false"
>
<template #default="{ data: { nodeName } }">
{{ nodeName }}
</template>
</el-tree-select>
</template>
<template #insertMode="{row}">
<el-radio-group v-model="row.insertMode" >
<template #insertMode="{ row }">
<el-radio-group v-model="row.insertMode">
<el-radio value="lib" size="large">从工况库选任务</el-radio>
<el-radio value="custom" size="large">自定义创建任务</el-radio>
</el-radio-group>
</template>
<template #libName="{row}">
<template #libName="{ row }">
<el-select
class="loadcase-lib"
:teleported="false"
v-model='row.currentLoadcaseLib'
:props="{label:'poolName', value:'value'}"
v-model="row.currentLoadcaseLib"
:props="{ label: 'poolName', value: 'value' }"
value-key="poolName"
:fit-input-width="true"
@change="(lib:any) => {changeLoadcaseLibFun(lib,row)}"
@change="
(lib: any) => {
changeLoadcaseLibFun(lib, row);
}
"
>
<el-option v-for="item in loadcaseLibList" :key="item.value" :label="item.poolName" :value="item" />
<el-option
v-for="item in loadcaseLibList"
:key="item.value"
:label="item.poolName"
:value="item"
/>
</el-select>
</template>
<template #libVersion="{row}">
<template #libVersion="{ row }">
<el-select
class="version"
:teleported="false"
v-model='row.currentLoadcaseLibVersion'
:props="{label:'poolVersion', value:'value'}"
v-model="row.currentLoadcaseLibVersion"
:props="{ label: 'poolVersion', value: 'value' }"
value-key="poolVersion"
:fit-input-width="true"
@change="changeLoadcaseVersionFun(row)"
>
<el-option v-for="item in row.loadcaseLibVersionList" :key="item.value" :label="item.poolVersion" :value="item" />
<el-option
v-for="item in row.loadcaseLibVersionList"
:key="item.value"
:label="item.poolVersion"
:value="item"
/>
</el-select>
</template>
<template #selectTask="{row}">
<template #selectTask="{ row }">
<div class="line-content">
<span class="required-tag" v-if="row.insertMode === 'lib'">*</span>
<el-select-v2
v-model="row.chooseTaskList"
:options="libTaskList"
:options="row.libTaskList"
placeholder="请选择"
filterable
clearable
value-key="uuid"
collapse-tags
:multiple="true"
>
<template #default="{ item }">
<div class="flex items-center">
<img class="loadcase-img" src="@/assets/imgs/projectTree/loadcase.png" alt="">
<span>{{ item.label }}</span>
<img class="loadcase-img" src="@/assets/imgs/projectTree/loadcase.png" alt="" />
<span :title="item.label">{{ item.label }}</span>
</div>
</template>
</el-select-v2>
</div>
</template>
<template #taskName="{row}">
<template #taskName="{ row }">
<div class="line-content">
<span class="required-tag" v-if="row.insertMode === 'custom'">*</span>
<el-input v-model="row.taskName"></el-input>
</div>
</template>
<template #planTime="{row}">
<template #planTime="{ row }">
<div class="line-content">
<span class="required-tag">*</span>
<el-date-picker
@@ -108,13 +125,10 @@
/>
</div>
</template>
<template #eMemberList="{row}">
<template #eMemberList="{ row }">
<div class="line-content">
<span class="required-tag">*</span>
<UserSelect
v-model="row.eMemberList"
:multiple="true"
/>
<UserSelect v-model="row.eMemberList" :multiple="true" />
</div>
</template>
<!-- <template #tableActions="{row}">
@@ -128,13 +142,16 @@
</div>
</template>
</Dialog>
</template>
<script lang='ts' setup>
<script lang="ts" setup>
import { computed, nextTick, onMounted, ref } from 'vue';
import Dialog from '@/components/common/dialog/index.vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import { getAllTaskPoolApi, getTaskPoolLoadcasesApi, getTaskPoolVersionsApi } from '@/api/task/taskpool';
import {
getAllTaskPoolApi,
getTaskPoolLoadcasesApi,
getTaskPoolVersionsApi,
} from '@/api/task/taskpool';
import UserSelect from '@/components/common/userSelect/index.vue';
import { ElMessage } from 'element-plus';
import { getTaskTreeFun } from '@/views/task/projectDetail/components/projectApi';
@@ -158,33 +175,100 @@ const emits = defineEmits(['update:diaVisible']);
const tableRef = ref();
const diaVisible = computed({
get () {
get() {
return props.diaVisible;
},
set (val) {
set(val) {
emits('update:diaVisible', val);
},
});
// BATCH_SEND_TASK
const headData = ref<any[]>([
{ title: '需求名称', key: 'demandName', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '上层节点', key: 'insertLevel', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '插入模式', key: 'insertMode', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '库名称', key: 'libName', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '库版本', key: 'libVersion', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '选择工况', key: 'selectTask', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '计划时间', key: 'planTime', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{ title: '仿真执行人', key: 'eMemberList', isShow: true, inputMode: 'input', type: 1, inForm: false, required: true },
{
title: '需求名称',
key: 'demandName',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '上层节点',
key: 'insertLevel',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '插入模式',
key: 'insertMode',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '库名称',
key: 'libName',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '库版本',
key: 'libVersion',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '选择工况',
key: 'selectTask',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '计划时间',
key: 'planTime',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
{
title: '仿真执行人',
key: 'eMemberList',
isShow: true,
inputMode: 'input',
type: 1,
inForm: false,
required: true,
},
]);
const loadingInterface = ref(false);
const taskTreeRefs = ref<any[]>([]);
const confirmFun = async() => {
const confirmFun = async () => {
console.log('tableRef.value.tableData', tableRef.value.tableData);
console.log('taskTreeRef', taskTreeRefs.value);
for (let index = 0; index < tableRef.value.tableData.length; index++) {
const item = tableRef.value.tableData[index];
if (!item.insertIndex) {
return ElMessage.warning('需求名为 ' + item.demandName + ' 的上层节点不能为空!');
}
if (item.insertMode === 'lib' && item.chooseTaskList?.length === 0) {
return ElMessage.warning('需求名为 ' + item.demandName + ' 的选择工况不能为空!');
}
@@ -194,20 +278,23 @@ const confirmFun = async() => {
if (item.eMemberList.length === 0) {
return ElMessage.warning('需求名为 ' + item.demandName + ' 的仿真执行人不能为空!');
}
if (item.planTime.length === 2 && (!item.planTime[0] || !item.planTime[1])) {
return ElMessage.warning('需求名为 ' + item.demandName + ' 的仿计划时间不能为空!');
}
}
loadingInterface.value = true;
const params = [];
for (let index = 0; index < tableRef.value.tableData.length; index++) {
const demandItem = tableRef.value.tableData[index];
const parentNodeInfo = taskTreeRefs.value[demandItem.uuid].getCurrentNode();
const tagProperty:{[key: string]: any;} = {};
tagSortList.forEach((item:any) => {
const tagProperty: { [key: string]: any } = {};
tagSortList.forEach((item: any) => {
tagProperty[item] = parentNodeInfo[item] ? parentNodeInfo[item].split(',') : [];
});
const idMap = getIdMap(demandItem.projectId, demandItem.phaseId);
const pMemberListStr = getMemberListIds(demandItem.pMemberList);
if (demandItem.insertMode === 'lib') {
const addTaskList = demandItem.chooseTaskList.map((task:any) => {
const addTaskList = demandItem.chooseTaskList.map((task: any) => {
return {
...task,
...tagProperty,
@@ -224,22 +311,24 @@ const confirmFun = async() => {
});
} else {
params.push({
addNodeList: [{
nodeName: demandItem.taskName,
...tagProperty,
beginTime: demandItem.beginTime,
endTime: demandItem.endTime,
eMemberList: demandItem.eMemberList,
pMemberList: pMemberListStr,
nodeId: parentNodeInfo.uuid,
}],
addNodeList: [
{
nodeName: demandItem.taskName,
...tagProperty,
beginTime: demandItem.beginTime,
endTime: demandItem.endTime,
eMemberList: demandItem.eMemberList,
pMemberList: pMemberListStr,
nodeId: parentNodeInfo.uuid,
},
],
demandId: demandItem.uuid,
idMap: idMap,
});
}
}
console.log('params', params);
const res:any = await issuedTaskApi({ reqList: params });
const res: any = await issuedTaskApi({ reqList: params });
if (res.code === 200) {
ElMessage.success('批量任务分发成功!');
closeFun();
@@ -255,12 +344,15 @@ const closeFun = () => {
const loadcaseLibList = ref<any[]>([]);
const changeLoadcaseLibFun = (lib:any, row:any) => {
const changeLoadcaseLibFun = (lib: any, row: any) => {
row.currentLoadcaseLib = lib;
queryLoadcaseLibVersionsFun(row);
};
const changeLoadcaseVersionFun = (row: { currentLoadcaseLib: { poolName: any; }; currentLoadcaseLibVersion: { poolVersion: any; }; }) => {
const changeLoadcaseVersionFun = (row: {
currentLoadcaseLib: { poolName: any };
currentLoadcaseLibVersion: { poolVersion: any };
}) => {
getLoadcaseList(row);
};
@@ -272,14 +364,16 @@ const queryPoolListFun = async () => {
loadcaseLibList.value = [];
}
if (loadcaseLibList.value.length > 0) {
props.checkedList.forEach(async (item:any) => {
item.indexTreeData = await getIndexTreeData(item);
item.currentLoadcaseLib = loadcaseLibList.value[0];
queryLoadcaseLibVersionsFun(item);
});
for (let index = 0; index < props.checkedList.length; index++) {
(props.checkedList[index] as any).indexTreeData = await getIndexTreeData(
props.checkedList[index]
);
(props.checkedList[index] as any).currentLoadcaseLib = loadcaseLibList.value[0];
queryLoadcaseLibVersionsFun(props.checkedList[index]);
}
}
};
const getIndexTreeData = async(info:any) => {
const getIndexTreeData = async (info: any) => {
const taskTree = await getTaskTreeFun(info.projectId, info.phaseId);
console.log('filterTask(taskTree)', filterTask(taskTree));
return filterTask(taskTree);
@@ -289,7 +383,7 @@ const queryLoadcaseLibVersionsFun = async (row: any) => {
const req = {
poolName: row.currentLoadcaseLib.poolName,
};
const res:any = await getTaskPoolVersionsApi(req);
const res: any = await getTaskPoolVersionsApi(req);
if (res.code === 200 && res.data && Array.isArray(res.data) && res.data.length > 0) {
row.loadcaseLibVersionList = res.data;
if (row.loadcaseLibVersionList.length > 0) {
@@ -302,48 +396,46 @@ const queryLoadcaseLibVersionsFun = async (row: any) => {
getLoadcaseList(row);
};
const libTaskList = ref<any[]>([]);
const getLoadcaseList = async (row:any) => {
const getLoadcaseList = async (row: any) => {
const res: any = await getTaskPoolLoadcasesApi({
poolName: row.currentLoadcaseLib.poolName,
version: row.currentLoadcaseLibVersion.poolVersion,
});
if (res.code === 200) {
libTaskList.value = res.data.map((item:any) => {
row.libTaskList = res.data.map((item: any) => {
return {
label: item.nodeName,
value: item,
};
})
;
});
}
};
onMounted(async() => {
onMounted(async () => {
loadingInterface.value = true;
await queryPoolListFun();
loadingInterface.value = false;
setTimeout(() => {
nextTick(() => {
tableRef.value.setDataFun(props.checkedList.map((item:any) => {
return {
...item,
insertMode: 'lib',
taskName: item.demandName,
chooseTaskList: [],
eMemberList: getMemberListIds(item.eMemberList),
planTime: [item.beginTime, item.endTime],
};
}));
tableRef.value.setDataFun(
props.checkedList.map((item: any) => {
return {
...item,
insertMode: 'lib',
taskName: item.demandName,
chooseTaskList: [],
eMemberList: getMemberListIds(item.eMemberList),
planTime: [item.beginTime, item.endTime],
};
})
);
console.log('tableRef', tableRef.value, props.checkedList);
});
}, 500);
});
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.line-content {
display: flex;
align-items: center;
@@ -351,6 +443,16 @@ onMounted(async() => {
.required-tag {
color: #ff4d4f; /* 红色 */
font-weight: bold;
margin:0 4px;
// margin: 0 4px;
// margin-right: var(--margin-tiny);
}
.loadcase-img {
width: 16px;
vertical-align: middle;
margin-right: var(--margin-tiny);
}
.last-insert-node {
width: 100%;
padding: 0 var(--padding-small);
}
</style>