mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' into pages
This commit is contained in:
		
						commit
						401d99b3be
					
				
							
								
								
									
										1
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -1,4 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  "tailwindCSS.experimental.configFile": "src/style/tailwind.css",
 | 
				
			||||||
  "editor.formatOnType": true,
 | 
					  "editor.formatOnType": true,
 | 
				
			||||||
  "editor.formatOnSave": true,
 | 
					  "editor.formatOnSave": true,
 | 
				
			||||||
  "[vue]": {
 | 
					  "[vue]": {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 6.2.0 (2025-10-16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Added full-screen `403`, `404`, and `500` error pages. These full-screen error pages are clear and secure, improving the user experience.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug Fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed an issue where the built-in homepage did not have a `name` configured, causing cache invalidation after setting the page cache.
 | 
				
			||||||
 | 
					- Fixed an issue where, in an embedded same-origin `iframe` page, when the `beforeunload` event was registered, right-clicking a tab and reloading it would cause the browser to prompt two confirmation blocks.
 | 
				
			||||||
 | 
					- Fixed an issue where pages with `keepAlive: true` set to cache invalidation when the initial load was slow.
 | 
				
			||||||
 | 
					- Fixed an issue where multiple tabs could be activated simultaneously when using the same parameters in different routes.
 | 
				
			||||||
 | 
					- Fixed an issue where the right-click menu on a tab displayed incorrectly when passing `params` parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Optimized the `nprogress` progress bar. It no longer displays when reloading a page or requesting an interface, improving the user experience.
 | 
				
			||||||
 | 
					- Optimized the timing of capturing all unmatched routes and redirecting to a full-screen `404` page.
 | 
				
			||||||
 | 
					- Explicitly configured the `Tailwind CSS` entry file path to improve the contextual recognition and prompting performance of the `Tailwind CSS IntelliSense` plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 6.1.0 (2025-07-31)
 | 
					# 6.1.0 (2025-07-31)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### ✔️ Refactor
 | 
					### ✔️ Refactor
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 6.2.0 (2025-10-16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Added full-screen `403`, `404`, and `500` error pages. These full-screen error pages are clear and secure, improving the user experience.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug Fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed an issue where the built-in homepage did not have a `name` configured, causing cache invalidation after setting the page cache.
 | 
				
			||||||
 | 
					- Fixed an issue where, in an embedded same-origin `iframe` page, when the `beforeunload` event was registered, right-clicking a tab and reloading it would cause the browser to prompt two confirmation blocks.
 | 
				
			||||||
 | 
					- Fixed an issue where pages with `keepAlive: true` set to cache invalidation when the initial load was slow.
 | 
				
			||||||
 | 
					- Fixed an issue where multiple tabs could be activated simultaneously when using the same parameters in different routes.
 | 
				
			||||||
 | 
					- Fixed an issue where the right-click menu on a tab displayed incorrectly when passing `params` parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Optimized the `nprogress` progress bar. It no longer displays when reloading a page or requesting an interface, improving the user experience.
 | 
				
			||||||
 | 
					- Optimized the timing of capturing all unmatched routes and redirecting to a full-screen `404` page.
 | 
				
			||||||
 | 
					- Explicitly configured the `Tailwind CSS` entry file path to improve the contextual recognition and prompting performance of the `Tailwind CSS IntelliSense` plugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 6.1.0 (2025-07-31)
 | 
					# 6.1.0 (2025-07-31)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### ✔️ Refactor
 | 
					### ✔️ Refactor
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,23 @@
 | 
				
			|||||||
 | 
					# 6.2.0 (2025-10-16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🎫 Feat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-  添加全屏`403`、`404`、`500`页面,全屏错误页面清晰且安全,提升用户体验
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🐞 Bug fixes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 修复内置的首页未设置`name`导致设置页面缓存后缓存无效的问题
 | 
				
			||||||
 | 
					- 修复在内嵌同源`iframe`页面中,当其注册了`beforeunload`事件时,右键标签页点击重新加载导致浏览器弹出两次确认拦截的问题
 | 
				
			||||||
 | 
					- 修复设置了`keepAlive: true`的页面在初次加载缓慢的情况下出现的页面缓存失效的问题
 | 
				
			||||||
 | 
					- 修复不同路由使用相同参数时,多个标签页会同时被激活的问题
 | 
				
			||||||
 | 
					- 修复`params`传参模式下标签页右键菜单显示不正确的问题
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 🍏 Perf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 优化`nprogress`进度条,页面重进或接口请求时不再显示进度条,提升用户体验
 | 
				
			||||||
 | 
					- 优化当捕获所有未匹配路由并跳转全屏`404`页面的时机
 | 
				
			||||||
 | 
					- 显式配置`Tailwind CSS`入口文件路径,优化`Tailwind CSS IntelliSense`插件的上下文识别与提示性能
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 6.1.0 (2025-07-31)
 | 
					# 6.1.0 (2025-07-31)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### ✔️ Refactor
 | 
					### ✔️ Refactor
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										60
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								package.json
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "vue-pure-admin",
 | 
					  "name": "vue-pure-admin",
 | 
				
			||||||
  "version": "6.1.0",
 | 
					  "version": "6.2.0",
 | 
				
			||||||
  "private": true,
 | 
					  "private": true,
 | 
				
			||||||
  "type": "module",
 | 
					  "type": "module",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
@ -56,7 +56,7 @@
 | 
				
			|||||||
    "@pureadmin/table": "^3.3.0",
 | 
					    "@pureadmin/table": "^3.3.0",
 | 
				
			||||||
    "@pureadmin/utils": "^2.6.2",
 | 
					    "@pureadmin/utils": "^2.6.2",
 | 
				
			||||||
    "@vue-flow/background": "^1.3.2",
 | 
					    "@vue-flow/background": "^1.3.2",
 | 
				
			||||||
    "@vue-flow/core": "^1.46.4",
 | 
					    "@vue-flow/core": "^1.47.0",
 | 
				
			||||||
    "@vueuse/core": "^13.9.0",
 | 
					    "@vueuse/core": "^13.9.0",
 | 
				
			||||||
    "@vueuse/motion": "^3.0.3",
 | 
					    "@vueuse/motion": "^3.0.3",
 | 
				
			||||||
    "@wangeditor/editor": "^5.1.23",
 | 
					    "@wangeditor/editor": "^5.1.23",
 | 
				
			||||||
@ -70,9 +70,9 @@
 | 
				
			|||||||
    "cropperjs": "^1.6.2",
 | 
					    "cropperjs": "^1.6.2",
 | 
				
			||||||
    "dayjs": "^1.11.18",
 | 
					    "dayjs": "^1.11.18",
 | 
				
			||||||
    "deep-chat": "^2.2.2",
 | 
					    "deep-chat": "^2.2.2",
 | 
				
			||||||
    "echarts": "^5.6.0",
 | 
					    "echarts": "^6.0.0",
 | 
				
			||||||
    "el-table-infinite-scroll": "^3.0.7",
 | 
					    "el-table-infinite-scroll": "^3.0.7",
 | 
				
			||||||
    "element-plus": "^2.11.2",
 | 
					    "element-plus": "^2.11.4",
 | 
				
			||||||
    "highlight.js": "^11.11.1",
 | 
					    "highlight.js": "^11.11.1",
 | 
				
			||||||
    "intro.js": "^7.2.0",
 | 
					    "intro.js": "^7.2.0",
 | 
				
			||||||
    "js-cookie": "^3.0.5",
 | 
					    "js-cookie": "^3.0.5",
 | 
				
			||||||
@ -90,13 +90,13 @@
 | 
				
			|||||||
    "qs": "^6.14.0",
 | 
					    "qs": "^6.14.0",
 | 
				
			||||||
    "responsive-storage": "^2.2.0",
 | 
					    "responsive-storage": "^2.2.0",
 | 
				
			||||||
    "sortablejs": "^1.15.6",
 | 
					    "sortablejs": "^1.15.6",
 | 
				
			||||||
    "swiper": "^11.2.10",
 | 
					    "swiper": "^12.0.2",
 | 
				
			||||||
    "typeit": "^8.8.7",
 | 
					    "typeit": "^8.8.7",
 | 
				
			||||||
    "v-contextmenu": "^3.2.0",
 | 
					    "v-contextmenu": "^3.2.0",
 | 
				
			||||||
    "v3-infinite-loading": "^1.3.2",
 | 
					    "v3-infinite-loading": "^1.3.2",
 | 
				
			||||||
    "vditor": "^3.11.2",
 | 
					    "vditor": "^3.11.2",
 | 
				
			||||||
    "version-rocket": "^1.7.4",
 | 
					    "version-rocket": "^1.7.4",
 | 
				
			||||||
    "vue": "^3.5.21",
 | 
					    "vue": "^3.5.22",
 | 
				
			||||||
    "vue-i18n": "^11.1.12",
 | 
					    "vue-i18n": "^11.1.12",
 | 
				
			||||||
    "vue-json-pretty": "^2.5.0",
 | 
					    "vue-json-pretty": "^2.5.0",
 | 
				
			||||||
    "vue-pdf-embed": "^2.1.3",
 | 
					    "vue-pdf-embed": "^2.1.3",
 | 
				
			||||||
@ -109,25 +109,25 @@
 | 
				
			|||||||
    "vue3-puzzle-vcode": "^1.1.7",
 | 
					    "vue3-puzzle-vcode": "^1.1.7",
 | 
				
			||||||
    "vuedraggable": "^4.1.0",
 | 
					    "vuedraggable": "^4.1.0",
 | 
				
			||||||
    "vxe-table": "4.6.25",
 | 
					    "vxe-table": "4.6.25",
 | 
				
			||||||
    "wavesurfer.js": "^7.10.1",
 | 
					    "wavesurfer.js": "^7.11.0",
 | 
				
			||||||
    "xgplayer": "^3.0.23",
 | 
					    "xgplayer": "^3.0.23",
 | 
				
			||||||
    "xlsx": "^0.18.5"
 | 
					    "xlsx": "^0.18.5"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@commitlint/cli": "^19.8.1",
 | 
					    "@commitlint/cli": "^20.1.0",
 | 
				
			||||||
    "@commitlint/config-conventional": "^19.8.1",
 | 
					    "@commitlint/config-conventional": "^20.0.0",
 | 
				
			||||||
    "@commitlint/types": "^19.8.1",
 | 
					    "@commitlint/types": "^20.0.0",
 | 
				
			||||||
    "@eslint/js": "^9.35.0",
 | 
					    "@eslint/js": "^9.37.0",
 | 
				
			||||||
    "@faker-js/faker": "^9.9.0",
 | 
					    "@faker-js/faker": "^10.0.0",
 | 
				
			||||||
    "@iconify/json": "^2.2.384",
 | 
					    "@iconify/json": "^2.2.393",
 | 
				
			||||||
    "@iconify/vue": "4.2.0",
 | 
					    "@iconify/vue": "4.2.0",
 | 
				
			||||||
    "@intlify/unplugin-vue-i18n": "^6.0.8",
 | 
					    "@intlify/unplugin-vue-i18n": "^11.0.1",
 | 
				
			||||||
    "@tailwindcss/vite": "^4.1.13",
 | 
					    "@tailwindcss/vite": "^4.1.14",
 | 
				
			||||||
    "@types/codemirror": "^5.60.16",
 | 
					    "@types/codemirror": "^5.60.16",
 | 
				
			||||||
    "@types/dagre": "^0.7.53",
 | 
					    "@types/dagre": "^0.7.53",
 | 
				
			||||||
    "@types/intro.js": "^5.1.5",
 | 
					    "@types/intro.js": "^5.1.5",
 | 
				
			||||||
    "@types/js-cookie": "^3.0.6",
 | 
					    "@types/js-cookie": "^3.0.6",
 | 
				
			||||||
    "@types/node": "^20.19.14",
 | 
					    "@types/node": "^20.19.19",
 | 
				
			||||||
    "@types/nprogress": "^0.2.3",
 | 
					    "@types/nprogress": "^0.2.3",
 | 
				
			||||||
    "@types/path-browserify": "^1.0.3",
 | 
					    "@types/path-browserify": "^1.0.3",
 | 
				
			||||||
    "@types/qrcode": "^1.5.5",
 | 
					    "@types/qrcode": "^1.5.5",
 | 
				
			||||||
@ -136,35 +136,35 @@
 | 
				
			|||||||
    "@vitejs/plugin-vue": "^6.0.1",
 | 
					    "@vitejs/plugin-vue": "^6.0.1",
 | 
				
			||||||
    "@vitejs/plugin-vue-jsx": "^5.1.1",
 | 
					    "@vitejs/plugin-vue-jsx": "^5.1.1",
 | 
				
			||||||
    "boxen": "^8.0.1",
 | 
					    "boxen": "^8.0.1",
 | 
				
			||||||
    "code-inspector-plugin": "^1.2.8",
 | 
					    "code-inspector-plugin": "^1.2.10",
 | 
				
			||||||
    "cssnano": "^7.1.1",
 | 
					    "cssnano": "^7.1.1",
 | 
				
			||||||
    "dagre": "^0.8.5",
 | 
					    "dagre": "^0.8.5",
 | 
				
			||||||
    "eslint": "^9.35.0",
 | 
					    "eslint": "^9.37.0",
 | 
				
			||||||
    "eslint-config-prettier": "^10.1.8",
 | 
					    "eslint-config-prettier": "^10.1.8",
 | 
				
			||||||
    "eslint-plugin-prettier": "^5.5.4",
 | 
					    "eslint-plugin-prettier": "^5.5.4",
 | 
				
			||||||
    "eslint-plugin-vue": "^10.4.0",
 | 
					    "eslint-plugin-vue": "^10.5.0",
 | 
				
			||||||
    "gradient-string": "^3.0.0",
 | 
					    "gradient-string": "^3.0.0",
 | 
				
			||||||
    "husky": "^9.1.7",
 | 
					    "husky": "^9.1.7",
 | 
				
			||||||
    "lint-staged": "^16.1.6",
 | 
					    "lint-staged": "^16.2.3",
 | 
				
			||||||
    "postcss": "^8.5.6",
 | 
					    "postcss": "^8.5.6",
 | 
				
			||||||
    "postcss-html": "^1.8.0",
 | 
					    "postcss-html": "^1.8.0",
 | 
				
			||||||
    "postcss-load-config": "^6.0.1",
 | 
					    "postcss-load-config": "^6.0.1",
 | 
				
			||||||
    "postcss-scss": "^4.0.9",
 | 
					    "postcss-scss": "^4.0.9",
 | 
				
			||||||
    "prettier": "^3.6.2",
 | 
					    "prettier": "^3.6.2",
 | 
				
			||||||
    "rimraf": "^6.0.1",
 | 
					    "rimraf": "^6.0.1",
 | 
				
			||||||
    "rollup-plugin-visualizer": "^6.0.3",
 | 
					    "rollup-plugin-visualizer": "^6.0.4",
 | 
				
			||||||
    "sass": "^1.92.1",
 | 
					    "sass": "^1.93.2",
 | 
				
			||||||
    "stylelint": "^16.24.0",
 | 
					    "stylelint": "^16.25.0",
 | 
				
			||||||
    "stylelint-config-recess-order": "^7.3.0",
 | 
					    "stylelint-config-recess-order": "^7.3.0",
 | 
				
			||||||
    "stylelint-config-recommended-vue": "^1.6.1",
 | 
					    "stylelint-config-recommended-vue": "^1.6.1",
 | 
				
			||||||
    "stylelint-config-standard-scss": "^14.0.0",
 | 
					    "stylelint-config-standard-scss": "^14.0.0",
 | 
				
			||||||
    "stylelint-prettier": "^5.0.3",
 | 
					    "stylelint-prettier": "^5.0.3",
 | 
				
			||||||
    "svgo": "^4.0.0",
 | 
					    "svgo": "^4.0.0",
 | 
				
			||||||
    "tailwindcss": "^4.1.13",
 | 
					    "tailwindcss": "^4.1.14",
 | 
				
			||||||
    "typescript": "^5.9.2",
 | 
					    "typescript": "^5.9.3",
 | 
				
			||||||
    "typescript-eslint": "^8.43.0",
 | 
					    "typescript-eslint": "^8.46.0",
 | 
				
			||||||
    "unplugin-icons": "^22.3.0",
 | 
					    "unplugin-icons": "^22.4.2",
 | 
				
			||||||
    "vite": "^7.1.5",
 | 
					    "vite": "^7.1.9",
 | 
				
			||||||
    "vite-plugin-cdn-import": "^1.0.1",
 | 
					    "vite-plugin-cdn-import": "^1.0.1",
 | 
				
			||||||
    "vite-plugin-compression": "^0.5.1",
 | 
					    "vite-plugin-compression": "^0.5.1",
 | 
				
			||||||
    "vite-plugin-fake-server": "^2.2.0",
 | 
					    "vite-plugin-fake-server": "^2.2.0",
 | 
				
			||||||
@ -172,10 +172,10 @@
 | 
				
			|||||||
    "vite-plugin-router-warn": "^1.0.0",
 | 
					    "vite-plugin-router-warn": "^1.0.0",
 | 
				
			||||||
    "vite-svg-loader": "^5.1.0",
 | 
					    "vite-svg-loader": "^5.1.0",
 | 
				
			||||||
    "vue-eslint-parser": "^10.2.0",
 | 
					    "vue-eslint-parser": "^10.2.0",
 | 
				
			||||||
    "vue-tsc": "^3.0.7"
 | 
					    "vue-tsc": "^3.1.1"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "engines": {
 | 
					  "engines": {
 | 
				
			||||||
    "node": "^20.19.0 || >=22.12.0",
 | 
					    "node": "^20.19.0 || >=22.13.0",
 | 
				
			||||||
    "pnpm": ">=9"
 | 
					    "pnpm": ">=9"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "pnpm": {
 | 
					  "pnpm": {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2353
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2353
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "Version": "6.1.0",
 | 
					  "Version": "6.2.0",
 | 
				
			||||||
  "Title": "PureAdmin",
 | 
					  "Title": "PureAdmin",
 | 
				
			||||||
  "FixedHeader": true,
 | 
					  "FixedHeader": true,
 | 
				
			||||||
  "HiddenSideBar": false,
 | 
					  "HiddenSideBar": false,
 | 
				
			||||||
 | 
				
			|||||||
@ -356,7 +356,7 @@ function onClickDrop(key, item, selectRoute?: RouteConfigs) {
 | 
				
			|||||||
      break;
 | 
					      break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  setTimeout(() => {
 | 
					  setTimeout(() => {
 | 
				
			||||||
    showMenuModel(route.fullPath, route.query);
 | 
					    showMenuModel(route.fullPath, route.query, route.params);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -391,15 +391,18 @@ function disabledMenus(value: boolean, fixedTag = false) {
 | 
				
			|||||||
function showMenuModel(
 | 
					function showMenuModel(
 | 
				
			||||||
  currentPath: string,
 | 
					  currentPath: string,
 | 
				
			||||||
  query: object = {},
 | 
					  query: object = {},
 | 
				
			||||||
 | 
					  params: object = {},
 | 
				
			||||||
  refresh = false
 | 
					  refresh = false
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  const allRoute = multiTags.value;
 | 
					  const allRoute = multiTags.value;
 | 
				
			||||||
  const routeLength = multiTags.value.length;
 | 
					  const routeLength = multiTags.value.length;
 | 
				
			||||||
  let currentIndex = -1;
 | 
					  let currentIndex = -1;
 | 
				
			||||||
  if (isAllEmpty(query)) {
 | 
					  if (!isAllEmpty(params)) {
 | 
				
			||||||
    currentIndex = allRoute.findIndex(v => v.path === currentPath);
 | 
					    currentIndex = allRoute.findIndex(v => isEqual(v.params, params));
 | 
				
			||||||
  } else {
 | 
					  } else if (!isAllEmpty(query)) {
 | 
				
			||||||
    currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
 | 
					    currentIndex = allRoute.findIndex(v => isEqual(v.query, query));
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    currentIndex = allRoute.findIndex(v => v.path === currentPath);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  function fixedTagDisabled() {
 | 
					  function fixedTagDisabled() {
 | 
				
			||||||
    if (allRoute[currentIndex]?.meta?.fixedTag) {
 | 
					    if (allRoute[currentIndex]?.meta?.fixedTag) {
 | 
				
			||||||
@ -465,14 +468,14 @@ function openMenu(tag, e) {
 | 
				
			|||||||
  } else if (route.path !== tag.path && route.name !== tag.name) {
 | 
					  } else if (route.path !== tag.path && route.name !== tag.name) {
 | 
				
			||||||
    // 右键菜单不匹配当前路由,隐藏刷新
 | 
					    // 右键菜单不匹配当前路由,隐藏刷新
 | 
				
			||||||
    tagsViews[0].show = false;
 | 
					    tagsViews[0].show = false;
 | 
				
			||||||
    showMenuModel(tag.path, tag.query);
 | 
					    showMenuModel(tag.path, tag.query, tag.params);
 | 
				
			||||||
  } else if (multiTags.value.length === 2 && route.path !== tag.path) {
 | 
					  } else if (multiTags.value.length === 2 && route.path !== tag.path) {
 | 
				
			||||||
    showMenus(true);
 | 
					    showMenus(true);
 | 
				
			||||||
    // 只有两个标签时不显示关闭其他标签页
 | 
					    // 只有两个标签时不显示关闭其他标签页
 | 
				
			||||||
    tagsViews[4].show = false;
 | 
					    tagsViews[4].show = false;
 | 
				
			||||||
  } else if (route.path === tag.path) {
 | 
					    showMenuModel(tag.path, tag.query, tag.params);
 | 
				
			||||||
    // 右键当前激活的菜单
 | 
					  } else {
 | 
				
			||||||
    showMenuModel(tag.path, tag.query, true);
 | 
					    showMenuModel(tag.path, tag.query, tag.params, true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  currentSelect.value = tag;
 | 
					  currentSelect.value = tag;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,22 @@ const loading = ref(true);
 | 
				
			|||||||
const currentRoute = useRoute();
 | 
					const currentRoute = useRoute();
 | 
				
			||||||
const frameSrc = ref<string>("");
 | 
					const frameSrc = ref<string>("");
 | 
				
			||||||
const frameRef = ref<HTMLElement | null>(null);
 | 
					const frameRef = ref<HTMLElement | null>(null);
 | 
				
			||||||
 | 
					const fallbackTimer = ref<number | null>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (unref(currentRoute.meta)?.frameSrc) {
 | 
					if (unref(currentRoute.meta)?.frameSrc) {
 | 
				
			||||||
  frameSrc.value = unref(currentRoute.meta)?.frameSrc as string;
 | 
					  frameSrc.value = unref(currentRoute.meta)?.frameSrc as string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
unref(currentRoute.meta)?.frameLoading === false && hideLoading();
 | 
					
 | 
				
			||||||
 | 
					function clearFallbackTimer() {
 | 
				
			||||||
 | 
					  if (fallbackTimer.value !== null) {
 | 
				
			||||||
 | 
					    clearTimeout(fallbackTimer.value);
 | 
				
			||||||
 | 
					    fallbackTimer.value = null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function hideLoading() {
 | 
					function hideLoading() {
 | 
				
			||||||
  loading.value = false;
 | 
					  loading.value = false;
 | 
				
			||||||
 | 
					  clearFallbackTimer();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function init() {
 | 
					function init() {
 | 
				
			||||||
@ -34,32 +43,42 @@ function init() {
 | 
				
			|||||||
    if (!iframe) return;
 | 
					    if (!iframe) return;
 | 
				
			||||||
    const _frame = iframe as any;
 | 
					    const _frame = iframe as any;
 | 
				
			||||||
    if (_frame.attachEvent) {
 | 
					    if (_frame.attachEvent) {
 | 
				
			||||||
      _frame.attachEvent("onload", () => {
 | 
					      _frame.attachEvent("onload", hideLoading);
 | 
				
			||||||
        hideLoading();
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      iframe.onload = () => {
 | 
					      iframe.onload = hideLoading;
 | 
				
			||||||
        hideLoading();
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let isRedirect = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => currentRoute.fullPath,
 | 
					  () => currentRoute.fullPath,
 | 
				
			||||||
  path => {
 | 
					  path => {
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
      currentRoute.name === "Redirect" &&
 | 
					      currentRoute.name === "Redirect" &&
 | 
				
			||||||
      path.includes(props.frameInfo?.fullPath)
 | 
					      props.frameInfo?.fullPath &&
 | 
				
			||||||
 | 
					      path.includes(props.frameInfo.fullPath)
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
      frameSrc.value = path; // redirect时,置换成任意值,待重定向后 重新赋值
 | 
					      isRedirect = true;
 | 
				
			||||||
      loading.value = true;
 | 
					      loading.value = true;
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // 重新赋值
 | 
					    if (props.frameInfo?.fullPath === path && isRedirect) {
 | 
				
			||||||
    if (props.frameInfo?.fullPath === path) {
 | 
					      loading.value = true;
 | 
				
			||||||
      frameSrc.value = props.frameInfo?.frameSrc;
 | 
					      clearFallbackTimer();
 | 
				
			||||||
 | 
					      const url = new URL(props.frameInfo.frameSrc, window.location.origin);
 | 
				
			||||||
 | 
					      const joinChar = url.search ? "&" : "?";
 | 
				
			||||||
 | 
					      frameSrc.value = `${props.frameInfo.frameSrc}${joinChar}t=${Date.now()}`;
 | 
				
			||||||
 | 
					      fallbackTimer.value = window.setTimeout(() => {
 | 
				
			||||||
 | 
					        if (loading.value) {
 | 
				
			||||||
 | 
					          hideLoading();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }, 1500);
 | 
				
			||||||
 | 
					      isRedirect = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
 | 
					  { immediate: true }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onMounted(() => {
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
				
			|||||||
@ -114,14 +114,21 @@ export function useTags() {
 | 
				
			|||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function conditionHandle(item, previous, next) {
 | 
					  function conditionHandle(item, previous, next) {
 | 
				
			||||||
 | 
					    const currentName = route.name || "";
 | 
				
			||||||
 | 
					    const itemName = item.name || "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
 | 
					    if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
 | 
				
			||||||
      if (Object.keys(route.query).length > 0) {
 | 
					      if (Object.keys(route.query).length > 0) {
 | 
				
			||||||
        return isEqual(route.query, item.query) ? previous : next;
 | 
					        return currentName === itemName && isEqual(route.query, item.query)
 | 
				
			||||||
 | 
					          ? previous
 | 
				
			||||||
 | 
					          : next;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        return isEqual(route.params, item.params) ? previous : next;
 | 
					        return currentName === itemName && isEqual(route.params, item.params)
 | 
				
			||||||
 | 
					          ? previous
 | 
				
			||||||
 | 
					          : next;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return route.path === item.path ? previous : next;
 | 
					      return currentName === itemName ? previous : next;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -80,22 +80,15 @@ export const useMultiTagsStore = defineStore("pure-multiTags", {
 | 
				
			|||||||
            if (isBoolean(tagVal?.meta?.showLink) && !tagVal?.meta?.showLink)
 | 
					            if (isBoolean(tagVal?.meta?.showLink) && !tagVal?.meta?.showLink)
 | 
				
			||||||
              return;
 | 
					              return;
 | 
				
			||||||
            const tagPath = tagVal.path;
 | 
					            const tagPath = tagVal.path;
 | 
				
			||||||
            // 判断tag是否已存在
 | 
					 | 
				
			||||||
            const tagHasExits = this.multiTags.some(tag => {
 | 
					            const tagHasExits = this.multiTags.some(tag => {
 | 
				
			||||||
              return tag.path === tagPath;
 | 
					              return (
 | 
				
			||||||
 | 
					                tag.path === tagPath &&
 | 
				
			||||||
 | 
					                isEqual(tag?.query, tagVal?.query) &&
 | 
				
			||||||
 | 
					                isEqual(tag?.params, tagVal?.params)
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 判断tag中的query键值是否相等
 | 
					            if (tagHasExits) return;
 | 
				
			||||||
            const tagQueryHasExits = this.multiTags.some(tag => {
 | 
					 | 
				
			||||||
              return isEqual(tag?.query, tagVal?.query);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // 判断tag中的params键值是否相等
 | 
					 | 
				
			||||||
            const tagParamsHasExits = this.multiTags.some(tag => {
 | 
					 | 
				
			||||||
              return isEqual(tag?.params, tagVal?.params);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (tagHasExits && tagQueryHasExits && tagParamsHasExits) return;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 动态路由可打开的最大数量
 | 
					            // 动态路由可打开的最大数量
 | 
				
			||||||
            const dynamicLevel = tagVal?.meta?.dynamicLevel ?? -1;
 | 
					            const dynamicLevel = tagVal?.meta?.dynamicLevel ?? -1;
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,6 @@ import { defineStore } from "pinia";
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  type cacheType,
 | 
					  type cacheType,
 | 
				
			||||||
  store,
 | 
					  store,
 | 
				
			||||||
  debounce,
 | 
					 | 
				
			||||||
  ascending,
 | 
					  ascending,
 | 
				
			||||||
  getKeyList,
 | 
					  getKeyList,
 | 
				
			||||||
  filterTree,
 | 
					  filterTree,
 | 
				
			||||||
@ -33,33 +32,35 @@ export const usePermissionStore = defineStore("pure-permission", {
 | 
				
			|||||||
        this.constantMenus.concat(routes) as any
 | 
					        this.constantMenus.concat(routes) as any
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    /** 监听缓存页面是否存在于标签页,不存在则删除 */
 | 
				
			||||||
 | 
					    clearCache() {
 | 
				
			||||||
 | 
					      let cacheLength = this.cachePageList.length;
 | 
				
			||||||
 | 
					      const nameList = getKeyList(useMultiTagsStoreHook().multiTags, "name");
 | 
				
			||||||
 | 
					      while (cacheLength > 0) {
 | 
				
			||||||
 | 
					        nameList.findIndex(v => v === this.cachePageList[cacheLength - 1]) ===
 | 
				
			||||||
 | 
					          -1 &&
 | 
				
			||||||
 | 
					          this.cachePageList.splice(
 | 
				
			||||||
 | 
					            this.cachePageList.indexOf(this.cachePageList[cacheLength - 1]),
 | 
				
			||||||
 | 
					            1
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        cacheLength--;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    cacheOperate({ mode, name }: cacheType) {
 | 
					    cacheOperate({ mode, name }: cacheType) {
 | 
				
			||||||
      const delIndex = this.cachePageList.findIndex(v => v === name);
 | 
					      const delIndex = this.cachePageList.findIndex(v => v === name);
 | 
				
			||||||
      switch (mode) {
 | 
					      switch (mode) {
 | 
				
			||||||
        case "refresh":
 | 
					        case "refresh":
 | 
				
			||||||
          this.cachePageList = this.cachePageList.filter(v => v !== name);
 | 
					          this.cachePageList = this.cachePageList.filter(v => v !== name);
 | 
				
			||||||
 | 
					          this.clearCache();
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case "add":
 | 
					        case "add":
 | 
				
			||||||
          this.cachePageList.push(name);
 | 
					          this.cachePageList.push(name);
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case "delete":
 | 
					        case "delete":
 | 
				
			||||||
          delIndex !== -1 && this.cachePageList.splice(delIndex, 1);
 | 
					          delIndex !== -1 && this.cachePageList.splice(delIndex, 1);
 | 
				
			||||||
 | 
					          this.clearCache();
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      /** 监听缓存页面是否存在于标签页,不存在则删除 */
 | 
					 | 
				
			||||||
      debounce(() => {
 | 
					 | 
				
			||||||
        let cacheLength = this.cachePageList.length;
 | 
					 | 
				
			||||||
        const nameList = getKeyList(useMultiTagsStoreHook().multiTags, "name");
 | 
					 | 
				
			||||||
        while (cacheLength > 0) {
 | 
					 | 
				
			||||||
          nameList.findIndex(v => v === this.cachePageList[cacheLength - 1]) ===
 | 
					 | 
				
			||||||
            -1 &&
 | 
					 | 
				
			||||||
            this.cachePageList.splice(
 | 
					 | 
				
			||||||
              this.cachePageList.indexOf(this.cachePageList[cacheLength - 1]),
 | 
					 | 
				
			||||||
              1
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
          cacheLength--;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })();
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    /** 清空缓存页面 */
 | 
					    /** 清空缓存页面 */
 | 
				
			||||||
    clearAllCachePage() {
 | 
					    clearAllCachePage() {
 | 
				
			||||||
 | 
				
			|||||||
@ -68,7 +68,7 @@ onMounted(() => {
 | 
				
			|||||||
        <span class="font-medium">
 | 
					        <span class="font-medium">
 | 
				
			||||||
          流程图组件,采用开源的
 | 
					          流程图组件,采用开源的
 | 
				
			||||||
          <el-link
 | 
					          <el-link
 | 
				
			||||||
            href="https://site.logic-flow.cn/docs/#/zh/guide/start"
 | 
					            href="https://site.logic-flow.cn/tutorial/get-started"
 | 
				
			||||||
            target="_blank"
 | 
					            target="_blank"
 | 
				
			||||||
            style="margin: 0 4px 5px; font-size: 16px"
 | 
					            style="margin: 0 4px 5px; font-size: 16px"
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user