菜单、菜单筛选、个人中心、基本信息、切换用户
Frontend CI/CD / build (web-office) (push) Failing after 11s
Details
Frontend CI/CD / build (web-office) (push) Failing after 11s
Details
This commit is contained in:
parent
3e41e8ca50
commit
154c104148
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
|
@ -20,6 +20,9 @@ import { $t } from '#/locales';
|
|||
import { useAuthStore } from '#/store';
|
||||
import LoginForm from '#/views/_core/authentication/login.vue';
|
||||
|
||||
import { UserInfo,UserSwitch,UserLike } from '#/layouts/user';
|
||||
|
||||
|
||||
const notifications = ref<NotificationItem[]>([
|
||||
{
|
||||
avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB',
|
||||
|
@ -61,27 +64,21 @@ const showDot = computed(() =>
|
|||
const menus = computed(() => [
|
||||
{
|
||||
handler: () => {
|
||||
openWindow(VBEN_DOC_URL, {
|
||||
target: '_blank',
|
||||
});
|
||||
infoVisible.value = true
|
||||
},
|
||||
icon: BookOpenText,
|
||||
text: '个人信息',
|
||||
},
|
||||
{
|
||||
handler: () => {
|
||||
openWindow(VBEN_GITHUB_URL, {
|
||||
target: '_blank',
|
||||
});
|
||||
switchVisible.value = true
|
||||
},
|
||||
icon: MdiGithub,
|
||||
text: '切换租户',
|
||||
},
|
||||
{
|
||||
handler: () => {
|
||||
openWindow(`${VBEN_GITHUB_URL}/issues`, {
|
||||
target: '_blank',
|
||||
});
|
||||
likeVisible.value = true
|
||||
},
|
||||
icon: CircleHelp,
|
||||
text: '个人偏好',
|
||||
|
@ -103,6 +100,10 @@ function handleNoticeClear() {
|
|||
function handleMakeAll() {
|
||||
notifications.value.forEach((item) => (item.isRead = true));
|
||||
}
|
||||
|
||||
let infoVisible = ref(false)
|
||||
let switchVisible = ref(false)
|
||||
let likeVisible = ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -110,7 +111,7 @@ function handleMakeAll() {
|
|||
|
||||
<template #user-dropdown>
|
||||
<UserDropdown :avatar :menus :text="userStore.userInfo?.realName"
|
||||
@logout="handleLogout" :hideLockLcreen="true" />
|
||||
@logout="handleLogout" />
|
||||
</template>
|
||||
<template #notification>
|
||||
<Notification :dot="showDot" :notifications="notifications" @clear="handleNoticeClear" :icColor="'#fff'"
|
||||
|
@ -125,4 +126,8 @@ function handleMakeAll() {
|
|||
<LockScreen :avatar @to-login="handleLogout" />
|
||||
</template>
|
||||
</BasicLayout>
|
||||
|
||||
<UserInfo v-model:visible="infoVisible"></UserInfo>
|
||||
<UserSwitch v-model:visible="switchVisible"></UserSwitch>
|
||||
<UserLike v-model:visible="likeVisible"></UserLike>
|
||||
</template>
|
||||
|
|
|
@ -3,10 +3,9 @@ import { computed, useSlots } from 'vue';
|
|||
|
||||
import { preferences, usePreferences } from '@vben/preferences';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import { VbenFullScreen } from '@vben-core/shadcn-ui';
|
||||
import VbenFullScreen from './../../full-screen/full-screen.vue';
|
||||
|
||||
import {
|
||||
GlobalSearch,
|
||||
LanguageToggle,
|
||||
PreferencesButton,
|
||||
ThemeToggle,
|
||||
|
@ -121,11 +120,6 @@ function clearPreferencesAndLogout() {
|
|||
<template v-for="slot in rightSlots" :key="slot.name">
|
||||
<slot :name="slot.name">
|
||||
<template v-if="slot.name === 'global-search'">
|
||||
<!-- <GlobalSearch
|
||||
:enable-shortcut-key="globalSearchShortcutKey"
|
||||
:menus="accessStore.accessMenus"
|
||||
class="mr-1 sm:mr-4"
|
||||
/> -->
|
||||
</template>
|
||||
|
||||
<template v-else-if="slot.name === 'preferences'">
|
||||
|
|
|
@ -13,7 +13,8 @@ import {
|
|||
import { useLockStore, useUserStore } from '@vben/stores';
|
||||
import { deepToRaw, mapTree } from '@vben/utils';
|
||||
import { VbenAdminLayout } from '@vben-core/layout-ui';
|
||||
import { Toaster, VbenBackTop, VbenLogo } from '@vben-core/shadcn-ui';
|
||||
import { Toaster, VbenBackTop } from '@vben-core/shadcn-ui';
|
||||
import { VbenLogo } from '#/layouts/logo';
|
||||
|
||||
import { Breadcrumb, CheckUpdates, Preferences } from '@vben/layouts';
|
||||
import { LayoutContent, LayoutContentSpinner } from './content';
|
||||
|
@ -201,6 +202,7 @@ const headerSlots = computed(() => {
|
|||
:text="'西北油田办公平台'"
|
||||
:theme="'!white'"
|
||||
:textClass="'text-white text-2xl'"
|
||||
:logoSize="100"
|
||||
/>
|
||||
</template>
|
||||
<!-- 头部区域 -->
|
||||
|
|
|
@ -4,6 +4,10 @@ import type { MenuProps } from '@vben-core/menu-ui';
|
|||
|
||||
import { Menu } from '@vben-core/menu-ui';
|
||||
|
||||
import {
|
||||
GlobalSearch,
|
||||
} from './../../global-search';
|
||||
|
||||
interface Props extends MenuProps {
|
||||
menus: MenuRecordRaw[];
|
||||
}
|
||||
|
@ -20,9 +24,20 @@ const emit = defineEmits<{
|
|||
function handleMenuSelect(key: string) {
|
||||
emit('select', key, props.mode);
|
||||
}
|
||||
|
||||
import { usePreferences } from '@vben/preferences';
|
||||
const {globalSearchShortcutKey } = usePreferences();
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
const accessStore = useAccessStore();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<GlobalSearch
|
||||
:enable-shortcut-key="globalSearchShortcutKey"
|
||||
:menus="accessStore.accessMenus"
|
||||
class="mr-1 sm:mr-4 pl-3 my-3"
|
||||
/>
|
||||
<Menu
|
||||
:accordion="accordion"
|
||||
:collapse="collapse"
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<script lang="ts" setup>
|
||||
import { Maximize, Minimize } from '@vben/icons';
|
||||
|
||||
import { useFullscreen } from '@vueuse/core';
|
||||
|
||||
|
||||
import {
|
||||
VbenIconButton,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
|
||||
defineOptions({ name: 'FullScreen' });
|
||||
|
||||
const { isFullscreen, toggle } = useFullscreen();
|
||||
|
||||
// 重新检查全屏状态
|
||||
isFullscreen.value = !!(
|
||||
document.fullscreenElement ||
|
||||
// @ts-ignore
|
||||
document.webkitFullscreenElement ||
|
||||
// @ts-ignore
|
||||
document.mozFullScreenElement ||
|
||||
// @ts-ignore
|
||||
document.msFullscreenElement
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<VbenIconButton @click="toggle" class="hover:text-[#007da3] text-white">
|
||||
<Minimize v-if="isFullscreen" class="size-4 hover:text-[#007da3]" />
|
||||
<Maximize v-else class="size-4 hover:text-[#007da3]" />
|
||||
</VbenIconButton>
|
||||
</template>
|
|
@ -0,0 +1 @@
|
|||
export { default as VbenFullScreen } from './full-screen.vue';
|
|
@ -0,0 +1,144 @@
|
|||
<script setup lang="ts">
|
||||
import type { MenuRecordRaw } from '@vben/types';
|
||||
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import {
|
||||
ArrowDown,
|
||||
ArrowUp,
|
||||
CornerDownLeft,
|
||||
MdiKeyboardEsc,
|
||||
Search,
|
||||
} from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
import { isWindowsOs } from '@vben/utils';
|
||||
import { useVbenModal } from '@vben-core/popup-ui';
|
||||
|
||||
import { useMagicKeys, whenever } from '@vueuse/core';
|
||||
|
||||
import SearchPanel from './search-panel.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'GlobalSearch',
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ enableShortcutKey?: boolean; menus: MenuRecordRaw[] }>(),
|
||||
{
|
||||
enableShortcutKey: true,
|
||||
menus: () => [],
|
||||
},
|
||||
);
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
});
|
||||
const open = modalApi.useStore((state) => state.isOpen);
|
||||
|
||||
const keyword = ref('');
|
||||
const searchInputRef = ref<HTMLInputElement>();
|
||||
|
||||
function handleClose() {
|
||||
modalApi.close();
|
||||
keyword.value = '';
|
||||
}
|
||||
|
||||
const keys = useMagicKeys();
|
||||
const cmd = isWindowsOs() ? keys['ctrl+k'] : keys['cmd+k'];
|
||||
whenever(cmd!, () => {
|
||||
if (props.enableShortcutKey) {
|
||||
modalApi.open();
|
||||
}
|
||||
});
|
||||
|
||||
whenever(open, () => {
|
||||
nextTick(() => {
|
||||
searchInputRef.value?.focus();
|
||||
});
|
||||
});
|
||||
|
||||
const preventDefaultBrowserSearchHotKey = (event: KeyboardEvent) => {
|
||||
if (event.key?.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
const toggleKeydownListener = () => {
|
||||
if (props.enableShortcutKey) {
|
||||
window.addEventListener('keydown', preventDefaultBrowserSearchHotKey);
|
||||
} else {
|
||||
window.removeEventListener('keydown', preventDefaultBrowserSearchHotKey);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleOpen = () => {
|
||||
open.value ? modalApi.close() : modalApi.open();
|
||||
};
|
||||
|
||||
watch(() => props.enableShortcutKey, toggleKeydownListener);
|
||||
|
||||
onMounted(() => {
|
||||
toggleKeydownListener();
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', preventDefaultBrowserSearchHotKey);
|
||||
});
|
||||
});
|
||||
|
||||
import { usePreferences } from '@vben/preferences';
|
||||
|
||||
const {sidebarCollapsed } = usePreferences();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Modal :fullscreen-button="false" class="w-[600px]" header-class="py-2">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
<Search class="text-muted-foreground mr-2 size-4" />
|
||||
<input ref="searchInputRef" v-model="keyword" :placeholder="$t('widgets.search.searchNavigate')"
|
||||
class="ring-none placeholder:text-muted-foreground w-[80%] rounded-md border border-none bg-transparent p-2 pl-0 text-sm font-normal outline-none ring-0 ring-offset-transparent focus-visible:ring-transparent" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<SearchPanel :keyword="keyword" :menus="menus" @close="handleClose" />
|
||||
<template #footer>
|
||||
<div class="flex w-full justify-start text-xs">
|
||||
<div class="mr-2 flex items-center">
|
||||
<CornerDownLeft class="mr-1 size-3" />
|
||||
{{ $t('widgets.search.select') }}
|
||||
</div>
|
||||
<div class="mr-2 flex items-center">
|
||||
<ArrowUp class="mr-1 size-3" />
|
||||
<ArrowDown class="mr-1 size-3" />
|
||||
{{ $t('widgets.search.navigate') }}
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<MdiKeyboardEsc class="mr-1 size-3" />
|
||||
{{ $t('widgets.search.close') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
<div v-if="!sidebarCollapsed"
|
||||
class="md:bg-accent group flex h-8 cursor-pointer items-center gap-3 rounded-2xl border-none bg-none px-2 py-0.5 outline-none"
|
||||
@click="toggleOpen()">
|
||||
<Search class="text-muted-foreground group-hover:text-foreground size-4 group-hover:opacity-100" />
|
||||
<span class="text-muted-foreground group-hover:text-foreground hidden text-xs duration-300 md:block">
|
||||
{{ $t('widgets.search.title') }}
|
||||
</span>
|
||||
<span v-if="enableShortcutKey"
|
||||
class="bg-background border-foreground/60 text-muted-foreground group-hover:text-foreground relative hidden rounded-sm rounded-r-xl px-1.5 py-1 text-xs leading-none group-hover:opacity-100 md:block">
|
||||
{{ isWindowsOs() ? 'Ctrl' : '⌘' }}
|
||||
<kbd>K</kbd>
|
||||
</span>
|
||||
<span v-else></span>
|
||||
</div>
|
||||
<div v-else class="rounded-full w100% flex justify-center">
|
||||
<Search class="text-muted-foreground group-hover:text-foreground size-4 group-hover:opacity-100" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1 @@
|
|||
export { default as GlobalSearch } from './global-search.vue';
|
|
@ -0,0 +1,287 @@
|
|||
<script setup lang="ts">
|
||||
import type { MenuRecordRaw } from '@vben/types';
|
||||
|
||||
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { SearchX, X } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
import { mapTree, traverseTreeValues, uniqueByField } from '@vben/utils';
|
||||
import { VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
|
||||
import { isHttpUrl } from '@vben-core/shared/utils';
|
||||
|
||||
import { onKeyStroke, useLocalStorage, useThrottleFn } from '@vueuse/core';
|
||||
|
||||
defineOptions({
|
||||
name: 'SearchPanel',
|
||||
});
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{ keyword: string; menus: MenuRecordRaw[] }>(),
|
||||
{
|
||||
keyword: '',
|
||||
menus: () => [],
|
||||
},
|
||||
);
|
||||
const emit = defineEmits<{ close: [] }>();
|
||||
|
||||
const router = useRouter();
|
||||
const searchHistory = useLocalStorage<MenuRecordRaw[]>(
|
||||
`__search-history-${location.hostname}__`,
|
||||
[],
|
||||
);
|
||||
const activeIndex = ref(-1);
|
||||
const searchItems = shallowRef<MenuRecordRaw[]>([]);
|
||||
const searchResults = ref<MenuRecordRaw[]>([]);
|
||||
|
||||
const handleSearch = useThrottleFn(search, 200);
|
||||
|
||||
// 搜索函数,用于根据搜索关键词查找匹配的菜单项
|
||||
function search(searchKey: string) {
|
||||
// 去除搜索关键词的前后空格
|
||||
searchKey = searchKey.trim();
|
||||
|
||||
// 如果搜索关键词为空,清空搜索结果并返回
|
||||
if (!searchKey) {
|
||||
searchResults.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用搜索关键词创建正则表达式
|
||||
const reg = createSearchReg(searchKey);
|
||||
|
||||
// 初始化结果数组
|
||||
const results: MenuRecordRaw[] = [];
|
||||
|
||||
// 遍历搜索项
|
||||
traverseTreeValues(searchItems.value, (item) => {
|
||||
// 如果菜单项的名称匹配正则表达式,将其添加到结果数组中
|
||||
if (reg.test(item.name?.toLowerCase())) {
|
||||
results.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
// 更新搜索结果
|
||||
searchResults.value = results;
|
||||
|
||||
// 如果有搜索结果,设置索引为 0
|
||||
if (results.length > 0) {
|
||||
activeIndex.value = 0;
|
||||
}
|
||||
|
||||
// 赋值索引为 0
|
||||
activeIndex.value = 0;
|
||||
}
|
||||
|
||||
// When the keyboard up and down keys move to an invisible place
|
||||
// the scroll bar needs to scroll automatically
|
||||
function scrollIntoView() {
|
||||
const element = document.querySelector(
|
||||
`[data-search-item="${activeIndex.value}"]`,
|
||||
);
|
||||
|
||||
if (element) {
|
||||
element.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
}
|
||||
|
||||
// enter keyboard event
|
||||
async function handleEnter() {
|
||||
if (searchResults.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
const result = searchResults.value;
|
||||
const index = activeIndex.value;
|
||||
if (result.length === 0 || index < 0) {
|
||||
return;
|
||||
}
|
||||
const to = result[index];
|
||||
if (to) {
|
||||
searchHistory.value.push(to);
|
||||
handleClose();
|
||||
await nextTick();
|
||||
if (isHttpUrl(to.path)) {
|
||||
window.open(to.path, '_blank');
|
||||
} else {
|
||||
router.push({ path: to.path, replace: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow key up
|
||||
function handleUp() {
|
||||
if (searchResults.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
activeIndex.value--;
|
||||
if (activeIndex.value < 0) {
|
||||
activeIndex.value = searchResults.value.length - 1;
|
||||
}
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
// Arrow key down
|
||||
function handleDown() {
|
||||
if (searchResults.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
activeIndex.value++;
|
||||
if (activeIndex.value > searchResults.value.length - 1) {
|
||||
activeIndex.value = 0;
|
||||
}
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
// close search modal
|
||||
function handleClose() {
|
||||
searchResults.value = [];
|
||||
emit('close');
|
||||
}
|
||||
|
||||
// Activate when the mouse moves to a certain line
|
||||
function handleMouseenter(e: MouseEvent) {
|
||||
const index = (e.target as HTMLElement)?.dataset.index;
|
||||
activeIndex.value = Number(index);
|
||||
}
|
||||
|
||||
function removeItem(index: number) {
|
||||
if (props.keyword) {
|
||||
searchResults.value.splice(index, 1);
|
||||
} else {
|
||||
searchHistory.value.splice(index, 1);
|
||||
}
|
||||
activeIndex.value = activeIndex.value - 1 >= 0 ? activeIndex.value - 1 : 0;
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
// 存储所有需要转义的特殊字符
|
||||
const code = new Set([
|
||||
'$',
|
||||
'(',
|
||||
')',
|
||||
'*',
|
||||
'+',
|
||||
'.',
|
||||
'?',
|
||||
'[',
|
||||
'\\',
|
||||
']',
|
||||
'^',
|
||||
'{',
|
||||
'|',
|
||||
'}',
|
||||
]);
|
||||
|
||||
// 转换函数,用于转义特殊字符
|
||||
function transform(c: string) {
|
||||
// 如果字符在特殊字符列表中,返回转义后的字符
|
||||
// 如果不在,返回字符本身
|
||||
return code.has(c) ? `\\${c}` : c;
|
||||
}
|
||||
|
||||
// 创建搜索正则表达式
|
||||
function createSearchReg(key: string) {
|
||||
// 将输入的字符串拆分为单个字符
|
||||
// 对每个字符进行转义
|
||||
// 然后用'.*'连接所有字符,创建正则表达式
|
||||
const keys = [...key].map((item) => transform(item)).join('.*');
|
||||
// 返回创建的正则表达式
|
||||
return new RegExp(`.*${keys}.*`);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.keyword,
|
||||
(val) => {
|
||||
if (val) {
|
||||
handleSearch(val);
|
||||
} else {
|
||||
searchResults.value = [...searchHistory.value];
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
searchItems.value = mapTree(props.menus, (item) => {
|
||||
return {
|
||||
...item,
|
||||
name: $t(item?.name),
|
||||
};
|
||||
});
|
||||
if (searchHistory.value.length > 0) {
|
||||
searchResults.value = searchHistory.value;
|
||||
}
|
||||
// enter search
|
||||
onKeyStroke('Enter', handleEnter);
|
||||
// Monitor keyboard arrow keys
|
||||
onKeyStroke('ArrowUp', handleUp);
|
||||
onKeyStroke('ArrowDown', handleDown);
|
||||
// esc close
|
||||
onKeyStroke('Escape', handleClose);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VbenScrollbar>
|
||||
<div class="!flex h-full justify-center px-2 sm:max-h-[450px]">
|
||||
<!-- 无搜索结果 -->
|
||||
<div
|
||||
v-if="keyword && searchResults.length === 0"
|
||||
class="text-muted-foreground text-center"
|
||||
>
|
||||
<SearchX class="mx-auto mt-4 size-12" />
|
||||
<p class="mb-10 mt-6 text-xs">
|
||||
{{ $t('widgets.search.noResults') }}
|
||||
<span class="text-foreground text-sm font-medium">
|
||||
"{{ keyword }}"
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- 历史搜索记录 & 没有搜索结果 -->
|
||||
<div
|
||||
v-if="!keyword && searchResults.length === 0"
|
||||
class="text-muted-foreground text-center"
|
||||
>
|
||||
<p class="my-10 text-xs">
|
||||
{{ $t('widgets.search.noRecent') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ul v-show="searchResults.length > 0" class="w-full">
|
||||
<li
|
||||
v-if="searchHistory.length > 0 && !keyword"
|
||||
class="text-muted-foreground mb-2 text-xs"
|
||||
>
|
||||
{{ $t('widgets.search.recent') }}
|
||||
</li>
|
||||
<li
|
||||
v-for="(item, index) in uniqueByField(searchResults, 'path')"
|
||||
:key="item.path"
|
||||
:class="
|
||||
activeIndex === index
|
||||
? 'active bg-primary text-primary-foreground'
|
||||
: ''
|
||||
"
|
||||
:data-index="index"
|
||||
:data-search-item="index"
|
||||
class="bg-accent flex-center group mb-3 w-full cursor-pointer rounded-lg px-4 py-4"
|
||||
@click="handleEnter"
|
||||
@mouseenter="handleMouseenter"
|
||||
>
|
||||
<VbenIcon
|
||||
:icon="item.icon"
|
||||
class="mr-2 size-5 flex-shrink-0"
|
||||
fallback
|
||||
/>
|
||||
|
||||
<span class="flex-1">{{ item.name }}</span>
|
||||
<div
|
||||
class="flex-center dark:hover:bg-accent hover:text-primary-foreground rounded-full p-1 hover:scale-110"
|
||||
@click.stop="removeItem(index)"
|
||||
>
|
||||
<X class="size-4" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</VbenScrollbar>
|
||||
</template>
|
|
@ -0,0 +1 @@
|
|||
export { default as VbenLogo } from './logo.vue';
|
|
@ -0,0 +1,59 @@
|
|||
<script setup lang="ts">
|
||||
// import { VbenAvatar } from '../avatar';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* @zh_CN 是否收起文本
|
||||
*/
|
||||
collapsed?: boolean;
|
||||
/**
|
||||
* @zh_CN Logo 跳转地址
|
||||
*/
|
||||
href?: string;
|
||||
/**
|
||||
* @zh_CN Logo 图片大小
|
||||
*/
|
||||
logoSize?: number;
|
||||
/**
|
||||
* @zh_CN Logo 图标
|
||||
*/
|
||||
src?: string;
|
||||
/**
|
||||
* @zh_CN Logo 文本
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* @zh_CN Logo 主题
|
||||
*/
|
||||
theme?: string;
|
||||
/**
|
||||
* logo字体颜色
|
||||
*/
|
||||
textClass?: string;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'VbenLogo',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
collapsed: false,
|
||||
href: 'javascript:void 0',
|
||||
logoSize: 32,
|
||||
src: '',
|
||||
theme: 'light',
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="theme" class="flex h-full items-center text-lg">
|
||||
<a :class="$attrs.class" :href="href"
|
||||
class="flex h-full items-center gap-2 overflow-hidden px-3 text-lg leading-normal transition-all duration-500">
|
||||
<!-- <VbenAvatar v-if="src" :alt="text" :src="src" :size="logoSize" class="relative w-8 rounded-none bg-transparent" /> -->
|
||||
<img v-if="src" :alt="text" :src="src" class="relative rounded-none bg-transparent w-100" >
|
||||
<span v-if="!collapsed" class="text-foreground truncate text-nowrap font-semibold" :class="textClass">
|
||||
{{ text }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,3 @@
|
|||
export { default as UserInfo } from './info.vue';
|
||||
export { default as UserLike } from './like.vue';
|
||||
export { default as UserSwitch } from './switch.vue';
|
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<Modal title="基本信息" :visible="visible" :cancelText="'关闭'" @cancel="close">
|
||||
<Form :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<FormItem label="头像" class="mb-3">
|
||||
<upload v-model:file-list="fileList" name="avatar" list-type="picture-card" class="avatar-uploader"
|
||||
:show-upload-list="false" action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||||
:before-upload="beforeUpload" @change="handleChange">
|
||||
<img v-if="imageUrl" :src="imageUrl" alt="avatar" />
|
||||
<div v-else>
|
||||
<loading-outlined v-if="loading"></loading-outlined>
|
||||
<plus-outlined v-else></plus-outlined>
|
||||
<div class="ant-upload-text">上传头像</div>
|
||||
</div>
|
||||
</upload>
|
||||
</FormItem>
|
||||
<FormItem :label="item.label" v-for="item in userData" :key="item.label" class="mb-3">
|
||||
{{ item.value }}
|
||||
</FormItem>
|
||||
</Form>
|
||||
<a href="#" class="text-[#007da3] ml-24">基本信息请至统一身份管理系统修改</a>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Modal, Form, FormItem ,Upload } from 'ant-design-vue';
|
||||
import { ref } from 'vue';
|
||||
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';
|
||||
|
||||
function getBase64(img: Blob, callback: (base64Url: string) => void) {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', () => callback(reader.result as string));
|
||||
reader.readAsDataURL(img);
|
||||
}
|
||||
|
||||
const fileList = ref([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const imageUrl = ref<string>('');
|
||||
|
||||
const handleChange = (info: UploadChangeParam) => {
|
||||
if (info.file.status === 'uploading') {
|
||||
loading.value = true;
|
||||
return;
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
// Get this url from response in real world.
|
||||
getBase64(info.file.originFileObj, (base64Url: string) => {
|
||||
imageUrl.value = base64Url;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
if (info.file.status === 'error') {
|
||||
loading.value = false;
|
||||
message.error('upload error');
|
||||
}
|
||||
};
|
||||
|
||||
const beforeUpload = (file: UploadProps['fileList'][number]) => {
|
||||
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
||||
if (!isJpgOrPng) {
|
||||
message.error('You can only upload JPG file!');
|
||||
}
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
if (!isLt2M) {
|
||||
message.error('Image must smaller than 2MB!');
|
||||
}
|
||||
return isJpgOrPng && isLt2M;
|
||||
};
|
||||
|
||||
const visible = defineModel<boolean>('visible');
|
||||
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
let userData = [{
|
||||
label: '姓名',
|
||||
value: '薛雄'
|
||||
}, {
|
||||
label: '登录名',
|
||||
value: 'xuex23'
|
||||
}, {
|
||||
label: '性别',
|
||||
value: '男'
|
||||
}, {
|
||||
label: '员工编号',
|
||||
value: '00454711'
|
||||
}, {
|
||||
label: '机构单位',
|
||||
value: '综合管理部(党委办公室)'
|
||||
}, {
|
||||
label: '邮件地址',
|
||||
value: '123@163.com'
|
||||
}]
|
||||
</script>
|
||||
<style scoped>
|
||||
.avatar-uploader > .ant-upload {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
.ant-upload-select-picture-card i {
|
||||
font-size: 32px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.ant-upload-select-picture-card .ant-upload-text {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<Modal title="个人偏好" :visible="visible" @cancel="close">
|
||||
<Tabs v-model:activeKey="activeKey" centered>
|
||||
<TabPane key="1" tab="自定义菜单">Content of Tab Pane 1</TabPane>
|
||||
<TabPane key="2" tab="菜单区设置" force-render>Content of Tab Pane 2</TabPane>
|
||||
<TabPane key="3" tab="主题设置">Content of Tab Pane 3</TabPane>
|
||||
<TabPane key="4" tab="消息语音">Content of Tab Pane 4</TabPane>
|
||||
</Tabs>
|
||||
<template #footer>
|
||||
<Button type="link" key="back" @click="close">恢复</Button>
|
||||
<Button key="back" @click="close">取消</Button>
|
||||
<Button key="submit" type="primary" @click="close">确定</Button>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Modal, Tabs, Form, FormItem, Select, Button, TabPane } from 'ant-design-vue';
|
||||
import { ref } from 'vue';
|
||||
let activeKey = ref('1');
|
||||
let options1 = [
|
||||
{
|
||||
value: '1',
|
||||
label: '西北油田(xbyt)',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '智能油气田(znyqt)',
|
||||
}
|
||||
]
|
||||
|
||||
const visible = defineModel<boolean>('visible');
|
||||
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<Modal title="切换租户" :visible="visible" @cancel="close">
|
||||
<!-- <div class="flex justify-center mb-10">请选择您要切换到的租户</div> -->
|
||||
<Form :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||
<FormItem label="请选择租户">
|
||||
<Select ref="select" v-model:value="value1" :options="options1"></Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Modal, Form, FormItem, Select } from 'ant-design-vue';
|
||||
import { ref } from 'vue';
|
||||
let value1 = ref('1');
|
||||
let options1 = [
|
||||
{
|
||||
value: '1',
|
||||
label: '西北油田(xbyt)',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '智能油气田(znyqt)',
|
||||
}
|
||||
]
|
||||
|
||||
const visible = defineModel<boolean>('visible');
|
||||
|
||||
const close = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
</script>
|
|
@ -30,7 +30,13 @@ export const overridesPreferences = defineOverridesPreferences({
|
|||
preferencesButtonPosition: 'auto',
|
||||
watermark: false,
|
||||
},
|
||||
logo: {
|
||||
source: '/logo1.png',
|
||||
},
|
||||
shortcutKeys: {
|
||||
globalSearch: false,
|
||||
},
|
||||
header: {
|
||||
height: 60,
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,6 +2,54 @@ import type { RouteRecordRaw } from 'vue-router';
|
|||
|
||||
import { BasicLayout } from '#/layouts';
|
||||
|
||||
import { firstRouter, otherRouter } from "./linkdata"
|
||||
|
||||
const getRouter = (list: any, type: string) => {
|
||||
let obj = [];
|
||||
if (type == 'first') {
|
||||
for (let i = 0; i < list.children.length; i++) {
|
||||
obj.push({
|
||||
name: list.children[i]?.rName,
|
||||
path: '',
|
||||
component: () => null,
|
||||
meta: {
|
||||
title: list.children[i]?.name,
|
||||
link: list.children[i]?.url
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let chunk:any = {}
|
||||
chunk.component = BasicLayout;
|
||||
chunk.meta = {
|
||||
icon: 'lucide:layout-dashboard',
|
||||
title: list[i].name,
|
||||
order: i,
|
||||
};
|
||||
chunk.name = list[i].rName;
|
||||
chunk.path = '/'+list[i].rName;
|
||||
|
||||
chunk.children = [];
|
||||
for (let j = 0; j < list[i].children.length; j++) {
|
||||
chunk.children.push({
|
||||
name: list[i].children[j]?.rName,
|
||||
path: '',
|
||||
component: () => null,
|
||||
meta: {
|
||||
title: list[i].children[j]?.name,
|
||||
link: list[i].children[j]?.url
|
||||
},
|
||||
})
|
||||
}
|
||||
obj.push(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
component: BasicLayout,
|
||||
|
@ -10,7 +58,7 @@ const routes: RouteRecordRaw[] = [
|
|||
order: -1,
|
||||
title: '总部系统',
|
||||
},
|
||||
name: 'Dashboard',
|
||||
name: 'zbxt',
|
||||
path: '/home',
|
||||
children: [
|
||||
{
|
||||
|
@ -23,34 +71,39 @@ const routes: RouteRecordRaw[] = [
|
|||
title: '总部系统',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'zshxgw',
|
||||
path: '',
|
||||
component: () => null,
|
||||
meta: {
|
||||
title: '中石化新公文系统',
|
||||
link: 'http://www.baidu.com'
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'zshht',
|
||||
path: '',
|
||||
component: () => null,
|
||||
meta: {
|
||||
title: '中石化合同系统',
|
||||
link: 'http://www.baidu.com'
|
||||
},
|
||||
},
|
||||
|
||||
...getRouter(firstRouter, 'first')
|
||||
// {
|
||||
// name: 'zshxgw',
|
||||
// path: '',
|
||||
// component: () => null,
|
||||
// meta: {
|
||||
// title: '中石化新公文系统',
|
||||
// link: 'http://www.baidu.com'
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'zshht',
|
||||
// path: '',
|
||||
// component: () => null,
|
||||
// meta: {
|
||||
// title: '中石化合同系统',
|
||||
// link: 'http://www.baidu.com'
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'Workspace',
|
||||
// path: '/workspace',
|
||||
// component: () => import('#/views/dashboard/workspace/index.vue'),
|
||||
// component: () => import('#/views/dashboard/wor kspace/index.vue'),
|
||||
// meta: {
|
||||
// title: $t('page.dashboard.workspace'),
|
||||
// },
|
||||
// },
|
||||
],
|
||||
},
|
||||
...getRouter(otherRouter,'other')
|
||||
];
|
||||
|
||||
console.log('999999',...getRouter(otherRouter,'other'));
|
||||
|
||||
export default routes;
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
import type { RouteRecordRaw } from 'vue-router';
|
||||
// import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { BasicLayout } from '#/layouts';
|
||||
import { $t } from '#/locales';
|
||||
// import { BasicLayout } from '#/layouts';
|
||||
// import { $t } from '#/locales';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
component: BasicLayout,
|
||||
meta: {
|
||||
icon: 'ic:baseline-view-in-ar',
|
||||
keepAlive: true,
|
||||
order: 1000,
|
||||
title: $t('page.demos.title'),
|
||||
},
|
||||
name: 'Demos',
|
||||
path: '/demos',
|
||||
children: [
|
||||
{
|
||||
meta: {
|
||||
title: $t('page.demos.antd'),
|
||||
},
|
||||
name: 'AntDesignDemos',
|
||||
path: '/demos/ant-design',
|
||||
component: () => import('#/views/demos/antd/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
// const routes: RouteRecordRaw[] = [
|
||||
// {
|
||||
// component: BasicLayout,
|
||||
// meta: {
|
||||
// icon: 'ic:baseline-view-in-ar',
|
||||
// keepAlive: true,
|
||||
// order: 1000,
|
||||
// title: $t('page.demos.title'),
|
||||
// },
|
||||
// name: 'Demos',
|
||||
// path: '/demos',
|
||||
// children: [
|
||||
// {
|
||||
// meta: {
|
||||
// title: $t('page.demos.antd'),
|
||||
// },
|
||||
// name: 'AntDesignDemos',
|
||||
// path: '/demos/ant-design',
|
||||
// component: () => import('#/views/demos/antd/index.vue'),
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
|
||||
export default routes;
|
||||
// export default routes;
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
let firstRouter = {
|
||||
"name": "总部系统",
|
||||
"children": [
|
||||
{
|
||||
"name": "中石化新公文系统",
|
||||
"url": "https://newoa12.sinopec.com?pageCode=zbxt_new_oa",
|
||||
"rName": "zbxt_new_oa"
|
||||
},
|
||||
{
|
||||
"name": "中石化移动应用平台",
|
||||
"url": "https://console.m.sinopec.com/ACWeb/Portal/IndexPage?pageCode=zbxt_ydyypt",
|
||||
"rName": "zbxt_ydyypt"
|
||||
},
|
||||
{
|
||||
"name": "中石化合同系统",
|
||||
"url": "https://cmis.sinopec.com/zen/portal/#/home?pageCode=zbxt_htxt",
|
||||
"rName": "zbxt_htxt"
|
||||
},
|
||||
{
|
||||
"name": "中石化党群管理系统",
|
||||
"url": "https://dj.sinopec.com?pageCode=zbxt_dqgl",
|
||||
"rName": "zbxt_dqgl"
|
||||
},
|
||||
{
|
||||
"name": "中石化法律共享平台",
|
||||
"url": "http://slsp.sinopec.com?pageCode=zbxt_flgl",
|
||||
"rName": "zbxt_flgl"
|
||||
},
|
||||
{
|
||||
"name": "中石化安全管理系统",
|
||||
"url": "http://safety.sinopec.com:8000/IPWeb/Home?pageCode=zbxt_aqgl",
|
||||
"rName": "zbxt_aqgl"
|
||||
},
|
||||
{
|
||||
"name": "中石化法治合规管理",
|
||||
"url": "https://lcrs.sinopec.com/?pageCode=zbxt_nkglxt",
|
||||
"rName": "zbxt_nkglxt"
|
||||
},
|
||||
{
|
||||
"name": "中石化制度管理系统",
|
||||
"url": "http://10.249.201.77?pageCode=zbxt_zdgl",
|
||||
"rName": "zbxt_zdgl"
|
||||
},
|
||||
{
|
||||
"name": "中石化信息化标准系统",
|
||||
"url": "http://infostd.sinopec.com/?pageCode=zbxt_xxhbz",
|
||||
"rName": "zbxt_xxhbz"
|
||||
},
|
||||
{
|
||||
"name": "中石化网络学院",
|
||||
"url": "https://sia.sinopec.com/learn/index.html?pageCode=zbxt_wlxy",
|
||||
"rName": "zbxt_wlxy"
|
||||
},
|
||||
{
|
||||
"name": "中石化科技管理平台",
|
||||
"url": "http://istm.sinopec.com/?pageCode=zbxt_kjglpt",
|
||||
"rName": "zbxt_kjglpt"
|
||||
},
|
||||
{
|
||||
"name": "中石化信创邮件系统",
|
||||
"url": "https://webmail.sinopec.com/?pageCode=zbxt_xcyj",
|
||||
"rName": "zbxt_xcyj"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
let otherRouter =
|
||||
[
|
||||
{
|
||||
"name": "经营管理",
|
||||
"children": [
|
||||
{
|
||||
"name": "市场管理信息系统",
|
||||
"url": "https://xbscgl.xbyt.sinopec.com?pageCode=jygl_scglxx",
|
||||
"rName": "jygl_scglxx"
|
||||
},
|
||||
{
|
||||
"name": "工程造价管理",
|
||||
"url": "http://10.16.0.157:8082/xbscjyweb?pageCode=jygl_gczjgl",
|
||||
"rName": "jygl_gczjgl"
|
||||
}
|
||||
],
|
||||
"rName": "jygl"
|
||||
},
|
||||
{
|
||||
"name": "勘探开发",
|
||||
"icon": "lucide:area-chart",
|
||||
"children": [
|
||||
{
|
||||
"name": "油气开发平台",
|
||||
"url": "http://yqkfyw.xbyt.sinopec.com/webptframe/home_navtree_hn.html?pageCode=yqkfyw_kfpt",
|
||||
"rName": "yqkfyw_kfpt"
|
||||
},
|
||||
{
|
||||
"name": "地面工程GIS",
|
||||
"url": "https://ssco.xbsj.sinopec.com/DMGCFZ//HomeXBYTGISFront/Index?pageCode=yqkfyw_gis",
|
||||
"rName": "yqkfyw_gis"
|
||||
},
|
||||
{
|
||||
"name": "设备管理系统",
|
||||
"url": "https://sbgl.xbyt.sinopec.com:9006/XBEM?pageCode=yqkfyw_sbxt",
|
||||
"rName": "yqkfyw_sbxt"
|
||||
},
|
||||
{
|
||||
"name": "石油工程决策系统",
|
||||
"url": "https://gcjc.xbyt.sinopec.com?pageCode=yqkfyw_sygc",
|
||||
"rName": "yqkfyw_sygc"
|
||||
},
|
||||
{
|
||||
"name": "完井快报",
|
||||
"url": "http://xbyt.sinopec.com/wczx/Lists/sc/SinopecAllItems.aspx?pageCode=yqkfyw_",
|
||||
"rName": "yqkfyw_"
|
||||
},
|
||||
{
|
||||
"name": "钻井数据库系统",
|
||||
"url": "http://10.16.0.74/tyrz_zjsjk/?pageCode=yqkfyw_zjsjk",
|
||||
"rName": "yqkfyw_zjsjk"
|
||||
},
|
||||
{
|
||||
"name": "完井测试日报",
|
||||
"url": "http://xbyt.sinopec.com/wczx/Lists/kt/SinopecAllItems.aspx?pageCode=yqkfyw_wjcs",
|
||||
"rName": "yqkfyw_wjcs"
|
||||
},
|
||||
{
|
||||
"name": "IPPE",
|
||||
"url": "http://ippe.sinopec.com/?pageCode=yqkfyw_ippe",
|
||||
"rName": "yqkfyw_ippe"
|
||||
}
|
||||
],
|
||||
"rName": "yqkfyw"
|
||||
},
|
||||
{
|
||||
"name": "安全生产",
|
||||
"children": [
|
||||
{
|
||||
"name": "生产重点",
|
||||
"url": "http://10.16.128.237:9528/yxrb/zdbb/scxxyxrb?pageCode=scyx_zdjxx",
|
||||
"rName": "scyx_zdjxx"
|
||||
},
|
||||
{
|
||||
"name": "集输防腐数据平台",
|
||||
"url": "https://dmgcysbgl.xbyt.sinopec.com:8080/xbyqjs//xbjqmh_1.0.0/mh/loginSuccess.action?pageCode=scyx_jsffsj",
|
||||
"rName": "scyx_jsffsj"
|
||||
},
|
||||
{
|
||||
"name": "土地信息管理系统",
|
||||
"url": "http://10.16.0.73:8888/xbtd?pageCode=scyx_tdxxgl",
|
||||
"rName": "scyx_tdxxgl"
|
||||
},
|
||||
{
|
||||
"name": "HSSE管理系统",
|
||||
"url": "http://10.16.128.247:8088/?pageCode=scyx_hseglxx",
|
||||
"rName": "scyx_hseglxx"
|
||||
},
|
||||
{
|
||||
"name": "生产运行(应急)指挥中心协同平台",
|
||||
"url": "http://10.16.66.120:8088/home?pageCode=scyx_yjzhxt",
|
||||
"rName": "scyx_yjzhxt"
|
||||
}
|
||||
],
|
||||
"rName": "scyx"
|
||||
},
|
||||
{
|
||||
"name": "综合行政",
|
||||
"children": [
|
||||
{
|
||||
"name": "领导请销假",
|
||||
"url": "https://10.16.0.128/xjOA/main/login/leave.jsp?pageCode=gcgl_ldqxj",
|
||||
"rName": "gcgl_ldqxj"
|
||||
},
|
||||
{
|
||||
"name": "督办管理",
|
||||
"url": "https://10.16.0.128/xjOA/main/login/urge.jsp?pageCode=gcgl_db",
|
||||
"rName": "gcgl_db"
|
||||
},
|
||||
{
|
||||
"name": "员工诉求",
|
||||
"url": "https://10.16.0.128/xjOA/main/login/appeal.jsp?pageCode=gcgl_ygsq",
|
||||
"rName": "gcgl_ygsq"
|
||||
},
|
||||
{
|
||||
"name": "会议管理系统",
|
||||
"url": "http://10.16.0.128:8089/HYXT/?pageCode=gcgl_hyxt",
|
||||
"rName": "gcgl_hyxt"
|
||||
}
|
||||
],
|
||||
"rName": "gcgl"
|
||||
},
|
||||
{
|
||||
"name": "数据管理",
|
||||
"children": [
|
||||
{
|
||||
"name": "GIS数据服务",
|
||||
"url": "http://10.16.0.210:8017?pageCode=sjgl_gissjfw",
|
||||
"rName": "sjgl_gissjfw"
|
||||
},
|
||||
{
|
||||
"name": "EPBP",
|
||||
"url": "http://10.16.128.130/blankSSO.action?pageCode=sjgl_EPBP_ktkfsjcj",
|
||||
"rName": "sjgl_EPBP_ktkfsjcj"
|
||||
},
|
||||
{
|
||||
"name": "单井数据服务",
|
||||
"url": "https://ssco.xbsj.sinopec.com/djsjfw/goto.html?pageCode=sjgl_djsjfw",
|
||||
"rName": "sjgl_djsjfw"
|
||||
},
|
||||
{
|
||||
"name": "数据管理平台",
|
||||
"url": "http://10.16.3.30:10008/?pageCode=sjgl_sjgl",
|
||||
"rName": "sjgl_sjgl"
|
||||
},
|
||||
{
|
||||
"name": "文档资料共享环境",
|
||||
"url": "https://10.16.67.140/xbsjzlgx/sso?pageCode=sjgl_wdzlgx",
|
||||
"rName": "sjgl_wdzlgx"
|
||||
},
|
||||
{
|
||||
"name": "视频共享平台",
|
||||
"url": "http://10.16.128.81:8020/?pageCode=sjgl_spgxpt",
|
||||
"rName": "sjgl_spgxpt"
|
||||
},
|
||||
{
|
||||
"name": "smartbi报表工具",
|
||||
"url": "http://10.16.67.135:18080/smartbi/vision/index.jsp?pageCode=sjgl_smartbi",
|
||||
"rName": "sjgl_smartbi"
|
||||
}
|
||||
],
|
||||
"rName": "sjgl"
|
||||
}
|
||||
]
|
||||
|
||||
export { firstRouter, otherRouter };
|
|
@ -1,81 +1,81 @@
|
|||
import type { RouteRecordRaw } from 'vue-router';
|
||||
// import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import {
|
||||
VBEN_DOC_URL,
|
||||
VBEN_ELE_PREVIEW_URL,
|
||||
VBEN_GITHUB_URL,
|
||||
VBEN_LOGO_URL,
|
||||
VBEN_NAIVE_PREVIEW_URL,
|
||||
} from '@vben/constants';
|
||||
// import {
|
||||
// VBEN_DOC_URL,
|
||||
// VBEN_ELE_PREVIEW_URL,
|
||||
// VBEN_GITHUB_URL,
|
||||
// VBEN_LOGO_URL,
|
||||
// VBEN_NAIVE_PREVIEW_URL,
|
||||
// } from '@vben/constants';
|
||||
|
||||
import { BasicLayout, IFrameView } from '#/layouts';
|
||||
import { $t } from '#/locales';
|
||||
// import { BasicLayout, IFrameView } from '#/layouts';
|
||||
// import { $t } from '#/locales';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
component: BasicLayout,
|
||||
meta: {
|
||||
badgeType: 'dot',
|
||||
icon: VBEN_LOGO_URL,
|
||||
order: 9999,
|
||||
title: $t('page.vben.title'),
|
||||
},
|
||||
name: 'VbenProject',
|
||||
path: '/vben-admin',
|
||||
children: [
|
||||
{
|
||||
name: 'VbenAbout',
|
||||
path: '/vben-admin/about',
|
||||
component: () => import('#/views/_core/about/index.vue'),
|
||||
meta: {
|
||||
icon: 'lucide:copyright',
|
||||
title: $t('page.vben.about'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'VbenDocument',
|
||||
path: '/vben-admin/document',
|
||||
component: IFrameView,
|
||||
meta: {
|
||||
icon: 'lucide:book-open-text',
|
||||
link: VBEN_DOC_URL,
|
||||
title: $t('page.vben.document'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'VbenGithub',
|
||||
path: '/vben-admin/github',
|
||||
component: IFrameView,
|
||||
meta: {
|
||||
icon: 'mdi:github',
|
||||
link: VBEN_GITHUB_URL,
|
||||
title: 'Github',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'VbenNaive',
|
||||
path: '/vben-admin/naive',
|
||||
component: IFrameView,
|
||||
meta: {
|
||||
badgeType: 'dot',
|
||||
icon: 'logos:naiveui',
|
||||
link: VBEN_NAIVE_PREVIEW_URL,
|
||||
title: $t('page.vben.naive-ui'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'VbenElementPlus',
|
||||
path: '/vben-admin/ele',
|
||||
component: IFrameView,
|
||||
meta: {
|
||||
badgeType: 'dot',
|
||||
icon: 'logos:element',
|
||||
link: VBEN_ELE_PREVIEW_URL,
|
||||
title: $t('page.vben.element-plus'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
// const routes: RouteRecordRaw[] = [
|
||||
// {
|
||||
// component: BasicLayout,
|
||||
// meta: {
|
||||
// badgeType: 'dot',
|
||||
// icon: VBEN_LOGO_URL,
|
||||
// order: 9999,
|
||||
// title: $t('page.vben.title'),
|
||||
// },
|
||||
// name: 'VbenProject',
|
||||
// path: '/vben-admin',
|
||||
// children: [
|
||||
// {
|
||||
// name: 'VbenAbout',
|
||||
// path: '/vben-admin/about',
|
||||
// component: () => import('#/views/_core/about/index.vue'),
|
||||
// meta: {
|
||||
// icon: 'lucide:copyright',
|
||||
// title: $t('page.vben.about'),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'VbenDocument',
|
||||
// path: '/vben-admin/document',
|
||||
// component: IFrameView,
|
||||
// meta: {
|
||||
// icon: 'lucide:book-open-text',
|
||||
// link: VBEN_DOC_URL,
|
||||
// title: $t('page.vben.document'),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'VbenGithub',
|
||||
// path: '/vben-admin/github',
|
||||
// component: IFrameView,
|
||||
// meta: {
|
||||
// icon: 'mdi:github',
|
||||
// link: VBEN_GITHUB_URL,
|
||||
// title: 'Github',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'VbenNaive',
|
||||
// path: '/vben-admin/naive',
|
||||
// component: IFrameView,
|
||||
// meta: {
|
||||
// badgeType: 'dot',
|
||||
// icon: 'logos:naiveui',
|
||||
// link: VBEN_NAIVE_PREVIEW_URL,
|
||||
// title: $t('page.vben.naive-ui'),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'VbenElementPlus',
|
||||
// path: '/vben-admin/ele',
|
||||
// component: IFrameView,
|
||||
// meta: {
|
||||
// badgeType: 'dot',
|
||||
// icon: 'logos:element',
|
||||
// link: VBEN_ELE_PREVIEW_URL,
|
||||
// title: $t('page.vben.element-plus'),
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
|
||||
export default routes;
|
||||
// export default routes;
|
||||
|
|
|
@ -107,7 +107,7 @@ onBeforeUnmount(() => {
|
|||
</template>
|
||||
<slot name="title"></slot>
|
||||
</VbenTooltip>
|
||||
<div v-show="!showTooltip" :class="[e('content')]">
|
||||
<div v-show="!showTooltip" :class="[e('content')]" class="text-wrap">
|
||||
<VbenMenuBadge
|
||||
v-if="rootMenu.props.mode !== 'horizontal'"
|
||||
class="right-2"
|
||||
|
|
Loading…
Reference in New Issue