解决404跳转问题
This commit is contained in:
parent
a5a02eb8c9
commit
183ade379b
@ -1,5 +1,4 @@
|
|||||||
import { createComponentLoader } from '@/utils/pathResolver';
|
import { createComponentLoader } from '@/utils/pathResolver';
|
||||||
import { h, resolveComponent as resolveVueComponent } from 'vue';
|
|
||||||
|
|
||||||
// 递归转换嵌套菜单为嵌套路由
|
// 递归转换嵌套菜单为嵌套路由
|
||||||
export function convertMenusToRoutes(menus, parentPath = '') {
|
export function convertMenusToRoutes(menus, parentPath = '') {
|
||||||
|
|||||||
@ -117,7 +117,6 @@ function addDynamicRoutes(menus) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
dynamicRoutesAdded = true;
|
dynamicRoutesAdded = true;
|
||||||
// console.log('动态路由添加完成:', router.getRoutes().map(r => r.path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function findRouteByName(routes, routeName) {
|
function findRouteByName(routes, routeName) {
|
||||||
|
|||||||
@ -1,179 +0,0 @@
|
|||||||
import { defineStore } from 'pinia'
|
|
||||||
import { ref, computed } from 'vue'
|
|
||||||
import { getDictItemsByCode } from '@/api/dict'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 字典 Store
|
|
||||||
*
|
|
||||||
* 用于全局管理系统字典数据
|
|
||||||
* 缓存字典数据避免重复请求,提高性能
|
|
||||||
*
|
|
||||||
* 使用示例:
|
|
||||||
* const dictStore = useDictStore()
|
|
||||||
* const statusDict = await dictStore.getDictItems('user_status')
|
|
||||||
* const roleDict = dictStore.getDictItemsSync('user_role') // 已加载则同步返回
|
|
||||||
*/
|
|
||||||
export const useDictStore = defineStore('dict', () => {
|
|
||||||
// 字典缓存:{ dictCode: [...items] }
|
|
||||||
const dictCache = ref({})
|
|
||||||
|
|
||||||
// 正在加载的字典代码集合
|
|
||||||
const loadingCodes = ref(new Set())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取字典项(异步)
|
|
||||||
* @param {string} code - 字典编码,如 'user_status'
|
|
||||||
* @returns {Promise<Array>} 字典项数组
|
|
||||||
*/
|
|
||||||
async function getDictItems(code) {
|
|
||||||
// 如果缓存中已有,直接返回
|
|
||||||
if (dictCache.value[code]) {
|
|
||||||
return dictCache.value[code]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 避免重复请求:如果已在加载中,等待
|
|
||||||
if (loadingCodes.value.has(code)) {
|
|
||||||
// 等待加载完成(最多 5 秒)
|
|
||||||
return await new Promise((resolve) => {
|
|
||||||
let count = 0
|
|
||||||
const timer = setInterval(() => {
|
|
||||||
if (dictCache.value[code]) {
|
|
||||||
clearInterval(timer)
|
|
||||||
resolve(dictCache.value[code])
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
if (count > 50) {
|
|
||||||
clearInterval(timer)
|
|
||||||
resolve([])
|
|
||||||
}
|
|
||||||
}, 100)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标记为正在加载
|
|
||||||
loadingCodes.value.add(code)
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await getDictItemsByCode(code)
|
|
||||||
let items = []
|
|
||||||
|
|
||||||
// 兼容不同的 API 响应格式
|
|
||||||
if (res?.data && Array.isArray(res.data)) {
|
|
||||||
items = res.data
|
|
||||||
} else if (Array.isArray(res)) {
|
|
||||||
items = res
|
|
||||||
} else if (res?.data?.data && Array.isArray(res.data.data)) {
|
|
||||||
items = res.data.data
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存字典项
|
|
||||||
dictCache.value[code] = items
|
|
||||||
// console.log(`✅ 字典 [${code}] 已加载,共 ${items.length} 项`)
|
|
||||||
|
|
||||||
return items
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ 加载字典 [${code}] 失败:`, error)
|
|
||||||
dictCache.value[code] = []
|
|
||||||
return []
|
|
||||||
} finally {
|
|
||||||
// 移除加载标记
|
|
||||||
loadingCodes.value.delete(code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步获取字典项(如果已缓存)
|
|
||||||
* @param {string} code - 字典编码
|
|
||||||
* @returns {Array} 字典项数组,未缓存则返回空数组
|
|
||||||
*/
|
|
||||||
function getDictItemsSync(code) {
|
|
||||||
return dictCache.value[code] || []
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 预加载字典(在应用启动时调用)
|
|
||||||
* @param {Array<string>} codes - 字典编码数组
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async function preloadDicts(codes) {
|
|
||||||
const promises = codes.map(code => getDictItems(code))
|
|
||||||
await Promise.all(promises)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据字典编码和值获取标签
|
|
||||||
* @param {string} code - 字典编码
|
|
||||||
* @param {any} value - 字典值
|
|
||||||
* @returns {string} 字典标签
|
|
||||||
*/
|
|
||||||
function getDictLabel(code, value) {
|
|
||||||
const items = getDictItemsSync(code)
|
|
||||||
if (!items.length) {
|
|
||||||
console.warn(`⚠️ 字典 [${code}] 未加载,无法获取标签`)
|
|
||||||
return String(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = items.find(i => String(i.dict_value) === String(value) || i.dict_value === value)
|
|
||||||
return item ? item.dict_label : String(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据字典编码和标签获取值
|
|
||||||
* @param {string} code - 字典编码
|
|
||||||
* @param {string} label - 字典标签
|
|
||||||
* @returns {any} 字典值
|
|
||||||
*/
|
|
||||||
function getDictValue(code, label) {
|
|
||||||
const items = getDictItemsSync(code)
|
|
||||||
if (!items.length) {
|
|
||||||
console.warn(`⚠️ 字典 [${code}] 未加载,无法获取值`)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = items.find(i => i.dict_label === label)
|
|
||||||
return item ? item.dict_value : null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空缓存
|
|
||||||
* @param {string} code - 字典编码,不指定则清空所有
|
|
||||||
*/
|
|
||||||
function clearCache(code) {
|
|
||||||
if (code) {
|
|
||||||
delete dictCache.value[code]
|
|
||||||
// console.log(`✅ 已清除字典 [${code}] 缓存`)
|
|
||||||
} else {
|
|
||||||
dictCache.value = {}
|
|
||||||
// console.log(`✅ 已清除所有字典缓存`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新字典
|
|
||||||
* @param {string} code - 字典编码
|
|
||||||
* @returns {Promise<Array>}
|
|
||||||
*/
|
|
||||||
async function refreshDict(code) {
|
|
||||||
clearCache(code)
|
|
||||||
return getDictItems(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有已缓存的字典
|
|
||||||
* @returns {Object}
|
|
||||||
*/
|
|
||||||
const allDicts = computed(() => dictCache.value)
|
|
||||||
|
|
||||||
return {
|
|
||||||
dictCache,
|
|
||||||
loadingCodes,
|
|
||||||
getDictItems,
|
|
||||||
getDictItemsSync,
|
|
||||||
preloadDicts,
|
|
||||||
getDictLabel,
|
|
||||||
getDictValue,
|
|
||||||
clearCache,
|
|
||||||
refreshDict,
|
|
||||||
allDicts,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@ -92,10 +92,6 @@ export const useMenuStore = defineStore('menu', () => {
|
|||||||
const cachedMenus = loadFromCache();
|
const cachedMenus = loadFromCache();
|
||||||
if (cachedMenus && cachedMenus.length > 0) {
|
if (cachedMenus && cachedMenus.length > 0) {
|
||||||
menus.value = cachedMenus;
|
menus.value = cachedMenus;
|
||||||
// 注释掉后台更新缓存的逻辑,避免重复请求
|
|
||||||
// fetchMenus(true).catch(err => {
|
|
||||||
// console.warn('后台更新菜单失败:', err);
|
|
||||||
// });
|
|
||||||
return Promise.resolve(cachedMenus);
|
return Promise.resolve(cachedMenus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,6 @@ import axios from 'axios';
|
|||||||
|
|
||||||
// 获取API基础URL,添加调试信息
|
// 获取API基础URL,添加调试信息
|
||||||
const apiBaseURL = import.meta.env.VITE_API_BASE_URL;
|
const apiBaseURL = import.meta.env.VITE_API_BASE_URL;
|
||||||
if (!apiBaseURL) {
|
|
||||||
console.error('警告: VITE_API_BASE_URL 环境变量未设置!');
|
|
||||||
console.log('当前环境变量:', import.meta.env);
|
|
||||||
} else {
|
|
||||||
console.log('API基础URL:', apiBaseURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建axios实例
|
// 创建axios实例
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
|
|||||||
@ -4,13 +4,22 @@
|
|||||||
<div class="not-found-big">404</div>
|
<div class="not-found-big">404</div>
|
||||||
<div class="not-found-message">页面未找到</div>
|
<div class="not-found-message">页面未找到</div>
|
||||||
<div class="not-found-desc">很抱歉,您访问的页面不存在或已被删除。</div>
|
<div class="not-found-desc">很抱歉,您访问的页面不存在或已被删除。</div>
|
||||||
<router-link to="/" class="back-home-btn">返回首页</router-link>
|
<a href="javascript:void(0)" class="back-home-btn" @click.prevent="backToHome">
|
||||||
|
返回首页
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script lang="ts" setup>
|
||||||
// 这里可以根据需要添加自定义逻辑
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const backToHome = () => {
|
||||||
|
// 使用 /home 作为首页(Hash模式下的系统导航页)
|
||||||
|
router.push("/home");
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -26,9 +35,9 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 60px 48px 40px;
|
padding: 60px 48px 40px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
box-shadow: 0 4px 24px rgba(0,0,0,0.10);
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
animation: float-in 0.8s cubic-bezier(.7,.13,.45,.81) both;
|
animation: float-in 0.8s cubic-bezier(0.7, 0.13, 0.45, 0.81) both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.not-found-big {
|
.not-found-big {
|
||||||
@ -64,7 +73,7 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
box-shadow: 0 2px 8px rgba(252,92,125,0.07);
|
box-shadow: 0 2px 8px rgba(252, 92, 125, 0.07);
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-home-btn:hover {
|
.back-home-btn:hover {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user