更新缓存和文件分类
This commit is contained in:
parent
873a2e297a
commit
f4244c09b9
@ -103,23 +103,62 @@ const activeBgColor = computed(() => {
|
||||
|
||||
// 将后端数据转换为前端需要的格式
|
||||
const transformMenuData = (menus) => {
|
||||
// 功能页面路径关键词,这些菜单不应该显示在侧边栏
|
||||
const functionPageKeywords = ['/detail', '/add', '/edit', '/delete', '/create', '/update', '/category', '/tag'];
|
||||
if (!menus || menus.length === 0) {
|
||||
console.warn('菜单数据为空');
|
||||
return [];
|
||||
}
|
||||
|
||||
// 判断是否是功能页面
|
||||
console.log('原始菜单数据:', menus);
|
||||
|
||||
// 功能页面路径关键词,这些菜单不应该显示在侧边栏
|
||||
// 注意:只过滤真正的功能页面,不过滤包含这些关键词的父菜单
|
||||
const functionPageKeywords = ['/detail', '/add', '/edit', '/delete', '/create', '/update'];
|
||||
|
||||
// 需要隐藏的子菜单路径(这些子菜单不应该显示在侧边栏)
|
||||
const hiddenSubMenuPaths = ['/apps/knowledge/category', '/apps/knowledge/tag'];
|
||||
|
||||
// 判断是否是功能页面(更精确的判断)
|
||||
const isFunctionPage = (path) => {
|
||||
if (!path) return false;
|
||||
const lowerPath = path.toLowerCase();
|
||||
return functionPageKeywords.some(keyword => lowerPath.includes(keyword));
|
||||
// 检查路径是否以这些关键词结尾,或者是这些关键词的组合
|
||||
// 例如:/apps/knowledge/detail 是功能页面
|
||||
// 但 /apps/knowledge 不是功能页面
|
||||
return functionPageKeywords.some(keyword => {
|
||||
// 检查路径是否以关键词结尾,或者路径中包含 /keyword/ 或 /keyword
|
||||
return lowerPath.endsWith(keyword) ||
|
||||
lowerPath.includes(`/${keyword}/`) ||
|
||||
lowerPath.endsWith(`/${keyword}`);
|
||||
});
|
||||
};
|
||||
|
||||
// 判断是否是需要隐藏的子菜单
|
||||
const isHiddenSubMenu = (path) => {
|
||||
if (!path) return false;
|
||||
const lowerPath = path.toLowerCase();
|
||||
return hiddenSubMenuPaths.some(hiddenPath => {
|
||||
return lowerPath === hiddenPath || lowerPath.startsWith(hiddenPath + '/');
|
||||
});
|
||||
};
|
||||
|
||||
// 首先映射字段格式,只保留页面菜单(menu_type=1),并过滤掉功能页面
|
||||
// 首先映射字段格式,只保留页面菜单(menu_type=1),并过滤掉功能页面和需要隐藏的子菜单
|
||||
const allMenus = menus
|
||||
.filter(menu => {
|
||||
// 只显示页面菜单,不显示API权限菜单
|
||||
if (menu.menuType !== 1) return false;
|
||||
// 过滤掉功能页面(详情、新增、编辑、删除、分类、标签等)
|
||||
if (isFunctionPage(menu.path)) return false;
|
||||
if (menu.menuType !== 1 && menu.menuType !== undefined) {
|
||||
console.log('过滤掉非页面菜单:', menu);
|
||||
return false;
|
||||
}
|
||||
// 过滤掉功能页面(详情、新增、编辑、删除等)
|
||||
if (isFunctionPage(menu.path)) {
|
||||
console.log('过滤掉功能页面:', menu.path);
|
||||
return false;
|
||||
}
|
||||
// 过滤掉需要隐藏的子菜单(如分类管理、标签管理)
|
||||
if (isHiddenSubMenu(menu.path)) {
|
||||
console.log('过滤掉隐藏的子菜单:', menu.path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map(menu => ({
|
||||
@ -133,16 +172,19 @@ const transformMenuData = (menus) => {
|
||||
children: []
|
||||
}));
|
||||
|
||||
console.log('过滤后的菜单数据:', allMenus);
|
||||
|
||||
// 构建菜单映射表(只包含有效的页面菜单)
|
||||
const menuMap = new Map();
|
||||
allMenus.forEach(menu => {
|
||||
menuMap.set(menu.id, menu);
|
||||
});
|
||||
|
||||
// 构建树形结构,只保留那些父菜单也存在的菜单项
|
||||
// 构建树形结构
|
||||
// 如果父菜单不在当前数据中,将菜单项作为根菜单显示
|
||||
const rootMenus = [];
|
||||
allMenus.forEach(menu => {
|
||||
if (menu.parentId === 0) {
|
||||
if (menu.parentId === 0 || !menu.parentId) {
|
||||
// 顶级菜单直接加入
|
||||
rootMenus.push(menu);
|
||||
} else {
|
||||
@ -154,10 +196,16 @@ const transformMenuData = (menus) => {
|
||||
parent.children = [];
|
||||
}
|
||||
parent.children.push(menu);
|
||||
} else {
|
||||
// 如果父菜单不存在,可能是父菜单被过滤掉了,或者父菜单不在当前返回的数据中
|
||||
// 这种情况下,将该菜单作为根菜单显示(避免菜单丢失)
|
||||
console.warn('菜单的父菜单不存在,将作为根菜单显示。菜单ID:', menu.id, '父菜单ID:', menu.parentId, '菜单路径:', menu.path);
|
||||
rootMenus.push(menu);
|
||||
}
|
||||
// 如果父菜单不存在(被过滤掉了或者是menu_type=2),则忽略该菜单项,不添加到任何地方
|
||||
}
|
||||
});
|
||||
|
||||
console.log('构建后的菜单树:', rootMenus);
|
||||
|
||||
// 按 order 排序(确保排序正确)
|
||||
const sortMenus = (menus) => {
|
||||
|
||||
@ -193,6 +193,33 @@ const handleCommand = async (command) => {
|
||||
// 清除菜单缓存
|
||||
menuStore.resetMenus();
|
||||
|
||||
// 清除所有以 menu_cache_ 开头的本地存储项
|
||||
const menuCacheKeys: string[] = [];
|
||||
// 遍历 localStorage
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key && key.startsWith('menu_cache_')) {
|
||||
menuCacheKeys.push(key);
|
||||
}
|
||||
}
|
||||
// 删除 localStorage 中的 menu_cache_ 项
|
||||
menuCacheKeys.forEach(key => {
|
||||
localStorage.removeItem(key);
|
||||
});
|
||||
|
||||
// 遍历 sessionStorage
|
||||
const sessionMenuCacheKeys: string[] = [];
|
||||
for (let i = 0; i < sessionStorage.length; i++) {
|
||||
const key = sessionStorage.key(i);
|
||||
if (key && key.startsWith('menu_cache_')) {
|
||||
sessionMenuCacheKeys.push(key);
|
||||
}
|
||||
}
|
||||
// 删除 sessionStorage 中的 menu_cache_ 项
|
||||
sessionMenuCacheKeys.forEach(key => {
|
||||
sessionStorage.removeItem(key);
|
||||
});
|
||||
|
||||
// 重置 tabs store 状态
|
||||
const { useTabsStore } = await import('@/stores');
|
||||
const tabsStore = useTabsStore();
|
||||
|
||||
@ -26,21 +26,17 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="描述" min-width="250" show-overflow-tooltip />
|
||||
<el-table-column prop="file_count" label="文件数量" width="120" sortable>
|
||||
<el-table-column prop="file_count" label="文件数量" width="120" sortable align="center">
|
||||
<template #default="{ row }">
|
||||
<el-badge :value="row.file_count || 0" :max="999" class="item">
|
||||
<el-button size="small" text type="primary">
|
||||
{{ row.file_count || 0 }} 个文件
|
||||
</el-button>
|
||||
</el-badge>
|
||||
<span>{{ row.file_count || 0 }} </span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort_order" label="排序" width="100" sortable>
|
||||
<el-table-column prop="sort_order" label="排序" width="100" sortable align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag type="info">{{ row.sort_order || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-model="row.status"
|
||||
@ -51,7 +47,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<el-table-column label="操作" width="180" fixed="right" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" type="primary" @click="editCategory(row)">
|
||||
编辑
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
详情
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.roleCode !== 'system_admin' && row.roleCode !== 'admin' && row.roleCode !== 'user'"
|
||||
v-if="row.default !== 1 && row.default !== 2"
|
||||
size="small"
|
||||
type="primary"
|
||||
link
|
||||
@ -60,7 +60,7 @@
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="row.roleCode !== 'system_admin' && row.roleCode !== 'admin' && row.roleCode !== 'user'"
|
||||
v-if="row.default !== 1 && row.default !== 2"
|
||||
size="small"
|
||||
type="danger"
|
||||
link
|
||||
|
||||
@ -127,9 +127,19 @@ func (c *RoleController) GetRoleByTenantId() {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前登录用户类型(从JWT中间件获取)
|
||||
userType, _ := c.Ctx.Input.GetData("userType").(string)
|
||||
isEmployee := userType == "employee"
|
||||
|
||||
// 转换为前端需要的格式,确保包含 tenantId 和 default 字段
|
||||
// 如果是租户登录(employee),过滤掉 default=1 的角色
|
||||
roleList := make([]map[string]interface{}, 0)
|
||||
for _, role := range roles {
|
||||
// 如果是租户登录,且角色的 default=1,则跳过(不显示)
|
||||
if isEmployee && role.Default == 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
roleList = append(roleList, map[string]interface{}{
|
||||
"roleId": role.RoleId,
|
||||
"tenantId": role.TenantId,
|
||||
|
||||
@ -99,6 +99,7 @@ func DeleteMenu(id int) error {
|
||||
}
|
||||
|
||||
// GetTenantMenus 根据角色ID获取租户菜单(只返回该角色有权限的菜单,且只返回页面菜单menu_type=1)
|
||||
// 注意:会自动包含所有父菜单,即使父菜单不在权限列表中
|
||||
func GetTenantMenus(roleId int) ([]map[string]interface{}, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
@ -141,7 +142,73 @@ func GetTenantMenus(roleId int) ([]map[string]interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 4. 转换为map格式
|
||||
// 4. 收集所有需要查询的父菜单ID(递归查找所有父菜单)
|
||||
parentIds := make(map[int]bool)
|
||||
var findParents func(pid int)
|
||||
findParents = func(pid int) {
|
||||
if pid == 0 || parentIds[pid] {
|
||||
return
|
||||
}
|
||||
parentIds[pid] = true
|
||||
// 查询父菜单
|
||||
var parentMenu Menu
|
||||
err := o.Raw("SELECT id, parent_id FROM yz_menus WHERE id = ? AND delete_time IS NULL AND menu_type = 1", pid).QueryRow(&parentMenu.Id, &parentMenu.ParentId)
|
||||
if err == nil && parentMenu.Id > 0 {
|
||||
// 继续查找父菜单的父菜单
|
||||
if parentMenu.ParentId > 0 {
|
||||
findParents(parentMenu.ParentId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 为每个菜单查找其父菜单
|
||||
for _, m := range menus {
|
||||
if m.ParentId > 0 {
|
||||
findParents(m.ParentId)
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 如果存在父菜单,查询所有父菜单
|
||||
if len(parentIds) > 0 {
|
||||
parentIdList := make([]int, 0, len(parentIds))
|
||||
for pid := range parentIds {
|
||||
parentIdList = append(parentIdList, pid)
|
||||
}
|
||||
|
||||
// 构建父菜单查询
|
||||
parentPlaceholders := make([]string, len(parentIdList))
|
||||
parentArgs := make([]interface{}, len(parentIdList)+1)
|
||||
for i, id := range parentIdList {
|
||||
parentPlaceholders[i] = "?"
|
||||
parentArgs[i] = id
|
||||
}
|
||||
parentArgs[len(parentIdList)] = 1 // menu_type=1
|
||||
|
||||
parentQuery := "SELECT id, name, path, parent_id, icon, `order`, status, component_path, is_external, external_url, menu_type, permission " +
|
||||
"FROM yz_menus " +
|
||||
"WHERE id IN (" + strings.Join(parentPlaceholders, ",") + ") " +
|
||||
"AND delete_time IS NULL " +
|
||||
"AND menu_type = ? " +
|
||||
"ORDER BY `order`, id"
|
||||
|
||||
var parentMenus []*Menu
|
||||
_, err = o.Raw(parentQuery, parentArgs...).QueryRows(&parentMenus)
|
||||
if err == nil && len(parentMenus) > 0 {
|
||||
// 将父菜单添加到结果中(去重)
|
||||
menuMap := make(map[int]*Menu)
|
||||
for _, m := range menus {
|
||||
menuMap[m.Id] = m
|
||||
}
|
||||
for _, pm := range parentMenus {
|
||||
if _, exists := menuMap[pm.Id]; !exists {
|
||||
menus = append(menus, pm)
|
||||
menuMap[pm.Id] = pm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 转换为map格式
|
||||
result := make([]map[string]interface{}, 0, len(menus))
|
||||
for _, m := range menus {
|
||||
item := map[string]interface{}{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user