2025-07-23 17:02:24 +08:00
|
|
|
<script setup>
|
2025-08-16 17:55:49 +08:00
|
|
|
import { Layout } from 'ant-design-vue';
|
2025-08-18 17:22:11 +08:00
|
|
|
import Navbar from './components/navbar';
|
|
|
|
|
import SiderBar from './components/siderBar';
|
2025-08-16 17:55:49 +08:00
|
|
|
|
2025-06-16 14:42:26 +08:00
|
|
|
import { useAppStore } from '@/stores';
|
2025-08-18 17:22:11 +08:00
|
|
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
2025-06-16 14:42:26 +08:00
|
|
|
import { useResponsive } from '@/hooks';
|
2025-06-20 18:16:40 +08:00
|
|
|
import JoinModal from '@/components/join-modal.vue';
|
|
|
|
|
import { getQueryParam } from '@/utils/helper';
|
2025-07-23 17:02:24 +08:00
|
|
|
import { useUserStore } from '@/stores';
|
|
|
|
|
|
2025-06-22 22:52:03 -04:00
|
|
|
import { ref, onMounted, computed } from 'vue';
|
|
|
|
|
import { useRoute } from 'vue-router';
|
2025-06-16 14:42:26 +08:00
|
|
|
|
2025-06-20 18:16:40 +08:00
|
|
|
const joinEnterpriseVisible = ref(false);
|
2025-07-23 17:02:24 +08:00
|
|
|
const joinModalRef = ref(null);
|
2025-06-16 14:42:26 +08:00
|
|
|
const appStore = useAppStore();
|
2025-08-18 17:22:11 +08:00
|
|
|
const sidebarStore = useSidebarStore();
|
2025-07-23 17:02:24 +08:00
|
|
|
const userStore = useUserStore();
|
2025-06-16 14:42:26 +08:00
|
|
|
const router = useRouter();
|
2025-06-22 22:52:03 -04:00
|
|
|
const route = useRoute();
|
2025-06-16 14:42:26 +08:00
|
|
|
|
2025-08-19 18:10:36 +08:00
|
|
|
|
2025-06-16 14:42:26 +08:00
|
|
|
useResponsive(true);
|
2025-08-18 17:38:14 +08:00
|
|
|
|
2025-08-16 17:55:49 +08:00
|
|
|
const showSider = computed(() => {
|
2025-08-19 10:43:53 +08:00
|
|
|
return !route.meta?.hideSidebar;
|
2025-08-16 17:55:49 +08:00
|
|
|
});
|
2025-08-19 18:10:36 +08:00
|
|
|
const isHomeRoute = computed(() => {
|
|
|
|
|
return route.name === 'Home';
|
|
|
|
|
});
|
2025-06-16 14:42:26 +08:00
|
|
|
|
2025-08-19 18:01:30 +08:00
|
|
|
const layoutPageClass = computed(() => {
|
2025-08-19 18:10:36 +08:00
|
|
|
if (isHomeRoute.value) {
|
2025-08-19 18:01:30 +08:00
|
|
|
return 'pb-8px pr-8px';
|
|
|
|
|
}
|
|
|
|
|
return 'pb-24px pr-24px';
|
2025-08-19 10:43:53 +08:00
|
|
|
});
|
|
|
|
|
|
2025-08-19 18:01:30 +08:00
|
|
|
const siderWidth = computed(() => {
|
|
|
|
|
return showSider.value ? sidebarStore.sidebarWidth : 0;
|
|
|
|
|
});
|
2025-08-19 10:43:53 +08:00
|
|
|
|
2025-06-16 14:42:26 +08:00
|
|
|
const collapsed = computed(() => {
|
2025-08-18 17:22:11 +08:00
|
|
|
return sidebarStore.menuCollapse;
|
2025-06-16 14:42:26 +08:00
|
|
|
});
|
2025-06-30 18:37:27 +08:00
|
|
|
|
2025-06-20 18:16:40 +08:00
|
|
|
onMounted(() => {
|
|
|
|
|
checkHasInviteCode();
|
|
|
|
|
});
|
2025-07-23 17:02:24 +08:00
|
|
|
const setCollapsed = (val) => {
|
2025-06-16 14:42:26 +08:00
|
|
|
appStore.updateSettings({ menuCollapse: val });
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-20 18:16:40 +08:00
|
|
|
const checkHasInviteCode = () => {
|
|
|
|
|
const inviteCode = getQueryParam('invite_code');
|
2025-07-23 17:02:24 +08:00
|
|
|
if (userStore.isLogin && inviteCode) {
|
2025-06-20 18:16:40 +08:00
|
|
|
joinEnterpriseVisible.value = true;
|
2025-07-23 17:02:24 +08:00
|
|
|
joinModalRef.value?.getEnterprise?.();
|
2025-06-20 18:16:40 +08:00
|
|
|
}
|
|
|
|
|
};
|
2025-06-16 14:42:26 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-08-16 17:55:49 +08:00
|
|
|
<Layout :class="['layout-wrap', { mobile: appStore.hideMenu }]" class="h-full flex flex-col w-full">
|
2025-07-23 17:02:24 +08:00
|
|
|
<JoinModal v-model:visible="joinEnterpriseVisible" ref="joinModalRef" />
|
2025-08-18 10:09:41 +08:00
|
|
|
<Layout.Header class="layout-header-wrap">
|
|
|
|
|
<Navbar />
|
|
|
|
|
</Layout.Header>
|
2025-08-16 17:55:49 +08:00
|
|
|
<Layout class="flex layout-content-wrap">
|
2025-08-18 10:09:41 +08:00
|
|
|
<Layout.Sider
|
2025-08-16 17:55:49 +08:00
|
|
|
v-if="showSider"
|
|
|
|
|
v-model="collapsed"
|
2025-08-19 18:01:30 +08:00
|
|
|
:width="siderWidth"
|
2025-08-16 17:01:06 +08:00
|
|
|
collapsible
|
2025-08-16 17:55:49 +08:00
|
|
|
trigger
|
2025-08-16 17:01:06 +08:00
|
|
|
@collapse="setCollapsed"
|
2025-08-19 10:43:53 +08:00
|
|
|
class="layout-sider"
|
2025-08-16 17:01:06 +08:00
|
|
|
>
|
2025-08-19 10:43:53 +08:00
|
|
|
<SiderBar />
|
2025-08-18 10:09:41 +08:00
|
|
|
</Layout.Sider>
|
2025-08-19 18:01:30 +08:00
|
|
|
<Layout
|
2025-08-19 10:43:53 +08:00
|
|
|
class="layout-content"
|
|
|
|
|
:style="{
|
2025-08-19 18:01:30 +08:00
|
|
|
paddingLeft: `${siderWidth}px`,
|
2025-08-19 10:43:53 +08:00
|
|
|
}"
|
|
|
|
|
>
|
2025-08-19 18:10:36 +08:00
|
|
|
<Layout.Content :class="layoutPageClass" class="!min-h-initial">
|
2025-08-16 17:01:06 +08:00
|
|
|
<layout-page />
|
2025-08-19 18:01:30 +08:00
|
|
|
</Layout.Content>
|
|
|
|
|
</Layout>
|
2025-08-16 17:55:49 +08:00
|
|
|
</Layout>
|
|
|
|
|
</Layout>
|
2025-06-16 14:42:26 +08:00
|
|
|
</template>
|
|
|
|
|
|
2025-07-11 16:50:48 +08:00
|
|
|
<style scoped lang="scss">
|
2025-08-16 17:01:06 +08:00
|
|
|
.layout-wrap {
|
2025-08-16 17:55:49 +08:00
|
|
|
font-family: inherit;
|
|
|
|
|
background: transparent;
|
2025-08-16 17:01:06 +08:00
|
|
|
min-width: 1200px;
|
2025-08-16 18:00:06 +08:00
|
|
|
.layout-header-wrap {
|
|
|
|
|
background: transparent;
|
2025-08-15 14:32:40 +08:00
|
|
|
height: $navbar-height;
|
2025-08-16 18:00:06 +08:00
|
|
|
line-height: $navbar-height;
|
|
|
|
|
padding-inline: inherit;
|
|
|
|
|
color: inherit;
|
2025-08-19 10:43:53 +08:00
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
2025-08-21 10:54:18 +08:00
|
|
|
z-index: 1000;
|
2025-08-19 10:43:53 +08:00
|
|
|
width: 100%;
|
2025-06-16 14:42:26 +08:00
|
|
|
}
|
2025-08-16 17:01:06 +08:00
|
|
|
.layout-content-wrap {
|
2025-08-19 10:43:53 +08:00
|
|
|
width: 100%;
|
2025-08-15 14:32:40 +08:00
|
|
|
height: 100%;
|
2025-08-16 17:55:49 +08:00
|
|
|
background: transparent;
|
2025-08-16 17:01:06 +08:00
|
|
|
min-height: calc(100vh - $navbar-height);
|
2025-08-16 17:55:49 +08:00
|
|
|
:deep(.ant-layout-sider) {
|
2025-08-16 17:01:06 +08:00
|
|
|
background: none;
|
|
|
|
|
box-shadow: none;
|
2025-08-19 10:43:53 +08:00
|
|
|
padding-top: $navbar-height;
|
2025-08-16 17:55:49 +08:00
|
|
|
padding-bottom: 0;
|
2025-08-19 10:43:53 +08:00
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
2025-08-19 18:01:30 +08:00
|
|
|
z-index: 999;
|
2025-08-19 10:43:53 +08:00
|
|
|
height: 100%;
|
|
|
|
|
transition: all 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
|
2025-08-16 17:55:49 +08:00
|
|
|
.ant-layout-sider-trigger {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
.ant-layout-sider-children {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
2025-06-16 14:42:26 +08:00
|
|
|
}
|
2025-08-16 17:01:06 +08:00
|
|
|
.layout-content {
|
2025-08-19 10:43:53 +08:00
|
|
|
padding-top: $navbar-height;
|
2025-08-16 17:55:49 +08:00
|
|
|
background: transparent;
|
2025-08-16 17:01:06 +08:00
|
|
|
transition: padding 0.2s cubic-bezier(0.34, 0.69, 0.1, 1);
|
|
|
|
|
}
|
2025-08-15 14:32:40 +08:00
|
|
|
}
|
2025-06-16 14:42:26 +08:00
|
|
|
}
|
|
|
|
|
</style>
|