diff --git a/src/index/views/resourcesOverview/Profile.vue b/src/index/views/resourcesOverview/Profile.vue index 918a0e3..aaef247 100644 --- a/src/index/views/resourcesOverview/Profile.vue +++ b/src/index/views/resourcesOverview/Profile.vue @@ -166,7 +166,10 @@ export default { workHourStatistics: {} }, quarterData: {}, - idChildrenMap: {} + teamTreeData: { + options: [], + idChildrenMap: {} + } }; }, computed:{ @@ -190,10 +193,8 @@ export default { // return res return moment(this.quarterStartTime).subtract(1, 'quarters').valueOf(); }, - options(){ - const idChildrenMap = {}; - const options = this.listToTreeData(this.teamList,{id:0},'parentTeamId',idChildrenMap); - return options; + options() { + return this.teamTreeData.options; } }, watch:{ @@ -202,8 +203,11 @@ export default { // this.getTeamList(); this.getTeamOverview(); }, - teamList(){ - this.idChildrenMap = {} + teamList: { + immediate: true, + handler(newTeamList) { + this.updateTeamTree(newTeamList); + } } }, created(){ @@ -216,32 +220,80 @@ export default { ...mapActions({ getTeamList: 'teamResource/getTeamList', }), - listToTreeData(list, parent, pid, map) { - const res = [] - map[parent.id]=[] - parent.visible = false - if(parent.teamType===0){ - parent.visible = true - map[parent.id].push({id: parent.id, teamName:parent.teamName }) - }else{ - list.forEach(item => { - if (item[pid] === parent.id) { - // 对于找出来的子节点, 都要再找它的下一级 - // 把当前的item.id 作为下一层的 pid - const children = this.listToTreeData(list, item, pid, map) - // 什么时候停止, 找不到下一级的时候停止 - if (children.length > 0) { - item.children = children - } - if(item.visible){ - parent.visible = true - res.push(item) - map[parent.id].push({id: item.id, teamName:item.teamName }) - } + /** + * 将扁平的团队列表转换为树形结构 + * @param {Array} list - 原始团队列表数据 + */ + updateTeamTree(list) { + // 第一步:构建父子关系映射表 + // key: 父团队ID,value: 该父团队下的所有子团队数组 + const parentChildMap = {}; + // key: 团队ID,value: 该团队下可选的直接子团队列表(用于级联选择器) + const idChildrenMap = {}; + + // 遍历团队列表,建立父子关系映射 + list.forEach(item => { + // 如果没有父团队ID,则默认为0(根节点) + const pid = item.parentTeamId || 0; + // 初始化父团队的子团队数组 + if (!parentChildMap[pid]) { + parentChildMap[pid] = []; + } + // 将当前团队添加到其父团队的子团队数组中 + parentChildMap[pid].push(item); + }); + + /** + * 递归构建树形结构 + * @param {number} parentId - 父团队ID + * @returns {Array} - 返回构建好的树形结构数组 + */ + const buildTree = (parentId = 0) => { + // 获取当前父节点下的所有子节点 + const children = parentChildMap[parentId] || []; + // 初始化当前父节点的可选子团队列表 + idChildrenMap[parentId] = []; + + // 使用reduce构建树形结构,acc为累加器 + return children.reduce((acc, node) => { + // 处理叶子节点(团队类型为0表示具体团队,不是部门) + if (node.teamType === 0) { + // 将叶子节点添加到可选子团队列表中 + idChildrenMap[parentId].push({ + id: node.id, + teamName: node.teamName + }); + // 将叶子节点添加到树形结构中 + acc.push(node); + return acc; } - }) - } - return res + + // 处理非叶子节点(部门节点) + // 递归处理当前节点的子节点 + const subTree = buildTree(node.id); + // 只有当子树不为空时,才添加该节点 + if (subTree.length > 0) { + // 设置子节点 + node.children = subTree; + // 将当前节点添加到树形结构中 + acc.push(node); + // 将当前节点添加到可选子团队列表中 + idChildrenMap[parentId].push({ + id: node.id, + teamName: node.teamName + }); + } + return acc; + }, []); + }; + + // 更新组件的数据 + // options: 用于级联选择器的树形结构数据 + // idChildrenMap: 用于快速查找某个团队下的直接子团队 + this.teamTreeData = { + options: buildTree(), + idChildrenMap + }; }, async getQuarterStatistics(){ const { data } = await getQuarterStatistics({ @@ -252,17 +304,28 @@ export default { this.quarterData = data; } }, - async getTeamOverview(teamId){ - // const { quarterStartTime, quarterEndTime } = quarter2Timestamp(this.quarter); - // const lastQuarterStartTime = moment(quarterStartTime).subtract(1, 'quarters').valueOf(); - // const aQuarterAgo = moment(quarterStartTime).subtract(1, 'quarters').valueOf(); - // const { quarterStartTime:lastQuarterStartTime, quarterEndTime:lastQuarterEndTime } = quarter2Timestamp(timestamp2Quarter(aQuarterAgo)); - const { data } = await getTeamOverview({ lastQuarterStartTime: this.lastQuarterStartTime, quarterStartTime: this.quarterStartTime, teamId }); - if(data){ - // this.teamProfiles = data; - const ids = data.map(team=>team.teamId); - const needFillChildren = this.idChildrenMap[teamId??0].filter(child=>!ids.includes(child.id)); - const filledChildren = needFillChildren.map(child=>({ + async getTeamOverview(teamId) { + const { data } = await getTeamOverview({ + lastQuarterStartTime: this.lastQuarterStartTime, + quarterStartTime: this.quarterStartTime, + teamId + }); + + if(data) { + // 获取当前选中团队的ID,如果未选中则使用0(根节点) + const currentTeamId = teamId ?? 0; + + // 确保 idChildrenMap 中存在对应的团队数据 + const teamChildren = this.teamTreeData.idChildrenMap[currentTeamId] || []; + + // 获取已有数据的团队ID列表 + const ids = data.map(team => team.teamId); + + // 找出需要补充的子团队 + const needFillChildren = teamChildren.filter(child => !ids.includes(child.id)); + + // 为没有数据的子团队创建默认数据结构 + const filledChildren = needFillChildren.map(child => ({ teamType: 0, disabled: true, teamId: child.id, @@ -278,7 +341,12 @@ export default { deliveredStoryCompareLast: null, projectCurrentQuarter: [] })); - this.teamProfiles = [ ...data, ...filledChildren ]; + + // 合并现有数据和补充数据 + this.teamProfiles = [...data, ...filledChildren]; + } else { + // 如果没有数据,清空显示 + this.teamProfiles = []; } }, async getYearStatistics(){