feat: 仿真策划审批
This commit is contained in:
@@ -100,6 +100,10 @@ watch(
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
defineExpose({ rollBackValue });
|
const getNodeInfo = () => {
|
||||||
|
return nodeLevel2ListOptions.value?.find((item: any) => item.value === nodeUuid.value)?.info;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ rollBackValue, getNodeInfo });
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,6 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="approval-page">
|
<div class="full">
|
||||||
<div class="approval-page-content">
|
<div class="header">
|
||||||
|
<div class="label">{{ $t('仿真策划.仿真策划') }}</div>
|
||||||
|
<div class="info-group">
|
||||||
|
<div v-if="projectName" class="info-item">
|
||||||
|
<span class="info-label">{{ $t('仿真策划.项目名称') }}:</span>
|
||||||
|
<span class="info-value">{{ projectName }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="projectCode" class="info-item">
|
||||||
|
<span class="info-label">{{ $t('仿真策划.项目编号') }}:</span>
|
||||||
|
<span class="info-value">{{ projectCode }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="phaseName" class="info-item">
|
||||||
|
<span class="info-label">{{ $t('仿真策划.阶段') }}:</span>
|
||||||
|
<span class="info-value">{{ phaseName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="legend-tooltip">
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color added"></span>
|
||||||
|
<span class="legend-label">{{ $t('通用.新增') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color updated"></span>
|
||||||
|
<span class="legend-label">{{ $t('通用.编辑') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="legend-item">
|
||||||
|
<span class="legend-color deleted"></span>
|
||||||
|
<span class="legend-label">{{ $t('通用.删除') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
<loadCaseTable
|
<loadCaseTable
|
||||||
:editMode="false"
|
:editMode="false"
|
||||||
ref="treeTableRef"
|
ref="treeTableRef"
|
||||||
@@ -17,101 +48,300 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from 'vue';
|
import { nextTick, onMounted, ref, watchEffect } from 'vue';
|
||||||
import loadCaseTable from '@/components/common/treeCaseTable/loadCaseTable.vue';
|
import loadCaseTable from '@/components/common/treeCaseTable/loadCaseTable.vue';
|
||||||
import { getTaskTreeFun } from '@/views/task/projectDetail/components/projectApi';
|
import type { VxeTablePropTypes } from 'vxe-table';
|
||||||
|
|
||||||
const props = defineProps({
|
interface Props {
|
||||||
pageData: {
|
pageData: any;
|
||||||
type: Object,
|
}
|
||||||
default: () => {},
|
|
||||||
},
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
pageData: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
enum PreviewAction {
|
||||||
|
Added = 'added',
|
||||||
|
Updated = 'updated',
|
||||||
|
Deleted = 'deleted',
|
||||||
|
}
|
||||||
|
|
||||||
|
const projectName = ref('');
|
||||||
|
const projectCode = ref('');
|
||||||
|
const phaseName = ref('');
|
||||||
|
const approveContents = ref<any>(null);
|
||||||
const mergedPreviewTree = ref<any>([]);
|
const mergedPreviewTree = ref<any>([]);
|
||||||
const addUuids = ref<any>([]);
|
|
||||||
const delUuids = ref<any>([]);
|
|
||||||
const editUuids = ref<any>([]);
|
|
||||||
const isCreatePool = ref(false);
|
|
||||||
// 获取审批内容
|
|
||||||
const getapprovalCOntentFun = async (data: any) => {
|
|
||||||
const approveContents = JSON.parse(data?.approveContents as string);
|
|
||||||
|
|
||||||
const { phaseNodeId, projectNodeId, deleteNodeList, editNodeList, addNodeList } = approveContents;
|
const buildMapById = (list: any[] = []) => {
|
||||||
|
const map: Record<string, any> = {};
|
||||||
getUUids(deleteNodeList, delUuids.value);
|
const walk = (nodes: any[]) => {
|
||||||
getUUids(editNodeList, editUuids.value);
|
(nodes || []).forEach((n) => {
|
||||||
getUUids(addNodeList, addUuids.value);
|
if (n?.fakeId) map[n.fakeId] = n;
|
||||||
|
if (n.children) walk(n.children);
|
||||||
const treeData = await getTaskTreeFun(projectNodeId, phaseNodeId);
|
});
|
||||||
|
};
|
||||||
if (treeData.length) {
|
walk(list);
|
||||||
mergedPreviewTree.value = treeData;
|
return map;
|
||||||
isCreatePool.value = false;
|
|
||||||
} else {
|
|
||||||
mergedPreviewTree.value = addNodeList;
|
|
||||||
isCreatePool.value = true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getUUids = (list: any, arr: any) => {
|
const cloneNode = (node: any) => JSON.parse(JSON.stringify(node));
|
||||||
for (let i = 0; i < list.length; i++) {
|
|
||||||
if (list[i].uuid) {
|
const collectDeletedNodes = (original: any[] = [], removeIds: string[] = []) => {
|
||||||
arr.push(list[i].uuid);
|
const origMap = buildMapById(original);
|
||||||
|
const parentMap: Record<string, string | null> = {};
|
||||||
|
const childrenOrder: Record<string, string[]> = {};
|
||||||
|
const rootOrder: string[] = [];
|
||||||
|
|
||||||
|
const walk = (nodes: any[], parentId: string | null) => {
|
||||||
|
(nodes || []).forEach((n: any) => {
|
||||||
|
if (!n || !n.fakeId) return;
|
||||||
|
const id = n.fakeId;
|
||||||
|
if (parentId === null) rootOrder.push(id);
|
||||||
|
parentMap[id] = parentId;
|
||||||
|
childrenOrder[id] = (n.children || []).map((c: any) => c.fakeId).filter(Boolean);
|
||||||
|
if (n.children) walk(n.children, id);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
walk(original, null);
|
||||||
|
|
||||||
|
const removedSet = new Set(removeIds.filter(Boolean));
|
||||||
|
const topRemoved = Array.from(removedSet).filter((id) => {
|
||||||
|
let p = parentMap[id];
|
||||||
|
while (p) {
|
||||||
|
if (removedSet.has(p)) return false;
|
||||||
|
p = parentMap[p];
|
||||||
}
|
}
|
||||||
if (list[i].nodeId) {
|
return true;
|
||||||
arr.push(list[i].nodeId);
|
});
|
||||||
}
|
|
||||||
if (list[i]?.children?.length) {
|
const cloneAndMark = (node: any) => {
|
||||||
getUUids(list[i]?.children, arr);
|
const n = cloneNode(node);
|
||||||
}
|
const markRec = (x: any) => {
|
||||||
}
|
if (!x) return;
|
||||||
|
delete x._X_ROW_KEY;
|
||||||
|
delete x._X_ROW_CHILD;
|
||||||
|
x._previewAction = PreviewAction.Deleted;
|
||||||
|
if (x.children) x.children.forEach((c: any) => markRec(c));
|
||||||
|
};
|
||||||
|
markRec(n);
|
||||||
|
return n;
|
||||||
|
};
|
||||||
|
|
||||||
|
const entries: { node: any; parentId: string | null; rootIndex: number; siblingIndex: number }[] =
|
||||||
|
[];
|
||||||
|
topRemoved.forEach((id) => {
|
||||||
|
const node = origMap[id];
|
||||||
|
if (!node) return;
|
||||||
|
const parentId = parentMap[id] ?? null;
|
||||||
|
const rootIndex = rootOrder.indexOf(id);
|
||||||
|
const siblingIndex = parentId ? (childrenOrder[parentId] || []).indexOf(id) : rootIndex;
|
||||||
|
entries.push({ node: cloneAndMark(node), parentId, rootIndex, siblingIndex });
|
||||||
|
});
|
||||||
|
|
||||||
|
entries.sort((a, b) => {
|
||||||
|
const ai = a.rootIndex >= 0 ? a.rootIndex : 0;
|
||||||
|
const bi = b.rootIndex >= 0 ? b.rootIndex : 0;
|
||||||
|
return ai - bi;
|
||||||
|
});
|
||||||
|
|
||||||
|
return { entries, rootOrder, childrenOrder };
|
||||||
};
|
};
|
||||||
|
|
||||||
const rowClassName: any = ({ row }: any) => {
|
const rowClassName: VxeTablePropTypes.RowClassName<any> = ({ row }) => {
|
||||||
if (!row) return '';
|
if (!row) return '';
|
||||||
if (isCreatePool.value) {
|
if (row._previewAction === PreviewAction.Added) {
|
||||||
return 'preview-added';
|
return 'preview-added';
|
||||||
}
|
} else if (row._previewAction === PreviewAction.Updated) {
|
||||||
if (addUuids.value.includes(row.uuid) || addUuids.value.includes(row.nodeId)) {
|
|
||||||
return 'preview-added';
|
|
||||||
} else if (editUuids.value.includes(row.uuid) || editUuids.value.includes(row.nodeId)) {
|
|
||||||
return 'preview-updated';
|
return 'preview-updated';
|
||||||
} else if (delUuids.value.includes(row.uuid) || delUuids.value.includes(row.nodeId)) {
|
} else if (row._previewAction === PreviewAction.Deleted) {
|
||||||
return 'preview-deleted';
|
return 'preview-deleted';
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
const initPreviewData = () => {
|
||||||
|
mergedPreviewTree.value = [];
|
||||||
|
approveContents.value = JSON.parse(props.pageData?.approveContents || '{}');
|
||||||
|
const approvePreviewInfo = approveContents.value?.approvePreviewInfo || {};
|
||||||
|
|
||||||
|
projectName.value = approvePreviewInfo.projectName || '';
|
||||||
|
projectCode.value = approvePreviewInfo.projectCode || '';
|
||||||
|
phaseName.value = approvePreviewInfo.phaseName || '';
|
||||||
|
|
||||||
|
const finalFullData = approvePreviewInfo.finalFullData || [];
|
||||||
|
const originalFullData = approvePreviewInfo.originalFullData || [];
|
||||||
|
const insertRecords = approvePreviewInfo.insertRecords || [];
|
||||||
|
const updateRecords = approvePreviewInfo.updateRecords || [];
|
||||||
|
const removeRecords = approvePreviewInfo.removeRecords || [];
|
||||||
|
const previewData = cloneNode(finalFullData);
|
||||||
|
|
||||||
|
const markTree = (nodes: any[]) => {
|
||||||
|
(nodes || []).forEach((n) => {
|
||||||
|
delete n._X_ROW_KEY;
|
||||||
|
delete n._X_ROW_CHILD;
|
||||||
|
if (!n) return;
|
||||||
|
if ((insertRecords || []).some((x: any) => x.fakeId === n.fakeId)) {
|
||||||
|
n._previewAction = PreviewAction.Added;
|
||||||
|
} else if ((updateRecords || []).some((x: any) => x.fakeId === n.fakeId)) {
|
||||||
|
n._previewAction = PreviewAction.Updated;
|
||||||
|
}
|
||||||
|
if (n.children) markTree(n.children);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
markTree(previewData);
|
||||||
|
|
||||||
|
const removeIds = (removeRecords || []).map((r: any) => r.fakeId || r);
|
||||||
|
const {
|
||||||
|
entries: deletedEntries,
|
||||||
|
rootOrder,
|
||||||
|
childrenOrder,
|
||||||
|
} = collectDeletedNodes(originalFullData, removeIds);
|
||||||
|
|
||||||
|
const findNodeRef = (nodes: any[], id: string): any | null => {
|
||||||
|
for (const n of nodes || []) {
|
||||||
|
if (!n) continue;
|
||||||
|
if (n.fakeId === id) return n;
|
||||||
|
if (n.children) {
|
||||||
|
const r = findNodeRef(n.children, id);
|
||||||
|
if (r) return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const existsInPreview = (id: string) => !!findNodeRef(previewData, id);
|
||||||
|
|
||||||
|
deletedEntries.forEach(({ node, parentId, rootIndex, siblingIndex }) => {
|
||||||
|
if (!node || !node.fakeId) return;
|
||||||
|
if (existsInPreview(node.fakeId)) return;
|
||||||
|
|
||||||
|
if (parentId && existsInPreview(parentId)) {
|
||||||
|
const parentRef = findNodeRef(previewData, parentId);
|
||||||
|
if (!parentRef.children) parentRef.children = [];
|
||||||
|
const origSiblings = childrenOrder[parentId] || [];
|
||||||
|
const beforeOrig = origSiblings.slice(0, Math.max(0, siblingIndex));
|
||||||
|
const insertPos = beforeOrig.reduce((cnt, sid) => {
|
||||||
|
return cnt + (parentRef.children.some((c: any) => c.fakeId === sid) ? 1 : 0);
|
||||||
|
}, 0);
|
||||||
|
parentRef.children.splice(insertPos, 0, node);
|
||||||
|
} else {
|
||||||
|
const beforeRoots = rootOrder.slice(0, Math.max(0, rootIndex));
|
||||||
|
const insertPos = beforeRoots.reduce((cnt, rid) => {
|
||||||
|
return cnt + (previewData.some((n: any) => n.fakeId === rid) ? 1 : 0);
|
||||||
|
}, 0);
|
||||||
|
previewData.splice(insertPos, 0, node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mergedPreviewTree.value = previewData;
|
||||||
|
expandAllFun();
|
||||||
|
};
|
||||||
|
|
||||||
|
const treeTableRef = ref();
|
||||||
|
const getVxeRef = () => {
|
||||||
|
return treeTableRef?.value?.loadcaseTableRef?.TreeTableRef?.treeTableRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
const expandAllFun = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
getVxeRef()?.setAllTreeExpand(true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
if (props.pageData) {
|
if (props.pageData) {
|
||||||
getapprovalCOntentFun(props.pageData);
|
initPreviewData();
|
||||||
console.log(props.pageData, 'props.pageData');
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if (props.pageData) {
|
||||||
|
initPreviewData();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.approval-page {
|
.full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #fff;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.approval-page-tooltips {
|
.header {
|
||||||
width: 100%;
|
height: 20px;
|
||||||
height: 40px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-group {
|
||||||
|
margin-left: var(--padding-small);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: row;
|
||||||
justify-content: flex-end;
|
gap: 20px;
|
||||||
}
|
|
||||||
|
|
||||||
.approval-page-content {
|
.info-item {
|
||||||
width: 100%;
|
display: flex;
|
||||||
// height: calc(100% - 40px);
|
align-items: center;
|
||||||
height: 100%;
|
}
|
||||||
|
|
||||||
|
.info-label {
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-value {
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.preview-added) {
|
||||||
|
background-color: var(--el-color-success-light-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.preview-updated) {
|
||||||
|
background-color: var(--el-color-primary-light-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.preview-deleted) {
|
||||||
|
background-color: var(--el-color-danger-light-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-tooltip {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
flex: 1;
|
||||||
|
margin-left: auto;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-color {
|
||||||
|
width: 24px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 2px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.legend-color.added {
|
.legend-color.added {
|
||||||
background-color: var(--el-color-success-light-7);
|
background-color: var(--el-color-success-light-7);
|
||||||
}
|
}
|
||||||
@@ -123,4 +353,9 @@ onMounted(async () => {
|
|||||||
.legend-color.deleted {
|
.legend-color.deleted {
|
||||||
background-color: var(--el-color-danger-light-7);
|
background-color: var(--el-color-danger-light-7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.legend-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--el-text-color-secondary);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -343,6 +343,7 @@ const props = defineProps<{
|
|||||||
}>();
|
}>();
|
||||||
const dialogApproveUserVisible = ref(false);
|
const dialogApproveUserVisible = ref(false);
|
||||||
const isEmptyPool = ref(true);
|
const isEmptyPool = ref(true);
|
||||||
|
let originalSnapshot: any = null;
|
||||||
|
|
||||||
const dialogVisible = computed(() => {
|
const dialogVisible = computed(() => {
|
||||||
return props.showTaskDialog;
|
return props.showTaskDialog;
|
||||||
@@ -427,8 +428,14 @@ const getNodeLevel3TreeByLevel2Uuid = async () => {
|
|||||||
rightTableLoading.value = true;
|
rightTableLoading.value = true;
|
||||||
rightTableData.value = await getTaskTreeFun(props.nodeLevel1Uuid, nodeLevel2Uuid.value);
|
rightTableData.value = await getTaskTreeFun(props.nodeLevel1Uuid, nodeLevel2Uuid.value);
|
||||||
rightTableLoading.value = false;
|
rightTableLoading.value = false;
|
||||||
|
nextTick(() => {
|
||||||
|
originalSnapshot = cloneDeep(rightTableData.value);
|
||||||
|
});
|
||||||
|
isEmptyPool.value = !rightTableData.value || rightTableData.value.length === 0;
|
||||||
} else {
|
} else {
|
||||||
rightTableData.value = [];
|
rightTableData.value = [];
|
||||||
|
originalSnapshot = null;
|
||||||
|
isEmptyPool.value = true;
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 待修改
|
// 待修改
|
||||||
@@ -812,6 +819,7 @@ const addOrEditTaskFun = async () => {
|
|||||||
// } else {
|
// } else {
|
||||||
approveParam.value = {
|
approveParam.value = {
|
||||||
insertTreeList,
|
insertTreeList,
|
||||||
|
insertRecords: insertList,
|
||||||
removeRecords,
|
removeRecords,
|
||||||
updateList,
|
updateList,
|
||||||
};
|
};
|
||||||
@@ -853,6 +861,25 @@ const onAddApproveConfirmFun = async (formData: any) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { fullData } = getRightVxeRef()?.getTableData() || { fullData: [] };
|
||||||
|
const columns = getRightVxeRef()?.getColumns() || [];
|
||||||
|
|
||||||
|
const currentPhaseInfo = nodeLevel2SelectRef.value?.getNodeInfo();
|
||||||
|
|
||||||
|
const approvePreviewInfo = {
|
||||||
|
isCreate: isEmptyPool.value,
|
||||||
|
isUpdate: !isEmptyPool.value,
|
||||||
|
columns,
|
||||||
|
originalFullData: cloneDeep(originalSnapshot),
|
||||||
|
finalFullData: cloneDeep(fullData),
|
||||||
|
insertRecords: approveParam.value.insertRecords,
|
||||||
|
updateRecords: approveParam.value.updateList,
|
||||||
|
removeRecords: approveParam.value.removeRecords,
|
||||||
|
projectName: props.nodeLevel1Name,
|
||||||
|
projectCode: props.nodeLevel1Info?.nodeCode,
|
||||||
|
phaseName: currentPhaseInfo?.nodeName || '',
|
||||||
|
};
|
||||||
|
|
||||||
const param = {
|
const param = {
|
||||||
addNodeList: approveParam.value.insertTreeList,
|
addNodeList: approveParam.value.insertTreeList,
|
||||||
editNodeList: approveParam.value.updateList,
|
editNodeList: approveParam.value.updateList,
|
||||||
@@ -861,6 +888,7 @@ const onAddApproveConfirmFun = async (formData: any) => {
|
|||||||
tagMap: getTagMapList(),
|
tagMap: getTagMapList(),
|
||||||
projectNodeId: props.nodeLevel1Uuid,
|
projectNodeId: props.nodeLevel1Uuid,
|
||||||
phaseNodeId: nodeLevel2Uuid.value,
|
phaseNodeId: nodeLevel2Uuid.value,
|
||||||
|
approvePreviewInfo,
|
||||||
...formData,
|
...formData,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1277,12 +1305,7 @@ const queryDesignVersionsFun = async () => {
|
|||||||
|
|
||||||
if (res.data?.length) {
|
if (res.data?.length) {
|
||||||
projectPhaseVersionList.value = [res.data.at(-1)];
|
projectPhaseVersionList.value = [res.data.at(-1)];
|
||||||
|
|
||||||
currentProjectPhaseTaskTreeVersion.value = projectPhaseVersionList.value[0]?.currentVersion;
|
currentProjectPhaseTaskTreeVersion.value = projectPhaseVersionList.value[0]?.currentVersion;
|
||||||
|
|
||||||
isEmptyPool.value = false;
|
|
||||||
} else {
|
|
||||||
isEmptyPool.value = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|||||||
Reference in New Issue
Block a user