From 83d251608828d17dbb9a8d480c13a1a7c0a20eb5 Mon Sep 17 00:00:00 2001
From: 祖安之光 <11848914+light-of-zuan@user.noreply.gitee.com>
Date: Wed, 29 Apr 2026 16:20:18 +0800
Subject: [PATCH] 修改主页跳转
---
src/permission.js | 35 +++
/dev/null | 436 ------------------------------------------------
src/views/work/menuIndex/index.vue | 52 +++--
src/views/menuPage.vue | 17 +
4 files changed, 84 insertions(+), 456 deletions(-)
diff --git a/src/permission.js b/src/permission.js
index 0628d25..9eac69c 100644
--- a/src/permission.js
+++ b/src/permission.js
@@ -1,5 +1,5 @@
import router from './router'
-import { ElMessage } from 'element-plus'
+import { ElMessage, ElLoading } from 'element-plus'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
@@ -13,6 +13,27 @@
const whiteList = ['/homePage'];
+// 全局 Loading 实例
+let loadingInstance = null
+
+// 显示 Loading
+const showLoading = () => {
+ loadingInstance = ElLoading.service({
+ fullscreen: false,
+ text: '正在加载系统菜单...',
+ customClass: 'route-loading'
+ })
+}
+
+// 隐藏 Loading
+const hideLoading = () => {
+ if (loadingInstance) {
+ loadingInstance.close()
+ loadingInstance = null
+ }
+}
+
+
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
@@ -22,9 +43,18 @@
next({ path: '/' })
NProgress.done()
} else if (whiteList.indexOf(to.path) !== -1) {
+
next()
} else {
+ if(to.path ==='/menuPage'){
+ next()
+ return
+ }
if (useUserStore().roles.length === 0) {
+ if(to.path ==='/menuIndex'){
+ showLoading()
+ }
+
isRelogin.show = true
// 判断当前用户是否已拉取完user_info信息
useUserStore().getInfo().then(() => {
@@ -36,6 +66,8 @@
router.addRoute(route) // 动态添加可访问路由表
}
})
+
+ hideLoading()
if (to.fullPath == '/index') {
@@ -77,5 +109,6 @@
})
router.afterEach(() => {
+ hideLoading()
NProgress.done()
})
diff --git a/src/views/menuPage.vue b/src/views/menuPage.vue
index 97370b3..6622f79 100644
--- a/src/views/menuPage.vue
+++ b/src/views/menuPage.vue
@@ -197,8 +197,17 @@
}
}
+const debounce = (func, wait) => {
+ let timeout
+ return (...args) => {
+ clearTimeout(timeout)
+ timeout = setTimeout(() => {
+ func(...args)
+ }, wait)
+ }
+}
+
const handleSystemLinkClick = (systemId) => {
- console.log('点击了'+ systemId)
if(systemId == 1){
router.push({ path: "/menuIndex"});
}else{
@@ -206,6 +215,12 @@
}
}
+// const debouncedSubmit = ref(debounce(submitHandle, 500))
+
+// const handleSystemLinkClick = (id) => {
+// debouncedSubmit.value(id)
+// }
+
function getInfo() {
reviewRef.value.openDialog('view',userInfo.value)
}
diff --git a/src/views/menuPage2.vue b/src/views/menuPage2.vue
deleted file mode 100644
index f3539e1..0000000
--- a/src/views/menuPage2.vue
+++ /dev/null
@@ -1,436 +0,0 @@
-<template>
- <div class="system-select-container">
- <!-- 顶部用户信息栏 -->
- <div class="user-info-bar">
- <div class="user-left">
- 欢迎访问多体系建设信息化系统
- </div>
- <div class="avatar-container">
- <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
- <div class="avatar-wrapper" style="display: flex;align-items: center">
- <img src="../assets/images/avator.png" class="user-avatar" />
- <span style="font-size: 16px;color: #fff">{{userName}}({{userTypeName}})</span>
- <el-icon color="#fff"><caret-bottom /></el-icon>
- </div>
- <template #dropdown>
- <el-dropdown-menu>
-<!-- <el-dropdown-item command="info">-->
-<!-- <span>基本信息</span>-->
-<!-- </el-dropdown-item>-->
- <el-dropdown-item command="password">
- <span>修改密码</span>
- </el-dropdown-item>
- <el-dropdown-item divided command="logout">
- <span>退出登录</span>
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </div>
-
- <!-- 系统选择区域 -->
- <div class="systems-container">
- <div class="systems-grid">
- <div
- v-for="system in systems"
- :key="system.id"
- class="system-card"
- @mouseenter="handleCardEnter($event, system.id)"
- @mousemove="handleCardMove($event, system.id)"
- @mouseleave="handleCardLeave(system.id)"
- @click="enterSystem(system.id)"
- :style="getCardStyle(system.id)"
- >
- <div class="card-content">
- <div class="system-icon">
- <img :src="system.icon"/>
- </div>
- <h3>{{ system.name }}</h3>
- <p>{{ system.description }}</p>
- </div>
- </div>
- </div>
- </div>
-<!-- <div class="sys-footer">-->
-<!-- <div class="footer-left">-->
-<!-- <img src="../assets/images/menuPageLogo.png"/>-->
-<!-- <span>中国科学院苏州纳米技术与纳米仿生研究所</span>-->
-<!-- </div>-->
-<!-- <div class="footer-right">-->
-<!-- 系统版本:V1.0.0-->
-<!-- </div>-->
-<!-- </div>-->
- <user-dialog ref="reviewRef"></user-dialog>
- </div>
-</template>
-
-<script setup>
-import { ref, onMounted } from 'vue'
-import { useRouter } from 'vue-router'
-import {getToken, removeToken} from "@/utils/auth";
-import Cookies from "js-cookie";
-import {ElMessage, ElMessageBox} from "element-plus";
-import useUserStore from '@/store/modules/user'
-import userDialog from '@/views/build/conpanyFunctionConsult/staffManage/staffRegister/components/staffDialog.vue'
-import menu1 from '@/assets/icons/menu1.png'
-import menu2 from '@/assets/icons/menu2.png'
-import menu3 from '@/assets/icons/menu3.png'
-import menu4 from '@/assets/icons/menu4.png'
-import menu5 from '@/assets/icons/menu5.png'
-import menu6 from '@/assets/icons/menu6.png'
-
-const router = useRouter()
-const route = useRoute();
-const reviewRef = ref();
-const userInfo = ref();
-const userName = ref('')
-const userTypeName = ref('')
-const cardStates = ref({})
-// 组件挂载时获取用户信息和系统列表
-onMounted(() => {
- if(getToken()){
- userInfo.value = JSON.parse(Cookies.get('userInfo'))
- userName.value = userInfo.value.username
- userTypeName.value = userInfo.value.userType == 0 ? '系统管理员' : (userInfo.value.userType == 1 || userInfo.value.userType == 2 || userInfo.value.userType == 3) ? '企业用户' :userInfo.value.userType == 6 ? '企业管理员' :userInfo.value.userType == 4 ? '其他' : '学员'
- }
-
- const userStore = useUserStore()
- userStore.roles = []
- systems.value.forEach(system => {
- cardStates.value[system.id] = {
- mouseX: 0,
- mouseY: 0,
- width: 0,
- height: 0,
- hover: false
- }
- })
-})
-
-
-// 鼠标进入卡片
-const handleCardEnter = (event, id) => {
- const card = event.currentTarget
- cardStates.value[id] = {
- ...cardStates.value[id],
- width: card.offsetWidth,
- height: card.offsetHeight,
- hover: true
- }
-}
-
-// 鼠标移动
-const handleCardMove = (event, id) => {
- if (!cardStates.value[id]?.hover) return
-
- const card = event.currentTarget
- const rect = card.getBoundingClientRect()
-
- cardStates.value[id].mouseX = event.clientX - rect.left - cardStates.value[id].width / 2
- cardStates.value[id].mouseY = event.clientY - rect.top - cardStates.value[id].height / 2
-}
-
-// 鼠标离开
-const handleCardLeave = (id) => {
- cardStates.value[id].hover = false;
- // 立即开始归位动画,不使用setTimeout延迟
- cardStates.value[id].mouseX = 0;
- cardStates.value[id].mouseY = 0;
-}
-
-// 获取卡片样式
-const getCardStyle = (id) => {
- const state = cardStates.value[id] || {}
- const mousePX = state.mouseX / (state.width || 1)
- const mousePY = state.mouseY / (state.height || 1)
-
- const rX = mousePX * 20 // 减小旋转角度,使效果更柔和
- const rY = mousePY * -20
-
- const tX = mousePX * -20
- const tY = mousePY * -20
-
- return {
- transform: `rotateY(${rX}deg) rotateX(${rY}deg)`,
- '--bg-transform': `translateX(${tX}px) translateY(${tY}px)`
- }
-}
-
-
-// 系统列表
-const systems = ref([
- {
- id: 1,
- name: '国军标9001C质量管理体系',
- description: '确保产品和服务质量符合国际标准',
- icon: menu1
- },
- {
- id: 2,
- name: 'ISO 27001 信息安全体系',
- description: '保护企业信息资产安全与机密性',
- icon: menu2
- },
- {
- id: 3,
- name: 'ISO 45001 安全体系',
- description: '实现企业安全的持续改进',
- icon: menu3
- },
- {
- id: 4,
- name: '项目管理控制',
- description: '标准化项目管理流程与方法',
- icon: menu4
- },
- {
- id: 5,
- name: '承制评价体系',
- description: '供应商与承包商能力评估标准',
- icon: menu5
- },
- {
- id: 6,
- name: '新体系评价',
- description: '新体系评价',
- icon: menu6
- }
-])
-function handleCommand(command) {
- switch (command) {
- case "info":
- getInfo();
- break;
- case "logout":
- logout();
- break;
- case "password":
- editPsd();
- break;
- default:
- break;
- }
-}
-// 进入系统
-const enterSystem = (systemId) => {
- if(systemId == 1){
- router.push({ path: "/menuIndex"});
- }else{
- ElMessage.warning('系统正在开发中...')
- }
-}
-function getInfo() {
- reviewRef.value.openDialog('view',userInfo.value)
-}
-function editPsd() {
- reviewRef.value.openDialog('pwd',userInfo.value)
-}
-// 退出登录
-function logout() {
- ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- removeToken()
- location.href = '/homePage';
-
- }).catch(() => { });
-}
-
-
-</script>
-
-<style scoped lang="scss">
-.system-select-container {
- height: 100vh;
- display: flex;
- flex-direction: column;
- background-color: #f5f7fa;
-}
-
-.user-info-bar {
- display: flex;
- height: 100px;
- align-items: center;
- justify-content: space-between;
- padding: 10px 20px;
- background-color: rgb(16,66,143);
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
-
- .user-left{
- width: 80%;
- font-size: clamp(1rem, -0.143rem + 1.79vw, 2rem);
- font-weight: bolder;
- padding-left: 40px;
- color: #fff;
- }
-
- .avatar-container {
- width: 20%;
- display: flex;
- justify-content: center;
-
- .avatar-wrapper {
- position: relative;
-
- .user-avatar {
- cursor: pointer;
- width: 40px;
- height: 40px;
- border-radius: 10px;
- margin-right: 15px;
- }
-
- i {
- cursor: pointer;
- position: absolute;
- right: -20px;
- font-size: 12px;
- }
- }
- }
-
-}
-
-
-.systems-container {
- flex: 1;
- padding: 20px 60px;
- overflow-y: auto;
- margin-top: 60px;
-}
-
-.sys-footer{
- height: 100px;
- background: #e6e6e6;
- display: flex;
- justify-content: space-between;
- align-items: center;
- .footer-left{
- display: flex;
- justify-content: left;
- align-items: center;
-
- img{
- width: 60px;
- height: 60px;
- }
- span{
- font-size: 24px;
- }
- }
-}
-
-.systems-grid {
- display: grid;
- grid-template-columns: repeat(3,1fr);
- gap: 30px;
- max-width: 100%;
- margin: 0 auto;
- perspective: 1000px;
-}
-
-.system-card {
- position: relative;
- height: 320px;
- background-color: #ffffff;
- border-radius: 4px;
- transition: transform 1s cubic-bezier(0.23, 1, 0.32, 1),
- box-shadow 0.5s cubic-bezier(0.23, 1, 0.32, 1);
- transform-style: preserve-3d;
- cursor: pointer;
- overflow: hidden;
-
- &:hover{
- border-radius: 16px;
- }
-
- &::after {
- content: '';
- position: absolute;
- top: 8px;
- left: 8px;
- right: 8px;
- bottom: 8px;
- border-radius: 4px; /* 比卡片小1px */
- border: 1px solid transparent;
- transition: border-color 0.3s ease;
- pointer-events: none; /* 确保不影响鼠标事件 */
- z-index: 3; /* 确保在内容之上 */
- }
-
- &::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- border-radius: 4px;
- background: #fff;
- transform: var(--bg-transform, translateX(0) translateY(0));
- transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
- z-index: 1;
- }
- &:hover::after {
- border-color: rgba(37,99,235,1); /* 使用蓝色描边 */
- border-radius: 12px;
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5); /* 可选:添加内发光效果 */
- }
- &:hover::before {
- border-radius: 16px;
- background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(20,20,20,0.05) 100%);
- }
-}
-
-.system-card:hover {
- //transform: translateY(-5px);
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15),
- 0 0 0 1px rgba(255, 255, 255, 0.5) inset;
-}
-.card-content {
- position: relative;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 25px;
- z-index: 2;
- transform-style: preserve-3d;
-}
-
-.system-icon img {
- width: 80px;
- height: 80px;
- margin-bottom: 30px;
- transition: transform 0.5s;
-}
-
-.system-card:hover .system-icon img {
- transform: scale(1.4);
-}
-
-.system-card h3 {
- margin: 0 0 12px;
- color: #333;
- font-size: 24px;
- text-align: center;
- transition: transform 0.3s;
-}
-
-.system-card p {
- margin: 0;
- color: #999;
- font-size: 15px;
- text-align: center;
- transition: transform 0.3s;
-}
-
-.system-card:hover h3,
-.system-card:hover p {
- transform: translateZ(20px);
-}
-</style>
diff --git a/src/views/work/menuIndex/index.vue b/src/views/work/menuIndex/index.vue
index 167b244..f0d689a 100644
--- a/src/views/work/menuIndex/index.vue
+++ b/src/views/work/menuIndex/index.vue
@@ -11,10 +11,20 @@
<span class="more-link" @click="toNoticeMng">更多 ></span>
</div>
<div class="notice-list">
- <div class="notice-item" v-for="item in noticeList" :key="item">
- <span class="notice-title" @click="openNoticeFile(item.filePath)">{{item.content}}</span>
- <span class="notice-date">{{item.publishDate}}</span>
- </div>
+
+ <template v-if="noticeLoading">
+ <div v-for="i in 6" :key="i" class="notice-item skeleton">
+ <div class="skeleton-title"></div>
+ <div class="skeleton-date"></div>
+ </div>
+ </template>
+
+ <template v-else>
+ <div class="notice-item" v-for="item in noticeList" :key="item.id">
+ <span class="notice-title" @click="openNoticeFile(item.filePath)">{{item.content}}</span>
+ <span class="notice-date">{{item.publishDate}}</span>
+ </div>
+ </template>
</div>
</div>
@@ -179,12 +189,6 @@
import userDialog from '@/views/build/conpanyFunctionConsult/staffManage/staffRegister/components/staffDialog.vue'
import editDialog from '@/views/build/conpanyFunctionConsult/infoPlatform/components/editDialog.vue'
import sealDialog from "@/views/work/sealManagement/apply/components/editDialog"
-import menu1 from '@/assets/icons/menu1.png'
-import menu2 from '@/assets/icons/menu2.png'
-import menu3 from '@/assets/icons/menu3.png'
-import menu4 from '@/assets/icons/menu4.png'
-import menu5 from '@/assets/icons/menu5.png'
-import menu6 from '@/assets/icons/menu6.png'
// 引入农历库
import * as lunarCalendar from 'lunar-calendar'
@@ -206,6 +210,8 @@
const calendarRef = ref()
const dialogRef = ref()
const noticeRef = ref();
+const noticeLoading = ref(true)
+
const userStore = useUserStore()
const state = reactive({
noticeParams: {
@@ -243,10 +249,13 @@
state.platformParams.companyId = userStore.companyId
state.isAdmin = false
}
- await getNoticeList()
- await getPlatformList()
- await getFlowList()
- await getMemo()
+ // 并行加载所有数据
+ await Promise.allSettled([
+ getNoticeList(),
+ getPlatformList(),
+ getFlowList(),
+ getMemo()
+ ])
state.platformList.forEach(system => {
cardStates.value[system.id] = {
mouseX: 0,
@@ -292,10 +301,17 @@
noticeRef.value.openDialog('review', data,state.companyList)
}
}
-function getNoticeList() {
- listNotice(state.noticeParams).then(res => {
- state.noticeList = res.data.list
- })
+async function getNoticeList() {
+ try {
+ noticeLoading.value = true
+ const res = await listNotice(state.noticeParams)
+ state.noticeList = res.data.list || []
+ } catch (error) {
+ console.error('获取通知公告失败:', error)
+ state.noticeList = []
+ } finally {
+ noticeLoading.value = false
+ }
}
const getCompanyList = async ()=>{
const queryParams = {
--
Gitblit v1.9.2