搜索结果列表页面开发
This commit is contained in:
12
src/components/NavSidebar/README.md
Normal file
12
src/components/NavSidebar/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# NavSidebar
|
||||
|
||||
### 说明
|
||||
- 布局中使用的侧边栏菜单
|
||||
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 说明 |
|
||||
|---------------------|---------------------------------------------|
|
||||
| sidebarInfo | sidebar顶部信息 |
|
||||
|
||||
81
src/components/NavSidebar/attachMenu.ts
Normal file
81
src/components/NavSidebar/attachMenu.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
export const attachOrgSettingMenu = [
|
||||
{
|
||||
icon: 'icon-manage',
|
||||
label: '管理',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '内容管理', id: '/organization/setting/content' },
|
||||
{ children: [], icon: '', label: '专栏管理', id: '/organization/setting/column' },
|
||||
{ children: [], icon: '', label: '静态页面管理', id: '/organization/setting/static-page' },
|
||||
{ children: [], icon: '', label: '收录管理', id: '/organization/setting/included' },
|
||||
{ children: [], icon: '', label: '直播与活动', id: '/organization/setting/live' },
|
||||
{ children: [], icon: '', label: '文档中心', id: '/organization/setting/docs' },
|
||||
{ children: [], icon: '', label: '评论管理', id: '/organization/setting/comment-manage' },
|
||||
{ children: [], icon: '', label: '分类管理', id: '/organization/setting/category' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-operate',
|
||||
label: '运营',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: 'Banner位', id: '/organization/setting/rotation' },
|
||||
{ children: [], icon: '', label: '自定义导航', id: '/organization/setting/navigation' },
|
||||
{ children: [], icon: '', label: '产品推荐', id: '/organization/setting/market' },
|
||||
{ children: [], icon: '', label: '运营活动', id: '/organization/setting/rotation-right' },
|
||||
{ children: [], icon: '', label: '热门标签', id: '/organization/setting/hot-tags' },
|
||||
{ children: [], icon: '', label: '悬浮窗设置', id: '/organization/setting/float-window' },
|
||||
{ children: [], icon: '', label: '模块配置', id: '/organization/setting/module-config' },
|
||||
{ children: [], icon: '', label: '服务商信息', id: '/organization/setting/facilitator-config' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-growth',
|
||||
label: '成长体系',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '功能设置', id: '/organization/setting/growth' },
|
||||
{ children: [], icon: '', label: '任务中心', id: '/organization/setting/growth-task' },
|
||||
{ children: [], icon: '', label: '成长等级', id: '/organization/setting/growth-level' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-marketing',
|
||||
label: '营销组件',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '加入社区', id: '/organization/setting/join' },
|
||||
{ children: [], icon: '', label: '触达消息', id: '/organization/setting/push-msg' },
|
||||
{ children: [], icon: '', label: '留资表单', id: '/organization/setting/retained-capital' },
|
||||
{ children: [], icon: '', label: '抽奖工具', id: '/organization/setting/draw' },
|
||||
{ children: [], icon: '', label: '自定义弹窗', id: '/organization/setting/custom' },
|
||||
{ children: [], icon: '', label: '文章内容设置', id: '/organization/setting/content-setting' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-edu',
|
||||
label: '课程',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '课程管理', id: '/organization/setting/edu-course' },
|
||||
{ children: [], icon: '', label: '课程数据', id: '/organization/setting/data-edu' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-data',
|
||||
label: '数据',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '概览', id: '/organization/setting/data-board' },
|
||||
{ children: [], icon: '', label: '内容分析', id: '/organization/setting/data-content' },
|
||||
{ children: [], icon: '', label: '渠道来源', id: '/organization/setting/data-source' },
|
||||
{ children: [], icon: '', label: '用户分析', id: '/organization/setting/data-user' },
|
||||
{ children: [], icon: '', label: '作者分析', id: '/organization/setting/data-author' }
|
||||
]
|
||||
}, {
|
||||
icon: 'icon-set',
|
||||
label: '设置',
|
||||
id: '',
|
||||
children: [
|
||||
{ children: [], icon: '', label: '社区信息', id: '/organization/setting/general' },
|
||||
{ children: [], icon: '', label: '成员管理', id: '/organization/setting/people' },
|
||||
{ children: [], icon: '', label: '页面设置', id: '/organization/setting/exterior' },
|
||||
{ children: [], icon: '', label: '域名设置', id: '/organization/setting/domain' }
|
||||
]
|
||||
}
|
||||
];
|
||||
269
src/components/NavSidebar/index.vue
Normal file
269
src/components/NavSidebar/index.vue
Normal file
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<div class="navtabs-avatardiv pb-24 pr-24 pl-[10px]" v-if="showAvatar">
|
||||
<GAvatar :src="avatarParam?.avatar"
|
||||
:style="isOrg ? 'border:.5px solid #d3d3d3;border-radius: var(--border-radius);' : ''" :name="avatarParam?.name"
|
||||
:width="48" :height="48" :is_round="isRound"></GAvatar>
|
||||
<div class="navtabs-text ml-[16px]">
|
||||
<div class="info-span text-base text-G900 navtabs-omit">{{ avatarParam?.name }}</div>
|
||||
<div class="info-subtext text-sm text-CG600 navtabs-omit">{{ avatarParam?.infoSubText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-nav-sidebar w-[280px] pb-[48px]">
|
||||
<slot name="sidebarInfo"></slot>
|
||||
<!-- ui增加分类名和分割线 -->
|
||||
<template v-if="menuShow">
|
||||
<div v-for="(typeItem, index) in setMenuTypes(menulist)" :key="`${typeItem.label}_${index}`">
|
||||
<div class="mt-[12px] mb-[8px] text-CG600 text-[12px]" v-if="typeItem.label">{{ typeItem.label }}</div>
|
||||
<d-menu class="w-[280px]" mode="vertical" :default-select-keys="[id]" :open-keys="openKeys" @select="handleNav">
|
||||
<template v-for="item in typeItem.children" :key="item.id">
|
||||
<d-menu-item v-if="!item.children" :key="item.id">
|
||||
<template #icon v-if="item?.icon">
|
||||
<Icon :name="item?.icon"></Icon>
|
||||
</template>
|
||||
{{ item.label }}</d-menu-item>
|
||||
<d-sub-menu v-if="item.children" :title="item.label" :key="item.id">
|
||||
<template #icon v-if="item?.icon">
|
||||
<!-- <Icon :name="item?.icon"></Icon> -->
|
||||
<div class="icon-div">
|
||||
<Icon :name="item?.icon"></Icon>
|
||||
<Icon v-if="item.isNew" class="icon-new" :name="'gt-new'" size="28px"></Icon>
|
||||
</div>
|
||||
</template>
|
||||
<d-menu-item v-for="item1 in item.children" :key="item1.id">
|
||||
<template #icon v-if="item1?.icon">
|
||||
<Icon :name="item1?.icon"></Icon>
|
||||
</template>
|
||||
{{ item1.label }}</d-menu-item>
|
||||
</d-sub-menu>
|
||||
</template>
|
||||
</d-menu>
|
||||
<div class="g-row-line mt-[12px]" v-if="setMenuTypes(menulist)?.length - 1 > index"></div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { onBeforeRouteUpdate, useRouter, useRoute } from 'vue-router';
|
||||
import { type listType } from './types';
|
||||
import menu from '@/constant/menu';
|
||||
import { orgInfoStore, type OrgInfo } from '@/stores/Org/index';
|
||||
import { useAccountStore } from '@/stores/user';
|
||||
import microApp from '@micro-zoe/micro-app';
|
||||
const { accountInfo } = useAccountStore();
|
||||
interface IProps {
|
||||
// 声明props内容
|
||||
showAvatar?: boolean,
|
||||
isRound?: boolean,
|
||||
avatarParam?: {
|
||||
avatar?: string,
|
||||
name?: string,
|
||||
infoSubText?: string, // 预留,暂时没有传值
|
||||
[x: string]: any
|
||||
}
|
||||
}
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
showAvatar: true,
|
||||
isRound: false,
|
||||
avatarParam: () => {
|
||||
return {
|
||||
visibility: ''
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const orgStore = orgInfoStore();
|
||||
const route = useRoute();
|
||||
const menulist = ref<listType[]>(menu[route.meta.sidebarType]);
|
||||
const router = useRouter();
|
||||
const nsId = computed(() => orgStore.communityInfo?.ns_id);
|
||||
const isOrg = computed(() => /^\/org\//.test(route.path));
|
||||
const devHost = '';
|
||||
// const devHost = (import.meta as any).env.MODE === 'development' ? 'https://loc-devpress.csdn.net:444' : '';
|
||||
const id = ref();
|
||||
const openKeys = ref([]);
|
||||
const setCurSelected = () => {
|
||||
// 白名单处理Webhook创建、详情页要选中导航
|
||||
id.value = router.currentRoute.value.name?.includes('repoWebhook') ? 'repoWebhook' : router.currentRoute.value.name;
|
||||
|
||||
menulist.value?.forEach(item => {
|
||||
if (item?.children?.some(e => e.id === id.value)) {
|
||||
openKeys.value.push(item.id);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 判断社区是否显示
|
||||
const menuShow = ref(true);
|
||||
const onShowCom = () => {
|
||||
menuShow.value = false;
|
||||
menulist.value = menu[route.meta.sidebarType].filter((item: any) => {
|
||||
if (item.label === '社区管理') {
|
||||
return orgStore.orgInfo.visibility === 'public';
|
||||
}
|
||||
return true;
|
||||
});
|
||||
nextTick(() => {
|
||||
menuShow.value = true;
|
||||
});
|
||||
};
|
||||
const onShowPipeLine = async () => {
|
||||
menuShow.value = false;
|
||||
menulist.value = menu[route.meta.sidebarType].filter((item: any) => {
|
||||
if (item.label === '流水线') {
|
||||
return accountInfo.atomgit_username;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
nextTick(() => {
|
||||
menuShow.value = true;
|
||||
});
|
||||
};
|
||||
watch(() => orgStore.orgInfo, () => {
|
||||
onShowCom();
|
||||
}, { deep: true });
|
||||
watch(() => accountInfo.atomgit_username, () => {
|
||||
onShowPipeLine();
|
||||
}, { deep: true });
|
||||
|
||||
onBeforeRouteUpdate((to) => {
|
||||
id.value = to.name; // 页面加载,激活对应tab
|
||||
menulist.value = menu[to.meta.sidebarType]; // 根据meta中的type确定导航内容
|
||||
if (route.meta.sidebarType === 'userSetting') {
|
||||
onShowPipeLine();
|
||||
}
|
||||
});
|
||||
watch(() => router.currentRoute.value.path, (newValue, oldValue) => {
|
||||
menulist.value = menu[route?.meta?.sidebarType];
|
||||
if (route.meta.sidebarType === 'orgSetting') {
|
||||
onShowCom();
|
||||
}
|
||||
if (route.meta.sidebarType === 'userSetting') {
|
||||
onShowPipeLine();
|
||||
}
|
||||
setCurSelected();
|
||||
}, { immediate: true });
|
||||
// 点击tab跳转路由
|
||||
const handleNav = (val) => {
|
||||
console.log(val)
|
||||
if (/^\/organization/.test(val.key)) {
|
||||
window.open(`${devHost}${val.key}/${nsId.value}`, '_self');
|
||||
} else router.push({ name: val.key });
|
||||
};
|
||||
|
||||
// 分类处理函数-增加分类名称显示
|
||||
const setMenuTypes = (menu: any) => {
|
||||
const res = []; const typeMap = new Map();
|
||||
for (let i = 0; i < menu.length; ++i) {
|
||||
const { menuType } = menu[i];
|
||||
if (menuType) {
|
||||
let type = typeMap.get(menuType);
|
||||
if (!type) {
|
||||
type = { label: menuType, children: [] };
|
||||
res.push(type);
|
||||
typeMap.set(menuType, type);
|
||||
}
|
||||
type.children.push(menu[i]);
|
||||
} else {
|
||||
if (res.length && res[res.length - 1].label === '') res[res.length - 1].children.push(menu[i]);
|
||||
else res.push({ label: '', children: [menu[i]] });
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const checkPage = (data: any) => {
|
||||
if (data.type === 'settingEmail') {
|
||||
id.value = 'settingEmail';
|
||||
router.push({ name: 'settingEmail' })
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
microApp.addDataListener('user-center', checkPage, );
|
||||
});
|
||||
onUnmounted(() => {
|
||||
microApp.removeDataListener('user-center', checkPage);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.g-nav-sidebar {
|
||||
:deep(.devui-menu-vertical) {
|
||||
border-right: 0;
|
||||
background: none !important;
|
||||
|
||||
.devui-menu-item-select {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.layer_1 {
|
||||
|
||||
.devui-menu-item,
|
||||
.devui-submenu-title {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.layer_2 {
|
||||
.devui-menu-item {
|
||||
padding: 0 50px !important;
|
||||
}
|
||||
|
||||
.devui-submenu-title {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.layer_2>div.devui-submenu-title,
|
||||
ul.devui-submenu .devui-menu-item {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.icon-chevron-up {
|
||||
color: var(--color-CG600);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navtabs-avatardiv {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.navtabs-text {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.info-span {
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.info-subtext {
|
||||
// font-size: var(--text-sm);
|
||||
font-weight: 400;
|
||||
// color: var(--color-CG600);
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.navtabs-omit {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon-div {
|
||||
position: relative;
|
||||
|
||||
.icon-new {
|
||||
position: absolute;
|
||||
top: -18px;
|
||||
left: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
src/components/NavSidebar/types.ts
Normal file
15
src/components/NavSidebar/types.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export interface itemProps {
|
||||
id: string; // 标识符,这里为路由别名
|
||||
label: string; // 标题
|
||||
number?: number; // 显示数量
|
||||
icon?: string; // 图标
|
||||
children?: itemProps[], // 子item
|
||||
menuType?: string // 菜单分类
|
||||
}
|
||||
export interface propsType {
|
||||
defaultActiveId?: string;
|
||||
tabList: itemProps[];
|
||||
}
|
||||
export interface listType {
|
||||
[index: number]: itemProps;
|
||||
}
|
||||
Reference in New Issue
Block a user