From ac4341ea6b66ae02427d39d35f41d42d78b2eb2e Mon Sep 17 00:00:00 2001 From: Junjie <fallin.jie@qq.com> Date: 星期五, 14 二月 2025 10:08:32 +0800 Subject: [PATCH] # --- zy-asrs-admin/src/views/IndexView.vue | 285 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 225 insertions(+), 60 deletions(-) diff --git a/zy-asrs-admin/src/views/IndexView.vue b/zy-asrs-admin/src/views/IndexView.vue index 1f9f9f7..858fcdb 100644 --- a/zy-asrs-admin/src/views/IndexView.vue +++ b/zy-asrs-admin/src/views/IndexView.vue @@ -1,9 +1,10 @@ <script setup> -import { nextTick, ref, inject, computed } from 'vue'; +import { nextTick, ref, inject, onMounted } from 'vue'; import { useRouter } from "vue-router"; -import { get, post } from '@/utils/request.js' +import { get, post, postForm } from '@/utils/request.js' import { logout } from '@/config.js'; import * as Icons from "@ant-design/icons-vue"; +import { message } from 'ant-design-vue'; import { MenuUnfoldOutlined, MenuFoldOutlined, @@ -12,28 +13,55 @@ RedoOutlined, UserOutlined, TranslationOutlined, + ApartmentOutlined, + CaretLeftOutlined, + CaretRightOutlined, } from "@ant-design/icons-vue"; -import { formatMessage } from '@/utils/localeUtils.js'; +import { formatMessage, loadData } from '@/utils/localeUtils.js'; +import AiView from '@/components/ai/index.vue' const globalState = inject('globalState'); const selectedKeys = ref([]); +let openKeys = ref([]); const collapsed = ref(false); const router = useRouter(); let routerCache = ref([]); -let routerCacheMap = ref(new Map()); +let routerCacheList = ref([]); let currentCache = ref(null); let isRouterAlive = ref(true); const menuCache = ref([]); +const hostList = ref([]); +const tabsContent = ref(null); const components = { ...Icons, }; -getMenu() +onMounted(() => { + let name = router.currentRoute.value.name; + let path = router.currentRoute.value.path; + if (currentCache.value == null && path != '/') { + get('/api/menu/get/route', { + route: path + }).then((resp) => { + let result = resp.data; + let data = result.data; + if (result.code == 200) { + currentCache.value = name; + routerCache.value.push(name) + routerCacheList.value.push({ + key: path, + languageId: data.languageId, + name: name, + }) + } + }) + } +}) +getMenu() function getMenu() { - post('/api/menu/tree', {}).then((result) => { - console.log(result.data.data); + get('/api/auth/menu', {}).then((result) => { menuCache.value = result.data.data; }) } @@ -45,19 +73,30 @@ let name = item.item.name; currentCache.value = name; - console.log(routerCache.value); if (name != undefined && routerCache.value.indexOf(name) == -1) { routerCache.value.push(item.item.name) - routerCacheMap.value.set(name, item.key) + routerCacheList.value.push({ + key: item.key, + languageId: item.item.languageId, + name: item.item.name, + }) } } -function closeTabs(name) { +function closeTabs(param) { + let name = param.name; let tmp = [] + let tmpList = []; routerCache.value.forEach((item) => { if (item != name) { tmp.push(item); + } + }) + + routerCacheList.value.forEach((item) => { + if (item.name != name) { + tmpList.push(item); } }) @@ -66,84 +105,195 @@ path: '/' }) routerCache.value.push('home') - routerCacheMap.value.set('home', '/') + routerCacheList.value.push({ + key: '/', + languageId: 'common.home', + name: '涓婚〉', + }) selectedKeys.value = ['/'] } else { - switchTabs(tmp[0]); + switchTabs(tmpList[0]); } routerCache.value = tmp; + routerCacheList.value = tmpList; } function reloadTabs() { - isRouterAlive.value = false; - nextTick(() => { - isRouterAlive.value = true; - }) + const hide = message.loading(formatMessage('common.loading', '鍔犺浇涓�')); + try { + isRouterAlive.value = false; + nextTick(() => { + isRouterAlive.value = true; + // message.success(formatMessage('common.success', '鍔犺浇鎴愬姛')); + }) + } catch (error) { + message.error(formatMessage('common.fail', '鍔犺浇澶辫触')); + } finally { + hide(); + } } -function switchTabs(name) { +function closeAllTabs() { + routerCache.value = []; + routerCacheList.value = []; router.push({ - path: routerCacheMap.value.get(name) + path: '/' }) - - currentCache.value = name; - selectedKeys.value = [routerCacheMap.value.get(name)] - - console.log(routerCacheMap, name, routerCacheMap.value.get(name)); - } -const switchLocale = (locale) => { +function switchTabs(item) { + router.push({ + path: item.key + }) + + currentCache.value = item.name; + selectedKeys.value = [item.key] + + // open menu + let arr = item.key.split("/"); + let key = '/' + arr[1]; + openKeys.value = [key] +} + +const switchLocale = async (locale) => { globalState.locale = locale; + localStorage.setItem('locale', locale) + loadData(locale); + reloadTabs() +} + +getHostList() +function getHostList() { + post('/api/show/host.action', {}).then((resp) => { + let result = resp.data; + let data = result.data; + let hostId = data.hostId; + if (data.root) { + post('/api/host/list', {}).then((resp) => { + let result = resp.data; + let data = result.data; + hostList.value = data; + data.forEach((item) => { + if (item.id == hostId) { + globalState.currentHost = item; + } + }) + }) + } + }) +} + +const licenseDays = ref(365); +getLicenseDays(); +function getLicenseDays() { + post('/api/license/getLicenseDays', {}).then((resp) => { + let result = resp.data; + let data = result.data; + if (result.code == 200) { + licenseDays.value = data; + } + }) +} + +const switchHost = (item) => { + globalState.currentHost = item; + postForm('/api/root/change/host/auth', { + hostId: item.id + }).then((resp) => { + let result = resp.data; + if (result.code == 200) { + window.location.reload(); + } else { + message.error(formatMessage('common.fail', '鍔犺浇澶辫触')); + } + }) +} + +const windowReload = () => { + window.location.reload(); +} + +const handleScroll = (data) => { + let position = tabsContent.value.scrollLeft; + let offset = position * 0.1 + 30; + if (data == 'left') { + tabsContent.value.scrollLeft = position - offset; + } else { + tabsContent.value.scrollLeft = position + offset; + } } </script> <template> <a-layout class="main"> - <a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible> + <a-layout-sider class="main-sider" v-model:collapsed="collapsed" :trigger="null" collapsible theme="dark"> <div class="logo" /> - <a-menu v-for="(item, index) in menuCache" :key="index" v-model:selectedKeys="selectedKeys" @select="menuSelect" - theme="dark" mode="inline"> + <a-menu v-model:openKeys="openKeys" v-model:selectedKeys="selectedKeys" @select="menuSelect" theme="dark" + mode="inline"> <div> <a-menu-item key="/" name="涓婚〉"> - <HomeOutlined /> {{ formatMessage('common.home','涓婚〉') }} + <HomeOutlined /> {{ formatMessage('common.home', '涓婚〉') }} </a-menu-item> </div> - <a-sub-menu v-if="item.type == 0"> - <template #title> - <span> - <component :is="components[ref(item.icon).value]" /> - {{ item.name }} - </span> - </template> - <div v-for="(child, idx) in item.children"> - <a-menu-item v-if="child.status == 1" :key="child.route" :name="child.name"> - {{ child.name }} - </a-menu-item> - </div> - </a-sub-menu> + <div v-for="(item, index) in menuCache" :key="index"> + <a-sub-menu :key="item.route" v-if="item.type == 0"> + <template #title> + <span> + <component :is="components[ref(item.icon).value]" /> + {{ formatMessage(item.languageId, item.name) }} + </span> + </template> + <div v-for="(child, idx) in item.children"> + <a-menu-item v-if="child.status == 1" :key="child.route" :name="child.name" + :languageId="child.languageId"> + {{ formatMessage(child.languageId, child.name) }} + </a-menu-item> + </div> + </a-sub-menu> + </div> </a-menu> </a-layout-sider> <a-layout> - <a-layout-header style="background: #fff; padding: 0"> + <a-layout-header style="background: #fff; padding: 0;"> <div class="header-top"> <div class="header-top-left"> - <MenuUnfoldOutlined v-if="collapsed" class="trigger" @click="() => (collapsed = !collapsed)" /> + <MenuUnfoldOutlined v-if="collapsed" class="trigger triggerLarge" @click="() => (collapsed = !collapsed)" /> <MenuFoldOutlined v-else class="trigger" @click="() => (collapsed = !collapsed)" /> + <RedoOutlined class="trigger" @click="windowReload()" /> </div> <div class="header-top-right"> - <div class="trigger"> + <div class="trigger" style="color: red;" v-if="licenseDays <= 30"> + 璁稿彲璇佹湁鏁堟湡锛歿{ licenseDays }}澶� + </div> + <div class="trigger" v-if="globalState.currentHost"> <a-dropdown> - <TranslationOutlined /> + <div> + <ApartmentOutlined /> + {{ globalState.currentHost?.name }} + </div> <template #overlay> <a-menu> - <a-menu-item @click="switchLocale('enUS')" - :class="globalState.locale == 'enUS' ? 'active' : ''">English</a-menu-item> - <a-menu-item @click="switchLocale('zhCN')" - :class="globalState.locale == 'zhCN' ? 'active' : ''">绠�浣撲腑鏂�</a-menu-item> + <a-menu-item v-for="(item, index) in hostList" :key="index" @click="switchHost(item)" + :class="globalState.currentHost?.id == item.id ? 'active' : ''">{{ item.name }}</a-menu-item> + </a-menu> + </template> + </a-dropdown> + </div> + <div class="trigger"> + <a-dropdown> + <div> + <TranslationOutlined /> + {{ globalState.localeList[globalState.locale]?.desc }} + </div> + <template #overlay> + <a-menu> + <div v-for="(item, key) in globalState.localeList" :key="key"> + <a-menu-item @click="switchLocale(key)" :class="globalState.locale == key ? 'active' : ''">{{ + item.desc }}</a-menu-item> + </div> </a-menu> </template> </a-dropdown> @@ -156,7 +306,7 @@ </a> <template #overlay> <a-menu @click="logout"> - <a-menu-item key="logout">{{ formatMessage('common.account.logout','閫�鍑�') }}</a-menu-item> + <a-menu-item key="logout">{{ formatMessage('common.account.logout', '閫�鍑�') }}</a-menu-item> </a-menu> </template> </a-dropdown> @@ -166,25 +316,40 @@ </a-layout-header> <a-layout-content class="content-view"> <div class="tabs-fixed"> - <div v-for="(item, index) in routerCache" :key="index" @click="switchTabs(item)" class="tabs-item" - :class="currentCache == item ? 'tabs-item-active' : ''"> - <div :class="currentCache == item ? '' : 'tabs-item-reload-none'" @click="reloadTabs" @click.stop> - <RedoOutlined /> - </div> - <div>{{ item }}</div> - <div @click="closeTabs(item)" @click.stop> - <CloseOutlined /> + <div class="tabs-arrow-left" @click="handleScroll('left')"> + <CaretLeftOutlined /> + </div> + + <div class="tabs-content" ref="tabsContent"> + <div class="tabs-content-item"> + <div v-for="(item, index) in routerCacheList" :key="index" @click="switchTabs(item)" class="tabs-item" + :class="currentCache == item.name ? 'tabs-item-active' : ''"> + <div :class="currentCache == item.name ? '' : 'tabs-item-reload-none'" @click="reloadTabs" @click.stop> + <RedoOutlined /> + </div> + <div>{{ formatMessage(item.languageId, item.name) }}</div> + <div @click="closeTabs(item)" @click.stop> + <CloseOutlined /> + </div> + </div> </div> </div> + + <div class="tabs-arrow-right" @click="handleScroll('right')"> + <CaretRightOutlined /> + </div> </div> + <router-view v-slot="{ Component, route }" v-if="isRouterAlive"> <keep-alive :include="routerCache"> - <component :is="Component" /> + <component :is="Component" @pageReload="reloadTabs" /> </keep-alive> </router-view> </a-layout-content> </a-layout> </a-layout> + + <AiView /> </template> <style scoped></style> -- Gitblit v1.9.1