Compare commits

...
7 Commits
Author SHA1 Message Date
Hooray b661e0e834 chore: release v5.10.1 2026-03-31 01:59:14 +08:00
Hooray 5bf2664a04 chore: 更新依赖 2026-03-31 01:55:54 +08:00
Hooray 3fded8abac chore: types 2026-03-25 22:27:22 +08:00
Hooray d707522b6c fix: 修复 FaSelect options 数组为空报错 2026-03-25 22:12:18 +08:00
Hooray a177b8c6a6 chore: 更新依赖 2026-03-25 22:10:24 +08:00
Hooray ac9b5d5b3b chore: 更新依赖 2026-03-15 02:13:49 +08:00
Hooray f0582cf721 fix: 优化路由守卫逻辑,简化条件判断和重定向处理 2026-03-07 15:12:04 +08:00
8 changed files with 2494 additions and 2153 deletions
+9 -8
View File
@@ -1,5 +1,6 @@
{
"eslint.useFlatConfig": true,
"npm.packageManager": "pnpm",
"js/ts.tsdk.path": "node_modules/typescript/lib",
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
@@ -7,12 +8,7 @@
"source.fixAll.stylelint": "explicit",
"source.organizeImports": "never"
},
"stylelint.validate": [
"css",
"postcss",
"scss",
"vue"
],
"eslint.useFlatConfig": true,
"eslint.validate": [
"javascript",
"javascriptreact",
@@ -25,5 +21,10 @@
"jsonc",
"yaml"
],
"typescript.tsdk": "node_modules/typescript/lib"
"stylelint.validate": [
"css",
"postcss",
"scss",
"vue"
]
}
+36 -36
View File
@@ -1,7 +1,7 @@
{
"type": "module",
"version": "5.10.0",
"packageManager": "pnpm@10.30.3",
"version": "5.10.1",
"packageManager": "pnpm@10.33.0",
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
@@ -29,93 +29,93 @@
"@vueuse/components": "^14.2.1",
"@vueuse/core": "^14.2.1",
"@vueuse/integrations": "^14.2.1",
"axios": "^1.13.6",
"axios": "^1.14.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.19",
"dayjs": "^1.11.20",
"defu": "^6.1.4",
"disable-devtool": "^0.3.9",
"element-plus": "^2.13.4",
"element-plus": "^2.13.6",
"eruda": "^3.4.3",
"es-toolkit": "^1.45.1",
"filesize": "^11.0.13",
"filesize": "^11.0.15",
"hotkeys-js": "^4.0.2",
"lucide-vue-next": "^0.577.0",
"lucide-vue-next": "^1.0.0",
"mitt": "^3.0.1",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^8.3.0",
"path-to-regexp": "^8.4.0",
"pinia": "^3.0.4",
"qs": "^6.15.0",
"reka-ui": "^2.9.0",
"reka-ui": "^2.9.2",
"scule": "^1.3.0",
"tailwind-merge": "^3.5.0",
"ua-parser-js": "^2.0.9",
"vconsole": "^3.15.1",
"vee-validate": "^4.15.1",
"vue": "^3.5.29",
"vue-router": "^5.0.3",
"vue": "^3.5.31",
"vue-router": "^5.0.4",
"vue-sonner": "^2.0.9",
"zod": "^4.3.6"
},
"devDependencies": {
"@antfu/eslint-config": "^7.7.0",
"@antfu/eslint-config": "^7.7.3",
"@clack/prompts": "^1.1.0",
"@faker-js/faker": "^10.3.0",
"@iconify/json": "^2.2.447",
"@faker-js/faker": "^10.4.0",
"@iconify/json": "^2.2.456",
"@iconify/vue": "^5.0.0",
"@stylistic/stylelint-config": "^4.0.0",
"@stylistic/stylelint-config": "^5.0.0",
"@types/nprogress": "^0.2.3",
"@types/path-browserify": "^1.0.3",
"@types/qs": "^6.15.0",
"@unocss/eslint-plugin": "^66.6.6",
"@unocss/preset-legacy-compat": "^66.6.6",
"@unocss/reset": "^66.6.6",
"@vitejs/plugin-legacy": "^7.2.1",
"@vitejs/plugin-vue": "^6.0.4",
"@vitejs/plugin-vue-jsx": "^5.1.4",
"@vue/tsconfig": "^0.9.0",
"@unocss/eslint-plugin": "^66.6.7",
"@unocss/preset-legacy-compat": "^66.6.7",
"@unocss/reset": "^66.6.7",
"@vitejs/plugin-legacy": "^8.0.1",
"@vitejs/plugin-vue": "^6.0.5",
"@vitejs/plugin-vue-jsx": "^5.1.5",
"@vue/tsconfig": "^0.9.1",
"autoprefixer": "^10.4.27",
"boxen": "^8.0.1",
"bumpp": "^10.4.1",
"bumpp": "^11.0.1",
"cz-git": "^1.12.0",
"eslint": "^9.39.4",
"eslint": "^10.1.0",
"fs-extra": "^11.3.4",
"http-server": "^14.1.1",
"lint-staged": "^16.3.2",
"lint-staged": "^16.4.0",
"npm-run-all2": "^8.0.4",
"picocolors": "^1.1.1",
"plop": "^4.0.5",
"postcss": "^8.5.8",
"postcss-nested": "^7.0.2",
"sass-embedded": "^1.97.3",
"sass-embedded": "^1.98.0",
"simple-git-hooks": "^2.13.1",
"stylelint": "^17.4.0",
"stylelint-config-recess-order": "^7.6.1",
"stylelint": "^17.6.0",
"stylelint-config-recess-order": "^7.7.0",
"stylelint-config-standard-scss": "^17.0.0",
"stylelint-config-standard-vue": "^1.0.0",
"stylelint-scss": "^7.0.0",
"svgo": "^4.0.1",
"taze": "^19.10.0",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"unocss": "^66.6.6",
"typescript": "^6.0.2",
"unocss": "^66.6.7",
"unocss-preset-animations": "^1.3.0",
"unplugin-auto-import": "^21.0.0",
"unplugin-turbo-console": "^2.3.0",
"unplugin-vue-components": "^31.0.0",
"vite": "^7.3.1",
"unplugin-vue-components": "^32.0.0",
"vite": "^8.0.3",
"vite-plugin-app-loading": "^0.4.0",
"vite-plugin-archiver": "^0.2.0",
"vite-plugin-banner": "^0.8.1",
"vite-plugin-compression2": "^2.5.0",
"vite-plugin-compression2": "^2.5.3",
"vite-plugin-env-parse": "^1.0.15",
"vite-plugin-fake-server": "^2.2.2",
"vite-plugin-fake-server": "^2.2.3",
"vite-plugin-pages": "^0.33.3",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-devtools": "^8.0.7",
"vite-plugin-vue-devtools": "^8.1.1",
"vite-plugin-vue-meta-layouts": "^0.6.1",
"vue-tsc": "^3.2.5"
"vue-tsc": "^3.2.6"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged",
+2423 -2064
View File
File diff suppressed because it is too large Load Diff
+12 -30
View File
@@ -4,7 +4,7 @@ import { asyncRoutes, asyncRoutesByFilesystem } from './routes'
import '@/assets/styles/nprogress.css'
function setupRoutes(router: Router) {
router.beforeEach(async (to, _from, next) => {
router.beforeEach(async (to) => {
const settingsStore = useSettingsStore()
const userStore = useUserStore()
const routeStore = useRouteStore()
@@ -17,27 +17,19 @@ function setupRoutes(router: Router) {
settingsStore.settings.menu.mode !== 'single' && menuStore.setActived(to.path)
// 如果已登录状态下,进入登录页会强制跳转到主页
if (to.name === 'login') {
next({
return {
path: settingsStore.settings.home.fullPath,
replace: true,
})
}
}
// 如果未开启主页,但进入的是主页,则会进入侧边栏导航第一个模块
else if (!settingsStore.settings.home.enable && to.fullPath === settingsStore.settings.home.fullPath) {
if (menuStore.sidebarMenus.length > 0) {
next({
return {
path: menuStore.sidebarMenusFirstDeepestPath,
replace: true,
})
}
}
// 如果侧边栏导航第一个模块均无法命中,则还是进入主页
else {
next()
}
}
// 正常访问页面
else {
next()
}
}
else {
@@ -84,24 +76,21 @@ function setupRoutes(router: Router) {
userStore.logout()
}
// 动态路由生成并注册后,重新进入当前路由
next({
return {
path: to.path,
query: to.query,
replace: true,
})
}
}
}
else {
if (to.name !== 'login') {
next({
return {
name: 'login',
query: {
redirect: to.fullPath !== settingsStore.settings.home.fullPath ? to.fullPath : undefined,
},
})
}
else {
next()
}
}
}
})
@@ -109,20 +98,14 @@ function setupRoutes(router: Router) {
// 当父级路由未配置重定向时,自动重定向到有访问权限的子路由
function setupRedirectAuthChildrenRoute(router: Router) {
router.beforeEach((to, _from, next) => {
router.beforeEach((to) => {
const { auth } = useAuth()
const currentRoute = router.getRoutes().find(route => route.path === (to.matched.at(-1)?.path ?? ''))
if (!currentRoute?.redirect) {
const findAuthRoute = currentRoute?.children?.find(route => route.meta?.menu !== false && auth(route.meta?.auth ?? ''))
if (findAuthRoute) {
next(findAuthRoute)
return findAuthRoute
}
else {
next()
}
}
else {
next()
}
})
}
@@ -130,12 +113,11 @@ function setupRedirectAuthChildrenRoute(router: Router) {
// 进度条
function setupProgress(router: Router) {
const { isLoading } = useNProgress()
router.beforeEach((_to, _from, next) => {
router.beforeEach(() => {
const settingsStore = useSettingsStore()
if (settingsStore.settings.app.enableProgress) {
isLoading.value = true
}
next()
})
router.afterEach(() => {
const settingsStore = useSettingsStore()
+10 -10
View File
@@ -1,13 +1,5 @@
interface ImportMetaEnv {
// Auto generate by env-parse
/**
* 应用配置面板
*/
readonly VITE_APP_SETTING: boolean
/**
* 页面标题
*/
readonly VITE_APP_TITLE: string
/**
* 接口请求地址,会设置到 axios 的 baseURL 参数上
*/
@@ -21,11 +13,19 @@ interface ImportMetaEnv {
*/
readonly VITE_APP_DISABLE_DEVTOOL: boolean
/**
* 是否开启代理
* 应用配置面板
*/
readonly VITE_OPEN_PROXY: boolean
readonly VITE_APP_SETTING: boolean
/**
* 页面标题
*/
readonly VITE_APP_TITLE: string
/**
* 是否开启开发者工具
*/
readonly VITE_OPEN_DEVTOOLS: boolean
/**
* 是否开启代理
*/
readonly VITE_OPEN_PROXY: boolean
}
+3 -3
View File
@@ -29,10 +29,10 @@ const value = defineModel<AcceptableValue>()
const selectedOption = computed({
get() {
return props.options.find(option => option.value === value.value) ?? props.options[0]
return props.options.length > 0 ? props.options.find(option => option.value === value.value) ?? props.options[0] : null
},
set(val) {
value.value = val.value
value.value = val?.value || null
},
})
</script>
@@ -40,7 +40,7 @@ const selectedOption = computed({
<template>
<Select v-model="value" :disabled>
<SelectTrigger :class="cn('w-[200px]', props.class)">
<SelectValue :placeholder="selectedOption.label" />
<SelectValue :placeholder="selectedOption?.label" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
+1 -1
View File
@@ -3,7 +3,6 @@
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"#/*": ["./src/types/*"]
@@ -19,6 +18,7 @@
"strict": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": false,
"noUncheckedSideEffectImports": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"sourceMap": true,
-1
View File
@@ -1,7 +1,6 @@
{
// 此处配置是为了满足 shadcn-vue CLI 的配置要求
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}