merge
This commit is contained in:
@@ -240,7 +240,7 @@ import { formOptionsFormat } from './lib';
|
||||
import { uniqBy, cloneDeep } from 'lodash-es';
|
||||
import { exportFile } from '@/utils/file';
|
||||
import HeadSearch from './treeHeadSearch.vue';
|
||||
import { traverseTree } from '@/utils/node';
|
||||
import { flatNode, traverseTree } from '@/utils/node';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const emit = defineEmits([
|
||||
@@ -290,7 +290,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
editMode: false,
|
||||
listTitle: '',
|
||||
actionList: [],
|
||||
showExpandSelect: false, // 默认显示展开级别下拉框
|
||||
showExpandSelect: true, // 默认显示展开级别下拉框
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const checkMethod: any = inject('checkMethod', () => {
|
||||
@@ -326,7 +326,6 @@ const expandOptions = computed(() => {
|
||||
for (let i = 1; i <= maxTreeLevel.value; i++) {
|
||||
options.push({ label: t('表格.显示级', { level: i }), value: String(i) });
|
||||
}
|
||||
options.push();
|
||||
return options;
|
||||
});
|
||||
|
||||
@@ -393,15 +392,15 @@ const calcMaxLevelFun = () => {
|
||||
if (!vxeTableRef.value) {
|
||||
return;
|
||||
}
|
||||
const treeData = vxeTableRef.value.getTableData().fullData;
|
||||
if (!treeData || treeData.length === 0) {
|
||||
const { fullData } = vxeTableRef.value.getTableData();
|
||||
if (!fullData || fullData.length === 0) {
|
||||
maxTreeLevel.value = 1;
|
||||
return;
|
||||
}
|
||||
let maxLevel = 1;
|
||||
const levelMap = new Map<any, number>();
|
||||
traverseTree(
|
||||
treeData,
|
||||
fullData,
|
||||
(node: any, parent: any) => {
|
||||
const level = parent ? (levelMap.get(parent) || 1) + 1 : 1;
|
||||
levelMap.set(node, level);
|
||||
@@ -423,48 +422,46 @@ const expandVisibleChangeFun = (visible: boolean) => {
|
||||
}
|
||||
};
|
||||
|
||||
const collectRowsToExpand = (data: any[], targetLevel: number) => {
|
||||
const rowsToExpand: any[] = [];
|
||||
const levelMap = new Map<any, number>();
|
||||
if (!Array.isArray(data) || !targetLevel) {
|
||||
return rowsToExpand;
|
||||
}
|
||||
traverseTree(
|
||||
data,
|
||||
(node: any, parent: any) => {
|
||||
const nodeLevel = parent ? (levelMap.get(parent) || 1) + 1 : 1;
|
||||
levelMap.set(node, nodeLevel);
|
||||
if (nodeLevel < targetLevel) {
|
||||
rowsToExpand.push(node);
|
||||
}
|
||||
},
|
||||
null
|
||||
);
|
||||
return rowsToExpand;
|
||||
};
|
||||
const expandLevelFun = (level: string) => {
|
||||
if (!vxeTableRef.value) {
|
||||
return;
|
||||
}
|
||||
expandLevel.value = level;
|
||||
const { fullData = [], visibleData = [] } = vxeTableRef.value.getTableData();
|
||||
const flattedVisibleData = flatNode(visibleData);
|
||||
if (level === 'all') {
|
||||
vxeTableRef.value.setAllTreeExpand(true);
|
||||
vxeTableRef.value.setTreeExpand(flattedVisibleData, true);
|
||||
} else if (level === 'collapse') {
|
||||
vxeTableRef.value.setAllTreeExpand(false);
|
||||
vxeTableRef.value.setTreeExpand(flattedVisibleData, false);
|
||||
} else {
|
||||
const targetLevel = parseInt(level, 10);
|
||||
const treeData = vxeTableRef.value.getTableData().fullData;
|
||||
const levelMap = new Map<any, number>();
|
||||
const rowsToExpand: any[] = [];
|
||||
traverseTree(
|
||||
treeData,
|
||||
(node: any, parent: any) => {
|
||||
const nodeLevel = parent ? (levelMap.get(parent) || 1) + 1 : 1;
|
||||
levelMap.set(node, nodeLevel);
|
||||
if (nodeLevel < targetLevel) {
|
||||
rowsToExpand.push(node);
|
||||
}
|
||||
},
|
||||
null
|
||||
);
|
||||
vxeTableRef.value.setAllTreeExpand(false);
|
||||
const rowsToExpand = collectRowsToExpand(fullData, targetLevel);
|
||||
vxeTableRef.value.setTreeExpand(flattedVisibleData, false);
|
||||
nextTick(() => {
|
||||
vxeTableRef.value.setTreeExpand(rowsToExpand, true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const checkDataChangeFun = () => {
|
||||
if (!vxeTableRef.value) {
|
||||
return;
|
||||
}
|
||||
calcMaxLevelFun();
|
||||
nextTick(() => {
|
||||
expandLevelFun(expandLevel.value);
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.params,
|
||||
(val: any) => {
|
||||
|
||||
@@ -136,6 +136,8 @@ watch(
|
||||
standard.value = formData.value.standard;
|
||||
if (formData.value.flowTemplate) {
|
||||
selectedFlowTemplate.value = formData.value.flowTemplate;
|
||||
} else {
|
||||
selectedFlowTemplate.value = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
:disabled-date="(time: Date) => disabledDate(time, row, 'beginTime')"
|
||||
/>
|
||||
</template>
|
||||
<!-- 计划结束时间 -->
|
||||
@@ -189,6 +190,7 @@
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
clearable
|
||||
:disabled-date="(time: Date) => disabledDate(time, row, 'endTime')"
|
||||
/>
|
||||
</template>
|
||||
<!-- 军令状时间 -->
|
||||
@@ -595,6 +597,22 @@ const onNodeNameChangeFun = (row: any, val: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const disabledDate = (time: Date, row: any, flag: string) => {
|
||||
if (flag === 'beginTime') {
|
||||
if (row.endTime) {
|
||||
return time.getTime() > new Date(row.endTime).getTime();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (row.beginTime) {
|
||||
return time.getTime() < new Date(row.beginTime).getTime();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initProjectDicts();
|
||||
taskStore.fetchTemplates();
|
||||
|
||||
@@ -94,17 +94,16 @@ const initFun = (data: any) => {
|
||||
if (uploading.value) {
|
||||
return;
|
||||
}
|
||||
const isSaveLocal = data.data?.isSaveLocal || 'N';
|
||||
listData.value.some((item: any, index: number) => {
|
||||
if (item.data.status === '0') {
|
||||
sliceFileFun(index, isSaveLocal);
|
||||
sliceFileFun(index);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 分片并上传
|
||||
const sliceFileFun = async (fileIndex: number, isSaveLocal?: any) => {
|
||||
const sliceFileFun = async (fileIndex: number) => {
|
||||
uploading.value = true;
|
||||
const fileObj = listData.value[fileIndex];
|
||||
const file = fileObj.file;
|
||||
@@ -124,7 +123,7 @@ const sliceFileFun = async (fileIndex: number, isSaveLocal?: any) => {
|
||||
chunk: chunkIndex + 1,
|
||||
chunkTotal: totalChunks,
|
||||
file: chunkFile,
|
||||
isSaveLocal,
|
||||
isSaveLocal: fileData.isSaveLocal,
|
||||
};
|
||||
if (fileTempPath) {
|
||||
params.fileTempPath = fileTempPath;
|
||||
|
||||
@@ -362,6 +362,7 @@ const runUploadRunFilesFun = async (list: any) => {
|
||||
|
||||
if (res && res.code === 200) {
|
||||
res.data.forEach((item: any, index: any) => {
|
||||
item.isSaveLocal = 'Y';
|
||||
emitter.emit('ADD_UPLOAD_FILE', {
|
||||
file: list[index].raw,
|
||||
data: {
|
||||
@@ -369,7 +370,6 @@ const runUploadRunFilesFun = async (list: any) => {
|
||||
...item,
|
||||
isApprove: 0, // 0否 1是
|
||||
taskType: 4, // 4交付物
|
||||
isSaveLocal: 'Y',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -92,6 +92,7 @@ import { CommonStore } from '@/stores/common';
|
||||
// import dayjs from 'dayjs';
|
||||
import { getTagMapList } from '@/utils/task';
|
||||
import TableForm from '@/components/common/table/tableForm.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const props = defineProps<{
|
||||
showNodeInfoDialog: boolean;
|
||||
@@ -100,6 +101,9 @@ const props = defineProps<{
|
||||
projectBeginTime?: string;
|
||||
projectEndTime?: string;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const emits = defineEmits([
|
||||
'update:showNodeInfoDialog',
|
||||
'nextPageFun',
|
||||
@@ -124,6 +128,8 @@ const actionList = ref([
|
||||
{
|
||||
title: '删除',
|
||||
type: 'danger',
|
||||
needConfirm: true,
|
||||
confirmTip: t('通用.确认删除吗'),
|
||||
click: (row: any) => {
|
||||
disposeDeleteListFun(row);
|
||||
},
|
||||
|
||||
@@ -541,7 +541,7 @@ const getUserGroupTaskCompleteStatistics = async () => {
|
||||
res.data?.allExeStatus?.map((item: any) => {
|
||||
return TASK_PROCESS_STATUS_OBJ[item];
|
||||
}) || [];
|
||||
|
||||
console.log(legendData, 'legendData');
|
||||
seriesData = legendData?.map((item: any) => {
|
||||
return {
|
||||
name: item,
|
||||
@@ -556,16 +556,28 @@ const getUserGroupTaskCompleteStatistics = async () => {
|
||||
},
|
||||
};
|
||||
});
|
||||
res.data?.result?.forEach((item: any) => {
|
||||
xData.push(item.userName);
|
||||
for (const key in item.statusCount) {
|
||||
seriesData?.forEach((seriesItem: any) => {
|
||||
if (seriesItem.name === TASK_PROCESS_STATUS_OBJ[key]) {
|
||||
seriesItem.data.push(item.statusCount[key]);
|
||||
if (res.data?.result) {
|
||||
res.data.result.forEach((item: any) => {
|
||||
if (item.userName) {
|
||||
xData.push(item.userName);
|
||||
}
|
||||
// 遍历所有状态
|
||||
legendData.forEach((statusName: string) => {
|
||||
// 找到对应的 seriesItem
|
||||
const seriesItem = seriesData.find((item: any) => item.name === statusName);
|
||||
if (seriesItem) {
|
||||
// 获取状态对应的 key
|
||||
const statusKey = Object.keys(TASK_PROCESS_STATUS_OBJ).find(
|
||||
(key) => TASK_PROCESS_STATUS_OBJ[key] === statusName
|
||||
);
|
||||
if (statusKey) {
|
||||
// 如果 statusCount 中有这个状态,使用其值,否则使用 0
|
||||
seriesItem.data.push(item.statusCount?.[statusKey] || '');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
xData,
|
||||
@@ -620,9 +632,8 @@ const userDifficultyCoefficientFormData = reactive<any>({
|
||||
const userDifficultyCoefficientChartRef = ref();
|
||||
const getDifficultyLevel = (difficulty: number) => {
|
||||
const str = DIFFICULTY_COEFFICIENT.value.O[difficulty];
|
||||
return str ? str + ', 系数' : '难度系数';
|
||||
return str ? str : '难度系数';
|
||||
};
|
||||
// console.log(getDifficultyLevel(5), '000000');
|
||||
const initUserDifficultyCoefficientStatistics = async () => {
|
||||
let xData: any = [];
|
||||
// const yData:any = [1, 2, 3, 4];
|
||||
@@ -1276,16 +1287,28 @@ const getProjectGroupTaskCompleteStatistics = async () => {
|
||||
},
|
||||
};
|
||||
});
|
||||
res.data?.result?.forEach((item: any) => {
|
||||
xData.push(item.userName);
|
||||
for (const key in item.statusCount) {
|
||||
seriesData?.forEach((seriesItem: any) => {
|
||||
if (seriesItem.name === TASK_PROCESS_STATUS_OBJ[key]) {
|
||||
seriesItem.data.push(item.statusCount[key]);
|
||||
if (res.data?.result) {
|
||||
res.data.result.forEach((item: any) => {
|
||||
if (item.userName) {
|
||||
xData.push(item.userName);
|
||||
}
|
||||
// 遍历所有状态
|
||||
legendData.forEach((statusName: string) => {
|
||||
// 找到对应的 seriesItem
|
||||
const seriesItem = seriesData.find((item: any) => item.name === statusName);
|
||||
if (seriesItem) {
|
||||
// 获取状态对应的 key
|
||||
const statusKey = Object.keys(TASK_PROCESS_STATUS_OBJ).find(
|
||||
(key) => TASK_PROCESS_STATUS_OBJ[key] === statusName
|
||||
);
|
||||
if (statusKey) {
|
||||
// 如果 statusCount 中有这个状态,使用其值,否则使用 0
|
||||
seriesItem.data.push(item.statusCount?.[statusKey] || '');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return {
|
||||
xData,
|
||||
|
||||
@@ -137,10 +137,9 @@ const openDialog = (type: string, row?: any) => {
|
||||
// nextTick(() => {
|
||||
if (type === 'edit' && row) {
|
||||
row.fileType = String(row.fileType);
|
||||
row.files = [{ name: row.originalName }];
|
||||
row.files = [{ name: row.originalName, id: row.id }];
|
||||
oldFile.value = {
|
||||
id: row.id,
|
||||
uid: row.files[0].uid,
|
||||
};
|
||||
// tableFormRef.value.setFormDataFun(row);
|
||||
editRowInfo.value = { ...row };
|
||||
@@ -231,9 +230,11 @@ const confirmUploadFun = async () => {
|
||||
}
|
||||
});
|
||||
}
|
||||
const oldFileInfo = fromData.files.find((item: any) => item.uid === oldFile.value.uid);
|
||||
if (!oldFileInfo) {
|
||||
dataDelFileApi({ delFileId: oldFile.value.id });
|
||||
if (isEditDialog.value) {
|
||||
const oldFileInfo = fromData.files.find((item: any) => item?.id === oldFile.value.id);
|
||||
if (!oldFileInfo) {
|
||||
dataDelFileApi({ delFileId: oldFile.value.id });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 无文件更新
|
||||
|
||||
@@ -497,7 +497,7 @@ const queryUserTaskCompletion = async () => {
|
||||
// });
|
||||
const getDifficultyLevel = (difficulty: number) => {
|
||||
const str = DIFFICULTY_COEFFICIENT.value.O[difficulty];
|
||||
return str ? str + ', 系数' : '难度系数';
|
||||
return str ? str : '难度系数';
|
||||
};
|
||||
const userDifficultyCoefficientChartRef = ref();
|
||||
const queryUserDifficultStatistics = async () => {
|
||||
|
||||
@@ -419,7 +419,8 @@ const expandTree = (treeRef: any) => {
|
||||
const selectMethod = ref('template'); // template 模板库 project 历史项目
|
||||
|
||||
const transferTask = async () => {
|
||||
if (getLeftVxeRef().getCheckboxRecords().length === 0) {
|
||||
const leftSelection = getLeftVxeRef().getCheckboxRecords();
|
||||
if (leftSelection.length === 0) {
|
||||
ElMessage.warning('请先选择左侧任务节点!');
|
||||
return;
|
||||
}
|
||||
@@ -432,12 +433,27 @@ const transferTask = async () => {
|
||||
|
||||
const rightSelection = getRightVxeRef().getCheckboxRecords();
|
||||
|
||||
if (rightSelection.length === 0) {
|
||||
// console.log('getRightVxeRef().getTableData()', getRightVxeRef().getTableData());
|
||||
const { fullData } = getRightVxeRef().getTableData();
|
||||
for (let index = 0; index < leftSelection.length; index++) {
|
||||
if (
|
||||
fullData.find((item: { nodeName: any }) => {
|
||||
return item.nodeName === leftSelection[index].nodeName;
|
||||
})
|
||||
) {
|
||||
ElMessage.warning('右侧已存在同名节点,如想覆盖,则需勾选右侧相同节点!');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rightSelection.length > 1) {
|
||||
ElMessage.warning('右侧只能选择一个节点进行导入!');
|
||||
return;
|
||||
}
|
||||
|
||||
const leftMultipleSelection = clearLeftSelectRepeat(getLeftVxeRef().getCheckboxRecords());
|
||||
const leftMultipleSelection = clearLeftSelectRepeat(leftSelection);
|
||||
|
||||
const leftInsertArr: any[][] = [];
|
||||
for (let index = 0; index < leftMultipleSelection.length; index++) {
|
||||
@@ -595,7 +611,11 @@ const mergeArrays = async (
|
||||
key !== 'pid' &&
|
||||
key !== '_X_ROW_CHILD'
|
||||
) {
|
||||
updateRow[key] = leftList[index][key];
|
||||
// console.log('leftList', key, leftList[index], leftList[index][key]);
|
||||
// if (updateRow.hasOwnProperty(key)) {
|
||||
if (updateRow.hasOwnProperty(key)) {
|
||||
updateRow[key] = leftList[index][key];
|
||||
}
|
||||
}
|
||||
});
|
||||
await getRightVxeRef().setRow(rightList[foundIndex], newObj);
|
||||
@@ -1069,10 +1089,10 @@ const tableFormChangeFun = (data: any) => {
|
||||
};
|
||||
|
||||
const checkMethod = computed(() => {
|
||||
return ({ row }: any) => {
|
||||
// return row.uuid === 'simu_pool_task_7df6f758-001a-4893-8104-821f6e2a612513130';
|
||||
return !checkChildrenIds.value.includes(row.uuid);
|
||||
};
|
||||
return () => true;
|
||||
// return ({ row }: any) => {
|
||||
// return !checkChildrenIds.value.includes(row.uuid);
|
||||
// };
|
||||
});
|
||||
|
||||
const checkChildrenIds = ref<any>([]);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@change="changeFun"
|
||||
@load="formLoad"
|
||||
v-model:data="editRow"
|
||||
:formAttrs="formAttrs"
|
||||
>
|
||||
</TableForm>
|
||||
<template #footer>
|
||||
@@ -78,6 +79,19 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const formAttrs = ref({
|
||||
progress: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
confidence: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
});
|
||||
|
||||
const taskParams = ref({ type: 0 });
|
||||
|
||||
const exeTableRef = ref();
|
||||
|
||||
@@ -89,6 +89,12 @@ const formAttrs = ref({
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
confidence: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
});
|
||||
|
||||
const taskParams = ref({ type: 3 });
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<template #progress="{ row }"> {{ row.progress || 0 }}% </template>
|
||||
<template #approvalStatus="{ row }">
|
||||
<StatusDot
|
||||
class="clcik-approval"
|
||||
:status="
|
||||
getApproveStyleClass(row.approvalStatus || TASK_APPROVE_STATUS_ENUM.NOT_APPROVED)
|
||||
"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
v-model="filterFprmData.userGroupId"
|
||||
class="mw200"
|
||||
clearable
|
||||
@clear="filterFprmData.userGroupId = ''"
|
||||
@change="filterWorkLoadFun('group')"
|
||||
>
|
||||
<el-option
|
||||
@@ -26,7 +27,7 @@
|
||||
multiple
|
||||
clearable
|
||||
class="mw200"
|
||||
@change="filterWorkLoadFun"
|
||||
@change="userChangeFun"
|
||||
@focus="focusUserFun"
|
||||
>
|
||||
<el-option
|
||||
@@ -105,6 +106,7 @@ import { getListUserWorkloadsApi } from '@/api/project/task';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { ChineseWorkday } from 'chinese-workday';
|
||||
import DetailDia from '@/views/task/workLoad/detailDia.vue';
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
// 维度:工作负载以人person为维度, 人力负载以项目project为维度
|
||||
@@ -124,6 +126,7 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 是否需要展示汇总行
|
||||
showTotal: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -145,7 +148,7 @@ dayjs.extend(isoWeek);
|
||||
|
||||
let Gantt: any = gantt;
|
||||
const ganttEvents = ref<any>([]);
|
||||
const colorList: string[] = ['#ffffff', '#d9ecff', '#c6e2ff', '#c6e2ff', '#79bbff', '#409eff']; // 格子颜色
|
||||
const colorList: string[] = ['#ffffff', '#e9f4ff', '#c6e2ff', '#acd3ff', '#79bbff', '#409eff']; // 格子颜色
|
||||
const taskOriginData = ref<any>([]); // 所有用户的任务数据
|
||||
const loading = ref<boolean>(false);
|
||||
// const workDaysRange = ref<number>(0);
|
||||
@@ -227,13 +230,6 @@ const getWorkLoadDataFun = async () => {
|
||||
...filterFprmData,
|
||||
...props.filterData,
|
||||
};
|
||||
|
||||
if (!filterFprmData.userGroupId) {
|
||||
param.userGroupId = '';
|
||||
}
|
||||
if (!filterFprmData.userIds.length) {
|
||||
param.userIds = [];
|
||||
}
|
||||
// 根据页面类型去掉没用的参数
|
||||
if (props.dimension === 'project') {
|
||||
delete param.userGroupId;
|
||||
@@ -737,7 +733,11 @@ const refreshGanttFun = async () => {
|
||||
initGantt();
|
||||
await getWorkLoadDataFun();
|
||||
};
|
||||
|
||||
// 切换用户
|
||||
const userChangeFun = debounce(async () => {
|
||||
await filterWorkLoadFun();
|
||||
}, 500);
|
||||
// 用户下拉框获取焦点
|
||||
const focusUserFun = () => {
|
||||
if (!filterFprmData.userGroupId) {
|
||||
ElMessage.warning('请选择用户组后再选择用户进行筛选!');
|
||||
|
||||
@@ -52,7 +52,7 @@ const columns = [
|
||||
const fieldMapFun = (data: any) => {
|
||||
const list = data.map((item: any) => {
|
||||
return {
|
||||
userName: item.projectName, // 显示项目名称
|
||||
userName: item.projectName, // 显示项目名称--姓名
|
||||
userId: item.projectId, // 项目ID
|
||||
taskNum: item.taskNum, // 任务数量
|
||||
workNum: item.personNum, // 人员数量
|
||||
|
||||
Reference in New Issue
Block a user