Compare commits

..

2 Commits

Author SHA1 Message Date
c212f628c5 fix: 🐛 不能在computed里修改data 2025-04-01 12:15:39 +08:00
53f887d0d6 fix: 🐛 管理员按钮错误消失 2025-04-01 12:15:13 +08:00
2 changed files with 116 additions and 48 deletions

View File

@ -50,7 +50,7 @@ router.beforeEach(async (to, from, next) => {
if (!userState.token && storageToken) restoreToken(storageToken); if (!userState.token && storageToken) restoreToken(storageToken);
// 4. Vuex 有 token,但还没有动态路由,获取用户资源, 生成动态路由 // 4. Vuex 有 token,但还没有动态路由,获取用户资源, 生成动态路由
if (userState.token && dynamicRoutes.length === 0) loadRoutes(userState.isAdmin, next); if (userState.token && dynamicRoutes.length === 0) loadRoutes(userState, next);
// 5. 放行 // 5. 放行
next(); next();
@ -88,13 +88,13 @@ function restoreToken(token) {
} }
/** 生成并加载动态路由 */ /** 生成并加载动态路由 */
async function loadRoutes(isAdmin, next) { async function loadRoutes(userState, next) {
try { try {
await store.dispatch('user/getUserInfo')
const routesResource = await store.dispatch("user/getRoutesResource"); const routesResource = await store.dispatch("user/getRoutesResource");
dynamicRoutes = generateIndexRouter(routesResource); dynamicRoutes = generateIndexRouter(routesResource);
router.addRoutes(dynamicRoutes); router.addRoutes(dynamicRoutes);
if (userState.isAdmin) {
if (isAdmin) {
router.addRoutes([systemSettings]); router.addRoutes([systemSettings]);
} }
} catch (err) { } catch (err) {

View File

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