feat: 顶部菜单&项目选择器&右上角图标
This commit is contained in:
parent
38f798f27e
commit
28525002f6
|
@ -0,0 +1,9 @@
|
||||||
|
import MSR from '@/api/http/index';
|
||||||
|
import { ProjectListUrl } from '@/api/requrls/system/project';
|
||||||
|
import type { ProjectListItem } from '@/models/system/project';
|
||||||
|
|
||||||
|
export function getProjectList(organizationId: string) {
|
||||||
|
return MSR.get<ProjectListItem[]>({ url: `${ProjectListUrl}/${organizationId}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {};
|
|
@ -1,5 +1,5 @@
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
import { GetUserListUrl, CreateUserUrl, UpdateUserUrl } from '@/api/requrls/system';
|
import { GetUserListUrl, CreateUserUrl, UpdateUserUrl } from '@/api/requrls/system/user';
|
||||||
import type { UserListItem, CreateUserParams } from '@/models/system/user';
|
import type { UserListItem, CreateUserParams } from '@/models/system/user';
|
||||||
import type { TableQueryParams } from '@/models/common';
|
import type { TableQueryParams } from '@/models/common';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
import { updateUserGroupU, getUserGroupU, addUserGroupU, deleteUserGroupU } from '@/api/requrls/usergroup';
|
import { updateUserGroupU, getUserGroupU, addUserGroupU, deleteUserGroupU } from '@/api/requrls/system/usergroup';
|
||||||
// import { QueryParams, CommonList } from '@/models/common';
|
// import { QueryParams, CommonList } from '@/models/common';
|
||||||
import { UserGroupItem } from '@/components/bussiness/usergroup/type';
|
import { UserGroupItem } from '@/components/bussiness/usergroup/type';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const ProjectListUrl = '/system/project/list';
|
||||||
|
|
||||||
|
export default {};
|
|
@ -3,7 +3,7 @@
|
||||||
v-if="appStore.topMenus.length > 0"
|
v-if="appStore.topMenus.length > 0"
|
||||||
class="bg-transparent"
|
class="bg-transparent"
|
||||||
mode="horizontal"
|
mode="horizontal"
|
||||||
:default-selected-keys="[appStore.topMenus[0].name]"
|
:default-selected-keys="[defaultActiveMenu]"
|
||||||
>
|
>
|
||||||
<a-menu-item v-for="menu of appStore.topMenus" :key="(menu.name as string)" @click="jumpPath(menu.name)">
|
<a-menu-item v-for="menu of appStore.topMenus" :key="(menu.name as string)" @click="jumpPath(menu.name)">
|
||||||
{{ t(menu.meta?.locale || '') }}
|
{{ t(menu.meta?.locale || '') }}
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue';
|
||||||
import { useRouter, RouteRecordRaw, RouteRecordNormalized, RouteRecordName } from 'vue-router';
|
import { useRouter, RouteRecordRaw, RouteRecordNormalized, RouteRecordName } from 'vue-router';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
@ -26,6 +27,11 @@
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const defaultActiveMenu = computed(() => {
|
||||||
|
const { name } = router.currentRoute.value;
|
||||||
|
return name;
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听路由变化,存储打开的三级子路由
|
* 监听路由变化,存储打开的三级子路由
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,35 +6,47 @@
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-side">
|
<div class="center-side">
|
||||||
|
<template v-if="showProjectSelect">
|
||||||
|
<a-divider direction="vertical" class="ml-0" />
|
||||||
|
<a-select
|
||||||
|
class="w-auto max-w-[200px] focus-within:!bg-[var(--color-text-n8)] hover:!bg-[var(--color-text-n8)]"
|
||||||
|
:default-value="appStore.getCurrentProjectId"
|
||||||
|
:bordered="false"
|
||||||
|
@change="selectProject"
|
||||||
|
>
|
||||||
|
<template #arrow-icon>
|
||||||
|
<icon-caret-down />
|
||||||
|
</template>
|
||||||
|
<a-tooltip v-for="project of projectList" :key="project.id" :mouse-enter-delay="500" :content="project.name">
|
||||||
|
<a-option
|
||||||
|
:value="project.id"
|
||||||
|
:class="project.id === appStore.getCurrentProjectId ? 'arco-select-option-selected' : ''"
|
||||||
|
>{{ project.name }}</a-option
|
||||||
|
>
|
||||||
|
</a-tooltip>
|
||||||
|
</a-select>
|
||||||
|
<a-divider direction="vertical" class="mr-0" />
|
||||||
|
</template>
|
||||||
<TopMenu />
|
<TopMenu />
|
||||||
</div>
|
</div>
|
||||||
<ul class="right-side">
|
<ul class="right-side">
|
||||||
<li>
|
<li>
|
||||||
<a-tooltip :content="$t('settings.language')">
|
<a-tooltip :content="t('settings.navbar.search')">
|
||||||
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="setDropDownVisible">
|
<a-button type="secondary">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-language />
|
<icon-search />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-dropdown trigger="click" @select="changeLocale as any">
|
|
||||||
<div ref="triggerBtn" class="trigger-btn"></div>
|
|
||||||
<template #content>
|
|
||||||
<a-doption v-for="item in locales" :key="item.value" :value="item.value">
|
|
||||||
<template #icon>
|
|
||||||
<icon-check v-show="item.value === currentLocale" />
|
|
||||||
</template>
|
|
||||||
{{ item.label }}
|
|
||||||
</a-doption>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a-tooltip :content="$t('settings.navbar.alerts')">
|
<a-tooltip :content="t('settings.navbar.alerts')">
|
||||||
<div class="message-box-trigger">
|
<div class="message-box-trigger">
|
||||||
<a-badge :count="9" dot>
|
<a-badge :count="9" dot>
|
||||||
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="setPopoverVisible">
|
<a-button type="secondary" @click="setPopoverVisible">
|
||||||
<icon-notification />
|
<template #icon>
|
||||||
|
<icon-notification />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-badge>
|
</a-badge>
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,7 +64,52 @@
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a-tooltip :content="isFullscreen ? $t('settings.navbar.screen.toExit') : $t('settings.navbar.screen.toFull')">
|
<a-tooltip :content="t('settings.navbar.task')">
|
||||||
|
<a-button type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-calendar-clock />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a-dropdown trigger="click" position="br">
|
||||||
|
<a-tooltip :content="t('settings.navbar.help')">
|
||||||
|
<a-button type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-question-circle />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<template #content>
|
||||||
|
<a-doption v-for="item in helpCenterList" :key="item.name" :value="item.name">
|
||||||
|
<component :is="item.icon"></component>
|
||||||
|
{{ t(item.name) }}
|
||||||
|
</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a-dropdown trigger="click" position="br" @select="changeLocale as any">
|
||||||
|
<a-tooltip :content="t('settings.language')">
|
||||||
|
<a-button type="secondary">
|
||||||
|
<template #icon>
|
||||||
|
<icon-translate />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
<template #content>
|
||||||
|
<a-doption v-for="item in locales" :key="item.value" :value="item.value">
|
||||||
|
<template #icon>
|
||||||
|
<icon-check v-show="item.value === currentLocale" />
|
||||||
|
</template>
|
||||||
|
{{ item.label }}
|
||||||
|
</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</li>
|
||||||
|
<!-- <li>
|
||||||
|
<a-tooltip :content="isFullscreen ? t('settings.navbar.screen.toExit') : t('settings.navbar.screen.toFull')">
|
||||||
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="toggleFullScreen">
|
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="toggleFullScreen">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-fullscreen-exit v-if="isFullscreen" />
|
<icon-fullscreen-exit v-if="isFullscreen" />
|
||||||
|
@ -60,9 +117,9 @@
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</li>
|
</li> -->
|
||||||
<!-- <li>
|
<!-- <li>
|
||||||
<a-tooltip :content="$t('settings.title')">
|
<a-tooltip :content="t('settings.title')">
|
||||||
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="setVisible">
|
<a-button class="nav-btn" type="outline" :shape="'circle'" @click="setVisible">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-settings />
|
<icon-settings />
|
||||||
|
@ -70,7 +127,7 @@
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</li> -->
|
</li> -->
|
||||||
<li>
|
<!-- <li>
|
||||||
<a-dropdown trigger="click">
|
<a-dropdown trigger="click">
|
||||||
<a-avatar :size="32" :style="{ marginRight: '8px', cursor: 'pointer' }">
|
<a-avatar :size="32" :style="{ marginRight: '8px', cursor: 'pointer' }">
|
||||||
<img alt="avatar" :src="avatar" />
|
<img alt="avatar" :src="avatar" />
|
||||||
|
@ -80,7 +137,7 @@
|
||||||
<a-space @click="switchRoles">
|
<a-space @click="switchRoles">
|
||||||
<icon-tag />
|
<icon-tag />
|
||||||
<span>
|
<span>
|
||||||
{{ $t('messageBox.switchRoles') }}
|
{{ t('messageBox.switchRoles') }}
|
||||||
</span>
|
</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
@ -88,7 +145,7 @@
|
||||||
<a-space @click="$router.push({ name: 'Info' })">
|
<a-space @click="$router.push({ name: 'Info' })">
|
||||||
<icon-user />
|
<icon-user />
|
||||||
<span>
|
<span>
|
||||||
{{ $t('messageBox.userCenter') }}
|
{{ t('messageBox.userCenter') }}
|
||||||
</span>
|
</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
@ -96,7 +153,7 @@
|
||||||
<a-space @click="$router.push({ name: 'Setting' })">
|
<a-space @click="$router.push({ name: 'Setting' })">
|
||||||
<icon-settings />
|
<icon-settings />
|
||||||
<span>
|
<span>
|
||||||
{{ $t('messageBox.userSettings') }}
|
{{ t('messageBox.userSettings') }}
|
||||||
</span>
|
</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
|
@ -104,41 +161,89 @@
|
||||||
<a-space @click="handleLogout">
|
<a-space @click="handleLogout">
|
||||||
<icon-export />
|
<icon-export />
|
||||||
<span>
|
<span>
|
||||||
{{ $t('messageBox.logout') }}
|
{{ t('messageBox.logout') }}
|
||||||
</span>
|
</span>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-doption>
|
</a-doption>
|
||||||
</template>
|
</template>
|
||||||
</a-dropdown>
|
</a-dropdown>
|
||||||
</li>
|
</li> -->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from 'vue';
|
import { ref, computed, Ref, onBeforeMount } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { useRoute } from 'vue-router';
|
||||||
import { useFullscreen } from '@vueuse/core';
|
import { IconCompass, IconQuestionCircle, IconFile, IconInfoCircle } from '@arco-design/web-vue/es/icon';
|
||||||
import { useUserStore } from '@/store';
|
// import { Message } from '@arco-design/web-vue';
|
||||||
|
// import { useFullscreen } from '@vueuse/core';
|
||||||
|
import { useAppStore } from '@/store';
|
||||||
import { LOCALE_OPTIONS } from '@/locale';
|
import { LOCALE_OPTIONS } from '@/locale';
|
||||||
import useLocale from '@/locale/useLocale';
|
import useLocale from '@/locale/useLocale';
|
||||||
import useUser from '@/hooks/useUser';
|
// import useUser from '@/hooks/useUser';
|
||||||
import TopMenu from '@/components/pure/ms-top-menu/index.vue';
|
import TopMenu from '@/components/pure/ms-top-menu/index.vue';
|
||||||
import MessageBox from '../message-box/index.vue';
|
import MessageBox from '../message-box/index.vue';
|
||||||
|
import { NOT_SHOW_PROJECT_SELECT_MODULE } from '@/router/constants';
|
||||||
|
import { getProjectList } from '@/api/modules/system/project';
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
import type { ProjectListItem } from '@/models/system/project';
|
||||||
const { logout } = useUser();
|
|
||||||
const { changeLocale, currentLocale } = useLocale();
|
const appStore = useAppStore();
|
||||||
const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
|
// const { logout } = useUser();
|
||||||
const locales = [...LOCALE_OPTIONS];
|
const route = useRoute();
|
||||||
const avatar = computed(() => {
|
const { t } = useI18n();
|
||||||
return userStore.avatar;
|
|
||||||
|
const projectList: Ref<ProjectListItem[]> = ref([]);
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
const res = await getProjectList(appStore.getCurrentOrgId);
|
||||||
|
projectList.value = res;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showProjectSelect = computed(() => {
|
||||||
|
// 匹配一级路由是否存在于不需要显示项目选择的路由中
|
||||||
|
return !NOT_SHOW_PROJECT_SELECT_MODULE.includes(route.fullPath.split('/')[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
function selectProject(value: string | number | Record<string, any> | undefined) {
|
||||||
|
appStore.setCurrentProjectId(value as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
const helpCenterList = [
|
||||||
|
{
|
||||||
|
name: 'settings.help.guide',
|
||||||
|
icon: IconCompass,
|
||||||
|
route: '/help-center/guide',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'settings.help.doc',
|
||||||
|
icon: IconQuestionCircle,
|
||||||
|
route: '/help-center/guide',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'settings.help.APIDoc',
|
||||||
|
icon: IconFile,
|
||||||
|
route: '/help-center/guide',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'settings.help.version',
|
||||||
|
icon: IconInfoCircle,
|
||||||
|
route: '/help-center/guide',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { changeLocale, currentLocale } = useLocale();
|
||||||
|
// const { isFullscreen, toggle: toggleFullScreen } = useFullscreen();
|
||||||
|
const locales = [...LOCALE_OPTIONS];
|
||||||
|
// const avatar = computed(() => {
|
||||||
|
// return userStore.avatar;
|
||||||
|
// });
|
||||||
// const setVisible = () => {
|
// const setVisible = () => {
|
||||||
// appStore.updateSettings({ globalSettings: true });
|
// appStore.updateSettings({ globalSettings: true });
|
||||||
// };
|
// };
|
||||||
const refBtn = ref();
|
const refBtn = ref();
|
||||||
const triggerBtn = ref();
|
|
||||||
const setPopoverVisible = () => {
|
const setPopoverVisible = () => {
|
||||||
const event = new MouseEvent('click', {
|
const event = new MouseEvent('click', {
|
||||||
view: window,
|
view: window,
|
||||||
|
@ -147,21 +252,13 @@
|
||||||
});
|
});
|
||||||
refBtn.value.dispatchEvent(event);
|
refBtn.value.dispatchEvent(event);
|
||||||
};
|
};
|
||||||
const handleLogout = () => {
|
// const handleLogout = () => {
|
||||||
logout();
|
// logout();
|
||||||
};
|
// };
|
||||||
const setDropDownVisible = () => {
|
// const switchRoles = async () => {
|
||||||
const event = new MouseEvent('click', {
|
// const res = await userStore.switchRoles();
|
||||||
view: window,
|
// Message.success(res as string);
|
||||||
bubbles: true,
|
// };
|
||||||
cancelable: true,
|
|
||||||
});
|
|
||||||
triggerBtn.value.dispatchEvent(event);
|
|
||||||
};
|
|
||||||
const switchRoles = async () => {
|
|
||||||
const res = await userStore.switchRoles();
|
|
||||||
Message.success(res as string);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -177,7 +274,7 @@
|
||||||
width: 185px;
|
width: 185px;
|
||||||
}
|
}
|
||||||
.center-side {
|
.center-side {
|
||||||
@apply flex-1;
|
@apply flex flex-1 items-center;
|
||||||
}
|
}
|
||||||
.right-side {
|
.right-side {
|
||||||
@apply flex list-none;
|
@apply flex list-none;
|
||||||
|
@ -189,7 +286,16 @@
|
||||||
li {
|
li {
|
||||||
@apply flex items-center;
|
@apply flex items-center;
|
||||||
|
|
||||||
padding: 0 10px;
|
padding-left: 10px;
|
||||||
|
.arco-btn-secondary {
|
||||||
|
@apply !bg-transparent;
|
||||||
|
|
||||||
|
color: var(--color-text-4) !important;
|
||||||
|
&:hover,
|
||||||
|
&:focus-visible {
|
||||||
|
color: var(--color-text-1) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
@apply no-underline;
|
@apply no-underline;
|
||||||
|
@ -219,4 +325,29 @@
|
||||||
@apply mt-0;
|
@apply mt-0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.arco-menu-horizontal {
|
||||||
|
.arco-menu-inner {
|
||||||
|
.arco-menu-item,
|
||||||
|
.arco-menu-overflow-sub-menu {
|
||||||
|
@apply !bg-transparent;
|
||||||
|
}
|
||||||
|
.arco-menu-selected {
|
||||||
|
@apply !font-normal;
|
||||||
|
|
||||||
|
color: rgb(var(--primary-5)) !important;
|
||||||
|
.arco-menu-selected-label {
|
||||||
|
bottom: -11px;
|
||||||
|
background-color: rgb(var(--primary-5)) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.arco-trigger-menu-vertical {
|
||||||
|
max-height: 500px;
|
||||||
|
.arco-trigger-menu-selected {
|
||||||
|
@apply !font-normal;
|
||||||
|
|
||||||
|
color: rgb(var(--primary-5)) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,7 +8,14 @@ export default {
|
||||||
'settings.menuWidth': 'Menu Width (px)',
|
'settings.menuWidth': 'Menu Width (px)',
|
||||||
'settings.navbar.screen.toFull': 'Click to switch to full screen mode',
|
'settings.navbar.screen.toFull': 'Click to switch to full screen mode',
|
||||||
'settings.navbar.screen.toExit': 'Click to exit the full screen mode',
|
'settings.navbar.screen.toExit': 'Click to exit the full screen mode',
|
||||||
'settings.navbar.alerts': 'alerts',
|
'settings.navbar.alerts': 'Alerts',
|
||||||
|
'settings.navbar.search': 'Search',
|
||||||
|
'settings.navbar.task': 'Task center',
|
||||||
|
'settings.navbar.help': 'Help center',
|
||||||
|
'settings.help.guide': 'Use Guide',
|
||||||
|
'settings.help.doc': 'Help docs',
|
||||||
|
'settings.help.APIDoc': 'API docs',
|
||||||
|
'settings.help.version': 'Version',
|
||||||
'settings.menu': 'Menu',
|
'settings.menu': 'Menu',
|
||||||
'settings.tabBar': 'Tab Bar',
|
'settings.tabBar': 'Tab Bar',
|
||||||
'settings.footer': 'Footer',
|
'settings.footer': 'Footer',
|
||||||
|
|
|
@ -9,6 +9,13 @@ export default {
|
||||||
'settings.navbar.screen.toFull': '点击切换全屏模式',
|
'settings.navbar.screen.toFull': '点击切换全屏模式',
|
||||||
'settings.navbar.screen.toExit': '点击退出全屏模式',
|
'settings.navbar.screen.toExit': '点击退出全屏模式',
|
||||||
'settings.navbar.alerts': '消息通知',
|
'settings.navbar.alerts': '消息通知',
|
||||||
|
'settings.navbar.search': '搜索',
|
||||||
|
'settings.navbar.task': '任务中心',
|
||||||
|
'settings.navbar.help': '帮助中心',
|
||||||
|
'settings.help.guide': '新手指引',
|
||||||
|
'settings.help.doc': '帮助文档',
|
||||||
|
'settings.help.APIDoc': 'API文档',
|
||||||
|
'settings.help.version': '版本信息',
|
||||||
'settings.menu': '菜单栏',
|
'settings.menu': '菜单栏',
|
||||||
'settings.tabBar': '多页签',
|
'settings.tabBar': '多页签',
|
||||||
'settings.footer': '底部',
|
'settings.footer': '底部',
|
||||||
|
|
|
@ -4,6 +4,7 @@ import './user';
|
||||||
import './message-box';
|
import './message-box';
|
||||||
import './api-test';
|
import './api-test';
|
||||||
import './system/user';
|
import './system/user';
|
||||||
|
import './system/project';
|
||||||
|
|
||||||
Mock.setup({
|
Mock.setup({
|
||||||
timeout: '600-1000',
|
timeout: '600-1000',
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import Mock from 'mockjs';
|
||||||
|
import setupMock, { successResponseWrap } from '@/utils/setup-mock';
|
||||||
|
|
||||||
|
const getProjectList = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: '0283f238hf2',
|
||||||
|
num: 0,
|
||||||
|
organizationId: 'v3v4h434c3',
|
||||||
|
name: '发了多少',
|
||||||
|
description: 'string',
|
||||||
|
createTime: 0,
|
||||||
|
updateTime: 0,
|
||||||
|
updateUser: 'string',
|
||||||
|
createUser: 'string',
|
||||||
|
deleteTime: 0,
|
||||||
|
deleted: true,
|
||||||
|
deleteUser: 'string',
|
||||||
|
enable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'f9h832',
|
||||||
|
num: 0,
|
||||||
|
organizationId: 'v3v4h434c3',
|
||||||
|
name: '你了大 V',
|
||||||
|
description: 'string',
|
||||||
|
createTime: 0,
|
||||||
|
updateTime: 0,
|
||||||
|
updateUser: 'string',
|
||||||
|
createUser: 'string',
|
||||||
|
deleteTime: 0,
|
||||||
|
deleted: true,
|
||||||
|
deleteUser: 'string',
|
||||||
|
enable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '0v023i92',
|
||||||
|
num: 0,
|
||||||
|
organizationId: 'v3v4h434c3',
|
||||||
|
name: '代付款就是快递方式觉得都是就',
|
||||||
|
description: 'string',
|
||||||
|
createTime: 0,
|
||||||
|
updateTime: 0,
|
||||||
|
updateUser: 'string',
|
||||||
|
createUser: 'string',
|
||||||
|
deleteTime: 0,
|
||||||
|
deleted: true,
|
||||||
|
deleteUser: 'string',
|
||||||
|
enable: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
setupMock({
|
||||||
|
setup: () => {
|
||||||
|
Mock.mock(new RegExp('/system/project/list'), () => {
|
||||||
|
return successResponseWrap(getProjectList());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,16 @@
|
||||||
|
// 项目列表项
|
||||||
|
export interface ProjectListItem {
|
||||||
|
id: string;
|
||||||
|
num: number;
|
||||||
|
organizationId: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
createTime: number;
|
||||||
|
updateTime: number;
|
||||||
|
updateUser: string;
|
||||||
|
createUser: string;
|
||||||
|
deleteTime: number;
|
||||||
|
deleted: boolean;
|
||||||
|
deleteUser: string;
|
||||||
|
enable: boolean;
|
||||||
|
}
|
|
@ -1,21 +1,30 @@
|
||||||
|
// 路由白名单,无需校验权限与登录状态
|
||||||
export const WHITE_LIST = [
|
export const WHITE_LIST = [
|
||||||
{ name: 'notFound', children: [] },
|
{ name: 'notFound', children: [] },
|
||||||
{ name: 'login', children: [] },
|
{ name: 'login', children: [] },
|
||||||
{ name: 'invite', children: [] },
|
{ name: 'invite', children: [] },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 左侧菜单底部对齐的菜单数组,数组项为一级路由的name
|
||||||
export const BOTTOM_MENU_LIST = ['setting'];
|
export const BOTTOM_MENU_LIST = ['setting'];
|
||||||
|
|
||||||
|
// 404 路由
|
||||||
export const NOT_FOUND = {
|
export const NOT_FOUND = {
|
||||||
name: 'notFound',
|
name: 'notFound',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 重定向中转站路由
|
||||||
export const REDIRECT_ROUTE_NAME = 'Redirect';
|
export const REDIRECT_ROUTE_NAME = 'Redirect';
|
||||||
|
|
||||||
|
// 首页路由
|
||||||
export const DEFAULT_ROUTE_NAME = 'Workplace';
|
export const DEFAULT_ROUTE_NAME = 'Workplace';
|
||||||
|
|
||||||
|
// 默认 tab-bar 路,多页签模式下,打开的第一个页面
|
||||||
export const DEFAULT_ROUTE = {
|
export const DEFAULT_ROUTE = {
|
||||||
title: 'menu.dashboard.workplace',
|
title: 'menu.dashboard.workplace',
|
||||||
name: DEFAULT_ROUTE_NAME,
|
name: DEFAULT_ROUTE_NAME,
|
||||||
fullPath: '/dashboard/workplace',
|
fullPath: '/dashboard/workplace',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 不需要显示项目选择器的模块,数组项为一级路由的path
|
||||||
|
export const NOT_SHOW_PROJECT_SELECT_MODULE = ['setting'];
|
||||||
|
|
|
@ -9,11 +9,12 @@ const ApiTest: AppRouteRecordRaw = {
|
||||||
locale: 'menu.apiTest',
|
locale: 'menu.apiTest',
|
||||||
icon: 'icon-dashboard',
|
icon: 'icon-dashboard',
|
||||||
order: 0,
|
order: 0,
|
||||||
|
hideChildrenInMenu: true,
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'list',
|
path: 'list',
|
||||||
name: 'apiTest',
|
name: 'apiTestList',
|
||||||
component: () => import('@/views/api-test/index.vue'),
|
component: () => import('@/views/api-test/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
locale: 'menu.apiTest',
|
locale: 'menu.apiTest',
|
||||||
|
|
|
@ -9,7 +9,14 @@ import type { NotificationReturn } from '@arco-design/web-vue/es/notification/in
|
||||||
import type { RouteRecordNormalized, RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordNormalized, RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
const useAppStore = defineStore('app', {
|
const useAppStore = defineStore('app', {
|
||||||
state: (): AppState => ({ ...defaultSettings, loading: false, loadingTip: '', topMenus: [] as RouteRecordRaw[] }),
|
state: (): AppState => ({
|
||||||
|
...defaultSettings,
|
||||||
|
loading: false,
|
||||||
|
loadingTip: '',
|
||||||
|
topMenus: [] as RouteRecordRaw[],
|
||||||
|
currentOrgId: '',
|
||||||
|
currentProjectId: '',
|
||||||
|
}),
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
appCurrentSetting(state: AppState): AppState {
|
appCurrentSetting(state: AppState): AppState {
|
||||||
|
@ -30,6 +37,12 @@ const useAppStore = defineStore('app', {
|
||||||
getTopMenus(state: AppState): RouteRecordRaw[] {
|
getTopMenus(state: AppState): RouteRecordRaw[] {
|
||||||
return state.topMenus;
|
return state.topMenus;
|
||||||
},
|
},
|
||||||
|
getCurrentOrgId(state: AppState): string {
|
||||||
|
return state.currentOrgId;
|
||||||
|
},
|
||||||
|
getCurrentProjectId(state: AppState): string {
|
||||||
|
return state.currentProjectId;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -111,6 +124,21 @@ const useAppStore = defineStore('app', {
|
||||||
setTopMenus(menus: RouteRecordRaw[] | undefined) {
|
setTopMenus(menus: RouteRecordRaw[] | undefined) {
|
||||||
this.topMenus = menus ? [...menus] : [];
|
this.topMenus = menus ? [...menus] : [];
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 设置当前组织 ID
|
||||||
|
*/
|
||||||
|
setCurrentOrgId(id: string) {
|
||||||
|
this.currentOrgId = id;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 设置当前项目 ID
|
||||||
|
*/
|
||||||
|
setCurrentProjectId(id: string) {
|
||||||
|
this.currentProjectId = id;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
paths: ['currentOrgId', 'currentProjectId'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ export interface AppState {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
loadingTip: string;
|
loadingTip: string;
|
||||||
topMenus: RouteRecordRaw[];
|
topMenus: RouteRecordRaw[];
|
||||||
|
currentOrgId: string;
|
||||||
|
currentProjectId: string;
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,11 @@ const useUserStore = defineStore('user', {
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
async info() {
|
async info() {
|
||||||
const res = await getUserInfo();
|
const res = await getUserInfo();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
if (appStore.currentOrgId === '') {
|
||||||
|
// 第一次进系统才设置组织 ID,后续已经持久化存储了
|
||||||
|
appStore.setCurrentOrgId(res.organization || '');
|
||||||
|
}
|
||||||
this.setInfo(res);
|
this.setInfo(res);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue