mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-10-31 13:53:43 +08:00 
			
		
		
		
	Compare commits
	
		
			80 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | a454b620f1 | ||
|  | 752ec1e9e7 | ||
|  | e035eab223 | ||
|  | be13ca274b | ||
|  | 72ede8bf9c | ||
|  | 0d20e4c915 | ||
|  | c791adc6bc | ||
|  | 693f704690 | ||
|  | 49f60b2d50 | ||
|  | 425c69acc2 | ||
|  | f7de3fd0f1 | ||
|  | c7f6f2a537 | ||
|  | 531432d5ff | ||
|  | ff1d50461f | ||
|  | b5027c8f3e | ||
|  | 1e67ae8c49 | ||
|  | 5c67d0650e | ||
|  | af735e87b8 | ||
|  | b336841567 | ||
|  | b094d6882b | ||
|  | b94baa18c1 | ||
|  | 3eeace94dd | ||
|  | ad2f24707a | ||
|  | cd9d58d4de | ||
|  | 2198b982f0 | ||
|  | 376e2f7d84 | ||
|  | 069fa8a817 | ||
|  | b5a723cb5f | ||
|  | 79e85bc6b5 | ||
|  | bf7183747b | ||
|  | aabb2a49c4 | ||
|  | 7026126a57 | ||
|  | c212565248 | ||
|  | 813d8ce4c7 | ||
|  | 20a8127434 | ||
|  | ec8cadd183 | ||
|  | 4470cb4e8c | ||
|  | 8f9a70505c | ||
|  | 9094b21cbb | ||
|  | 6259287240 | ||
|  | 22004ff4dc | ||
|  | 08827a42a3 | ||
|  | 6a6eb9afd6 | ||
|  | ff51b72dac | ||
|  | fe06b8c499 | ||
|  | 4b63bbcf67 | ||
|  | 5531a68641 | ||
|  | 584cd54d6d | ||
|  | 2bec899031 | ||
|  | 83862ba76e | ||
|  | 060c0a91c7 | ||
|  | 76649e2a08 | ||
|  | ddf3823a55 | ||
|  | e75fd73f34 | ||
|  | 1f4647b995 | ||
|  | 910dfca8bb | ||
|  | ffb48b15bc | ||
|  | e6086f0f35 | ||
|  | 9b05d73e6d | ||
|  | bd69c00e74 | ||
|  | d08a3817d1 | ||
|  | d0380ce5cb | ||
|  | 756f84ab1d | ||
|  | 5a4f844d24 | ||
|  | 59faf15229 | ||
|  | 5bd96b8dd3 | ||
|  | 8efdb10d86 | ||
|  | 2aa85c6f93 | ||
|  | 3ad438984e | ||
|  | f1850416c8 | ||
|  | 086bad474e | ||
|  | 42b121a117 | ||
|  | db64b0e2e9 | ||
|  | 40d0f8ac1c | ||
|  | 87b18386f5 | ||
|  | 4c1c7e6599 | ||
|  | ac78b9a394 | ||
|  | e379d6ce67 | ||
|  | 64fc0996e3 | ||
|  | bc8dc47d7f | 
| @@ -1,5 +1,5 @@ | ||||
| # backend service base url, prod environment | ||||
| VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default | ||||
| VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default | ||||
|  | ||||
| # other backend service base url, prod environment | ||||
| VITE_OTHER_SERVICE_BASE_URL= `{ | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| # backend service base url, test environment | ||||
| VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default | ||||
| VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default | ||||
|  | ||||
| # other backend service base url, test environment | ||||
| VITE_OTHER_SERVICE_BASE_URL= `{ | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug-report_cn.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug-report_cn.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| name: Bug提交 | ||||
| name: 🐞 Bug提交 | ||||
| description: 在使用软件或功能的过程中遇到了错误 | ||||
| title: '[Bug]: ' | ||||
| labels: [ "bug?" ] | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug-report_en.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug-report_en.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| name: Bug Report | ||||
| name: 🐞 Bug Report | ||||
| description: Encountered an error while using the software or feature | ||||
| title: '[Bug]: ' | ||||
| labels: [ "bug?" ] | ||||
|   | ||||
							
								
								
									
										48
									
								
								.github/ISSUE_TEMPLATE/feature_request_cn.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								.github/ISSUE_TEMPLATE/feature_request_cn.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| --- | ||||
| name: 🚀 功能请求 | ||||
| description: 提出一个想法以帮助我们改进W&B | ||||
| title: "[功能]: " | ||||
| labels: | ||||
|   - "功能请求" | ||||
|  | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         **感谢 :heart: 您花时间填写此功能请求报告!** | ||||
|         我们恳请您搜索看看您的功能是否[已经存在](https://github.com/soybeanjs/soybean-admin/issues?q=is%3Aissue+sort%3Acreated-desc+)。 | ||||
|  | ||||
|         我们也很乐意接受用户的贡献。有关更多详细信息,请参阅[此处](https://github.com/soybeanjs/soybean-admin/blob/main/README.zh_CN.md#%E5%A6%82%E4%BD%95%E8%B4%A1%E7%8C%AE)。 | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: 描述 | ||||
|       description: | | ||||
|         对您感兴趣的功能的清晰简洁的描述。 | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: 建议的解决方案 | ||||
|       description: | | ||||
|         描述您想要的解决方案。对您希望发生的事情的清晰简洁的描述。 | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: 替代方案 | ||||
|       description: | | ||||
|         描述您考虑过的替代方案。 | ||||
|         对您考虑过的任何替代解决方案或功能的清晰简洁的描述。 | ||||
|     validations: | ||||
|       required: false | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: 额外的上下文 | ||||
|       description: | | ||||
|         在此处添加有关问题的其他上下文。 | ||||
|     validations: | ||||
|       required: false | ||||
							
								
								
									
										48
									
								
								.github/ISSUE_TEMPLATE/feature_request_en.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								.github/ISSUE_TEMPLATE/feature_request_en.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| --- | ||||
| name: 🚀 Feature Request | ||||
| description: Suggest an idea to help us improve W&B | ||||
| title: "[Feature]: " | ||||
| labels: | ||||
|   - "feature_request" | ||||
|  | ||||
| body: | ||||
|   - type: markdown | ||||
|     attributes: | ||||
|       value: | | ||||
|         **Thanks :heart: for taking the time to fill out this feature request report!** | ||||
|         We kindly ask that you search to see if an issue [already exists](https://github.com/soybeanjs/soybean-admin/issues?q=is%3Aissue+sort%3Acreated-desc+) for your feature. | ||||
|  | ||||
|         We are also happy to accept contributions from our users. For more details see [here](https://github.com/soybeanjs/soybean-admin/blob/main/README.md#how-to-contribute). | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Description | ||||
|       description: | | ||||
|         A clear and concise description of the feature you're interested in. | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Suggested Solution | ||||
|       description: | | ||||
|         Describe the solution you'd like. A clear and concise description of what you want to happen. | ||||
|     validations: | ||||
|       required: true | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Alternatives | ||||
|       description: | | ||||
|         Describe alternatives you've considered. | ||||
|         A clear and concise description of any alternative solutions or features you've considered. | ||||
|     validations: | ||||
|       required: false | ||||
|  | ||||
|   - type: textarea | ||||
|     attributes: | ||||
|       label: Additional Context | ||||
|       description: | | ||||
|         Add any other context about the problem here. | ||||
|     validations: | ||||
|       required: false | ||||
							
								
								
									
										2
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @@ -12,7 +12,7 @@ | ||||
|       "type": "node", | ||||
|       "request": "launch", | ||||
|       "name": "TS Debugger", | ||||
|       "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx", | ||||
|       "runtimeExecutable": "tsx", | ||||
|       "skipFiles": ["<node_internals>/**", "${workspaceFolder}/node_modules/**"], | ||||
|       "program": "${file}" | ||||
|     } | ||||
|   | ||||
							
								
								
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
|     "source.fixAll.eslint": "explicit", | ||||
|     "source.organizeImports": "never" | ||||
|   }, | ||||
|   "eslint.experimental.useFlatConfig": true, | ||||
|   "eslint.useFlatConfig": true, | ||||
|   "editor.formatOnSave": false, | ||||
|   "eslint.validate": ["html", "css", "scss", "json", "jsonc"], | ||||
|   "i18n-ally.displayLanguage": "zh-cn", | ||||
| @@ -14,5 +14,6 @@ | ||||
|   "i18n-ally.localesPaths": ["src/locales/langs"], | ||||
|   "prettier.enable": false, | ||||
|   "typescript.tsdk": "node_modules/typescript/lib", | ||||
|   "unocss.root": ["./"] | ||||
|   "unocss.root": ["./"], | ||||
|   "vue.server.hybridMode": true | ||||
| } | ||||
|   | ||||
							
								
								
									
										271
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										271
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,6 +1,277 @@ | ||||
| # Changelog | ||||
|  | ||||
|  | ||||
| ## [v1.2.7](https://github.com/honghuangdc/soybean-admin/compare/v1.2.6...v1.2.7) (2024-07-12) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: supports custom menu icon sizes  -  by @wynn-w in https://github.com/honghuangdc/soybean-admin/issues/534 [<samp>(e035e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e035eab) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: | ||||
|   - update deps  -  by @honghuangdc [<samp>(72ede)</samp>](https://github.com/honghuangdc/soybean-admin/commit/72ede8b) | ||||
|   - update deps  -  by @honghuangdc [<samp>(be13c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/be13ca2) | ||||
|   - update deps  -  by @honghuangdc [<samp>(752ec)</samp>](https://github.com/honghuangdc/soybean-admin/commit/752ec1e) | ||||
| - **projects**: | ||||
|   - Fix deprecated configuration config  -  by @paynezhuang in https://github.com/honghuangdc/soybean-admin/issues/524 [<samp>(0d20e)</samp>](https://github.com/honghuangdc/soybean-admin/commit/0d20e4c) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/honghuangdc)  [](https://github.com/wynn-w)  [](https://github.com/paynezhuang)   | ||||
|  | ||||
| ## [v1.2.6](https://github.com/honghuangdc/soybean-admin/compare/v1.2.5...v1.2.6) (2024-06-21) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: | ||||
|   - request modal title use i18n. fixed #507  -  by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/507 [<samp>(f7de3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/f7de3fd) | ||||
|   - add `getDataByPage` for `useTable`. fixed #499  -  by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/499 [<samp>(425c6)</samp>](https://github.com/honghuangdc/soybean-admin/commit/425c69a) | ||||
|   - fix login redirect to routeHome when routeHome of dynamic route is not same as static route. fixed #511  -  by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/511 [<samp>(49f60)</samp>](https://github.com/honghuangdc/soybean-admin/commit/49f60b2) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: optimize `getRouteQueryOfLoginRoute`  -  by @honghuangdc [<samp>(693f7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/693f704) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: | ||||
|   - update CHANGELOG  -  by @honghuangdc [<samp>(5c67d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/5c67d06) | ||||
|   - update README  -  by @honghuangdc [<samp>(1e67a)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1e67ae8) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: | ||||
|   - update deps. close #510  -  by @honghuangdc in https://github.com/honghuangdc/soybean-admin/issues/510 [<samp>(53143)</samp>](https://github.com/honghuangdc/soybean-admin/commit/531432d) | ||||
|   - update deps  -  by @honghuangdc [<samp>(c7f6f)</samp>](https://github.com/honghuangdc/soybean-admin/commit/c7f6f2a) | ||||
|  | ||||
| ###    🤖 CI | ||||
|  | ||||
| - **projects**: | ||||
|   - add github issues template  -  by @honghuangdc [<samp>(b5027)</samp>](https://github.com/honghuangdc/soybean-admin/commit/b5027c8) | ||||
|   - update github issues template  -  by @honghuangdc [<samp>(ff1d5)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff1d504) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/honghuangdc)   | ||||
|  | ||||
| ## [v1.2.5](https://github.com/soybeanjs/soybean-admin/compare/v1.2.4...v1.2.5) (2024-06-15) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: Fix the issue of abnormal tab caching after logout. fixed #495  -  by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/495 [<samp>(3eeac)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eeace9) | ||||
|  | ||||
| ###    🔥 Performance | ||||
|  | ||||
| - **project**: Initializing the static routing function does not require asynchronization  -  by **CHENZL** in https://github.com/soybeanjs/soybean-admin/issues/493 [<samp>(2198b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2198b98) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: optimize code  -  by @soybeanjs [<samp>(b94ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b94baa1) | ||||
| - **types**: Enhance compatibility of global types  -  by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/494 [<samp>(cd9d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cd9d58d) | ||||
| - **utils**: Reduce code indentation and improve readability  -  by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/496 [<samp>(ad2f2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ad2f247) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: update CHANGELOG  -  by @soybeanjs [<samp>(b3368)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b336841) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: update deps  -  by @soybeanjs [<samp>(b094d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b094d68) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)   | ||||
| [CHENZL](mailto:zlong5568863@qq.com) | ||||
|  | ||||
| ## [v1.2.4](https://github.com/soybeanjs/soybean-admin/compare/v1.2.3...v1.2.4) (2024-06-14) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: | ||||
|   - optimize `setupAppVersionNotification`  -  by @soybeanjs [<samp>(b5a72)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5a723c) | ||||
|   - get buildTime with timezone 'Asia/Shanghai'  -  by @soybeanjs [<samp>(069fa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/069fa8a) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
| ## [v1.2.3](https://github.com/soybeanjs/soybean-admin/compare/v1.2.2...v1.2.3) (2024-06-13) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: | ||||
|   - fix mobile browser theme issue by adding color-scheme meta tag to index.html  -  by @KickCashew in https://github.com/soybeanjs/soybean-admin/issues/488 [<samp>(c2125)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c212565) | ||||
|   - Fix secondary directory components is empty  -  by @paynezhuang in https://github.com/soybeanjs/soybean-admin/issues/491 [<samp>(aabb2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/aabb2a4) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: | ||||
|   - Fixed the hyperlink pointing error  -  by **Azir** [<samp>(20a81)</samp>](https://github.com/soybeanjs/soybean-admin/commit/20a8127) | ||||
|   - update README  -  by @soybeanjs [<samp>(70261)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7026126) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: | ||||
|   - update deps  -  by @soybeanjs [<samp>(813d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/813d8ce) | ||||
|   - update deps  -  by @soybeanjs [<samp>(bf718)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bf71837) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/paynezhuang)  [](https://github.com/KickCashew)   | ||||
| [Azir](mailto:2075125282@qq.com) | ||||
|  | ||||
| ## [v1.2.2](https://github.com/honghuangdc/soybean-admin/compare/v1.2.1...v1.2.2) (2024-06-12) | ||||
|  | ||||
| ###    🚀 Features | ||||
|  | ||||
| - **projects**: reset scroll position when tab change  -  by @soybeanjs [<samp>(9094b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9094b21) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: | ||||
|   - hide AppVersionNotification in DEV mode  -  by @sigma-plus in https://github.com/honghuangdc/soybean-admin/issues/482 [<samp>(62592)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6259287) | ||||
|   - fix menu-toggler hidden in mobile layout. fixed #483  -  by @soybeanjs in https://github.com/honghuangdc/soybean-admin/issues/483 [<samp>(4470c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4470cb4) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: update README  -  by @soybeanjs [<samp>(8f9a7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8f9a705) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/sigma-plus)   | ||||
|  | ||||
| ## [v1.2.1](https://github.com/honghuangdc/soybean-admin/compare/v1.2.0...v1.2.1) (2024-06-07) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: | ||||
|   - fix get user info when page reload  -  by @soybeanjs [<samp>(ff51b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff51b72) | ||||
|   - fix setupAppVersionNotification render  -  by @soybeanjs [<samp>(6a6eb)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6a6eb9a) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: update CHANGELOG  -  by @soybeanjs [<samp>(fe06b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/fe06b8c) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: update deps  -  by @soybeanjs [<samp>(08827)</samp>](https://github.com/honghuangdc/soybean-admin/commit/08827a4) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
| ## [v1.2.0](https://github.com/soybeanjs/soybean-admin/compare/v1.1.5...v1.2.0) (2024-06-06) | ||||
|  | ||||
| ###    🚀 Features | ||||
|  | ||||
| - **projects**: | ||||
|   - support system new version update notification. close #420  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/420 [<samp>(584cd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/584cd54) | ||||
|   - get user info in router guard and remove in localStorage. close #459  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/459 [<samp>(5531a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5531a68) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: update CHANGELOG  -  by @soybeanjs [<samp>(2bec8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2bec899) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
| ## [v1.1.5](https://github.com/soybeanjs/soybean-admin/compare/v1.1.4...v1.1.5) (2024-06-06) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: fix register name, CodeLogin => Register  -  by @m-xlsea in https://github.com/soybeanjs/soybean-admin/issues/478 [<samp>(ddf38)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ddf3823) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: update deps  -  by @soybeanjs [<samp>(060c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/060c0a9) | ||||
| - **projects**: update vscode settings: vue official  -  by @soybeanjs [<samp>(76649)</samp>](https://github.com/soybeanjs/soybean-admin/commit/76649e2) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/m-xlsea)   | ||||
|  | ||||
| ## [v1.1.4](https://github.com/honghuangdc/soybean-admin/compare/v1.1.3...v1.1.4) (2024-06-06) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **utils**: modalLogout bug when esc is pressed  -  by @sigma-plus in https://github.com/honghuangdc/soybean-admin/issues/470 [<samp>(bd69c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/bd69c00) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: optimize RouteMeta remarks  -  by @soybeanjs [<samp>(ffb48)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ffb48b1) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: | ||||
|   - update CHANGELOG  -  by @soybeanjs [<samp>(756f8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/756f84a) | ||||
|   - update Node&pnpm version  -  by @Azir-11 in https://github.com/honghuangdc/soybean-admin/issues/472 [<samp>(9b05d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9b05d73) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **deps**: | ||||
|   - update deps  -  by @soybeanjs [<samp>(d0380)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d0380ce) | ||||
|   - update deps  -  by @soybeanjs [<samp>(1f464)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1f4647b) | ||||
| - **projects**: | ||||
|   - close http proxy  -  by @soybeanjs [<samp>(d08a3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d08a381) | ||||
|   - update mock url  -  by @soybeanjs [<samp>(e6086)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e6086f0) | ||||
|   - update vscode settings  -  by @soybeanjs [<samp>(910df)</samp>](https://github.com/honghuangdc/soybean-admin/commit/910dfca) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)  [](https://github.com/sigma-plus)   | ||||
|  | ||||
| ## [v1.1.3](https://github.com/soybeanjs/soybean-admin/compare/v1.1.2...v1.1.3) (2024-06-02) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **components**: | ||||
|   - Fix the issue of search box popping up repeatedly due to carriage return  -  by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/468 [<samp>(5bd96)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5bd96b8) | ||||
| - **projects**: | ||||
|   - fix click menu search. fixed #466, close #467  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/466 and https://github.com/soybeanjs/soybean-admin/issues/467 [<samp>(8efdb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8efdb10) | ||||
|   - fix reCacheRoute. fixed #464  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/464 [<samp>(59faf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/59faf15) | ||||
| - **styles**: | ||||
|   - fix FirstLevelMenu style. fixed #450  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/450 [<samp>(db64b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db64b0e) | ||||
|   - fix PinToggler style. fixed #451  -  by @soybeanjs in https://github.com/soybeanjs/soybean-admin/issues/451 [<samp>(42b12)</samp>](https://github.com/soybeanjs/soybean-admin/commit/42b121a) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **components**: accuracy draggable area for TableColumnSetting with animation  -  by @orangelckc in https://github.com/soybeanjs/soybean-admin/issues/465 [<samp>(2aa85)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2aa85c6) | ||||
| - **projects**: unocss border shortcut  -  by @soybeanjs [<samp>(40d0f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/40d0f8a) | ||||
|  | ||||
| ###    📖 Documentation | ||||
|  | ||||
| - **projects**: update CHANGELOG  -  by @soybeanjs [<samp>(87b18)</samp>](https://github.com/soybeanjs/soybean-admin/commit/87b1838) | ||||
|  | ||||
| ###    🏡 Chore | ||||
|  | ||||
| - **other**: | ||||
|   - correct spell mistake  -  by @orangelckc in https://github.com/soybeanjs/soybean-admin/issues/460 [<samp>(086ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/086bad4) | ||||
|   - correct spell mistake  -  by @Azir-11 in https://github.com/soybeanjs/soybean-admin/issues/462 [<samp>(f1850)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f185041) | ||||
| - **projects**: | ||||
|   - update vscode launch.json  -  by @soybeanjs [<samp>(4c1c7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c1c7e6) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)  [](https://github.com/orangelckc)   | ||||
|  | ||||
| ## [v1.1.2](https://github.com/soybeanjs/soybean-admin/compare/v1.1.1...v1.1.2) (2024-05-24) | ||||
|  | ||||
| ###    🐞 Bug Fixes | ||||
|  | ||||
| - **projects**: | ||||
|   - fix header style & fix button highlight when click global-tab. fixed #446  -  by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/446 [<samp>(64fc0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/64fc099) | ||||
|   - fix multi tab page only render once. fixed #441  -  by @honghuangdc in https://github.com/soybeanjs/soybean-admin/issues/441 [<samp>(e379d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e379d6c) | ||||
|  | ||||
| ###    🛠 Optimizations | ||||
|  | ||||
| - **projects**: optimize code  -  by @honghuangdc [<samp>(bc8dc)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bc8dc47) | ||||
|  | ||||
| ###    ❤️ Contributors | ||||
|  | ||||
| [](https://github.com/honghuangdc)   | ||||
|  | ||||
| ## [v1.1.1](https://github.com/soybeanjs/soybean-admin/compare/v1.1.0...v1.1.1) (2024-05-20) | ||||
|  | ||||
| ###    🚀 Features | ||||
|   | ||||
| @@ -1,6 +1,257 @@ | ||||
| # 更新日志 | ||||
|  | ||||
|  | ||||
| ## [v1.2.5](https://github.com/soybeanjs/soybean-admin/compare/v1.2.4...v1.2.5) (2024-06-15) | ||||
|  | ||||
| ###    🐞 错误修复 | ||||
|  | ||||
| - **项目**: 修复登出后标签页异常缓存的问题。已修复 #495  -  由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/495 [<samp>(3eeac)</samp>](https://github.com/soybeanjs/soybean-admin/commit/3eeace9) | ||||
|  | ||||
| ###    🔥 性能 | ||||
|  | ||||
| - **项目**: 初始化静态路由功能不需要异步  -  由 **CHENZL** 在 https://github.com/soybeanjs/soybean-admin/issues/493 [<samp>(2198b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2198b98) | ||||
|  | ||||
| ###    🛠 优化 | ||||
|  | ||||
| - **项目**: 优化代码  -  由 @soybeanjs [<samp>(b94ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b94baa1) | ||||
| - **类型**: 提高全局类型的兼容性  -  由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/494 [<samp>(cd9d5)</samp>](https://github.com/soybeanjs/soybean-admin/commit/cd9d58d) | ||||
| - **工具**: 减少代码缩进,提高可读性  -  由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/496 [<samp>(ad2f2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ad2f247) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: 更新CHANGELOG  -  由 @soybeanjs [<samp>(f70d2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f70d29b) | ||||
|  | ||||
| ###    🏡 杂项 | ||||
|  | ||||
| - **依赖**: 更新依赖  -  由 @soybeanjs [<samp>(b094d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b094d68) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)   | ||||
| [CHENZL](mailto:zlong5568863@qq.com) | ||||
|  | ||||
|  | ||||
| ## [v1.2.4](https://github.com/soybeanjs/soybean-admin/compare/v1.2.3...v1.2.4) (2024-06-14) | ||||
|  | ||||
| ###    🛠 优化 | ||||
|  | ||||
| - **项目**: | ||||
|   - 优化 `setupAppVersionNotification`  -  由 @soybeanjs 提交 [<samp>(b5a72)</samp>](https://github.com/soybeanjs/soybean-admin/commit/b5a723c) | ||||
|   - 获取 'Asia/Shanghai' 时区的构建时间  -  由 @soybeanjs 提交 [<samp>(069fa)</samp>](https://github.com/soybeanjs/soybean-admin/commit/069fa8a) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
| ## [v1.2.3](https://github.com/soybeanjs/soybean-admin/compare/v1.2.2...v1.2.3) (2024-06-13) | ||||
|  | ||||
| ###    🐞 修复错误 | ||||
|  | ||||
| - **项目**: | ||||
|   - 通过在index.html中添加color-scheme元标签修复移动浏览器主题问题  -  由 @KickCashew 在 https://github.com/soybeanjs/soybean-admin/issues/488 中提交 [<samp>(c2125)</samp>](https://github.com/soybeanjs/soybean-admin/commit/c212565) | ||||
|   - 修复二级目录组件为空  -  由 @paynezhuang 在 https://github.com/soybeanjs/soybean-admin/issues/491 中提交 [<samp>(aabb2)</samp>](https://github.com/soybeanjs/soybean-admin/commit/aabb2a4) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: | ||||
|   - 修复超链接指向错误  -  由 **Azir** 提交 [<samp>(20a81)</samp>](https://github.com/soybeanjs/soybean-admin/commit/20a8127) | ||||
|   - 更新 README  -  由 @soybeanjs 提交 [<samp>(70261)</samp>](https://github.com/soybeanjs/soybean-admin/commit/7026126) | ||||
|  | ||||
| ###    🏡 杂项 | ||||
|  | ||||
| - **依赖**: | ||||
|   - 更新依赖  -  由 @soybeanjs 提交 [<samp>(813d8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/813d8ce) | ||||
|   - 更新依赖  -  由 @soybeanjs 提交 [<samp>(bf718)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bf71837) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/paynezhuang)  [](https://github.com/KickCashew)   | ||||
| [Azir](mailto:2075125282@qq.com) | ||||
|  | ||||
| ## [v1.2.2](https://github.com/honghuangdc/soybean-admin/compare/v1.2.1...v1.2.2) (2024-06-12) | ||||
|  | ||||
| ###    🚀 特性 | ||||
|  | ||||
| - **项目**: 切换标签时重置滚动位置  -  由 @soybeanjs 提交 [<samp>(9094b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9094b21) | ||||
|  | ||||
| ###    🐞 修复错误 | ||||
|  | ||||
| - **项目**: | ||||
|   - 在DEV模式下隐藏AppVersionNotification  -  由 @sigma-plus 在 https://github.com/honghuangdc/soybean-admin/issues/482 中提交 [<samp>(62592)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6259287) | ||||
|   - 修复在移动布局中隐藏menu-toggler。fixed #483  -  由 @soybeanjs 在 https://github.com/honghuangdc/soybean-admin/issues/483 中提交 [<samp>(4470c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/4470cb4) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: 更新 README  -  由 @soybeanjs 提交 [<samp>(8f9a7)</samp>](https://github.com/honghuangdc/soybean-admin/commit/8f9a705) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/sigma-plus)   | ||||
|  | ||||
| ## [v1.2.1](https://github.com/honghuangdc/soybean-admin/compare/v1.2.0...v1.2.1) (2024-06-07) | ||||
|  | ||||
| ###    🐞 修复错误 | ||||
|  | ||||
| - **项目**: | ||||
|   - 修复页面重新加载时获取用户信息  -  由 @soybeanjs 提交 [<samp>(ff51b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ff51b72) | ||||
|   - 修复setupAppVersionNotification渲染  -  由 @soybeanjs 提交 [<samp>(6a6eb)</samp>](https://github.com/honghuangdc/soybean-admin/commit/6a6eb9a) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: 更新CHANGELOG  -  由 @soybeanjs [<samp>(fe06b)</samp>](https://github.com/honghuangdc/soybean-admin/commit/fe06b8c)完成 | ||||
|  | ||||
| ###    🏡 日常任务 | ||||
|  | ||||
| - **依赖**: 更新依赖  -  由 @soybeanjs [<samp>(08827)</samp>](https://github.com/honghuangdc/soybean-admin/commit/08827a4)完成 | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
|  | ||||
| ## [v1.2.0](https://github.com/soybeanjs/soybean-admin/compare/v1.1.5...v1.2.0) (2024-06-06) | ||||
|  | ||||
| ###    🚀 功能 | ||||
|  | ||||
| - **项目**: | ||||
|   - 支持系统新版本更新通知。关闭 #420  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/420 [<samp>(584cd)</samp>](https://github.com/soybeanjs/soybean-admin/commit/584cd54) | ||||
|   - 在路由守卫中获取用户信息并从localStorage中移除。关闭 #459  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/459 [<samp>(5531a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5531a68) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: 更新CHANGELOG  -  由 @soybeanjs [<samp>(2bec8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2bec899) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)   | ||||
|  | ||||
| ## [v1.1.5](https://github.com/soybeanjs/soybean-admin/compare/v1.1.4...v1.1.5) (2024-06-06) | ||||
|  | ||||
| ###    🐞 错误修复 | ||||
|  | ||||
| - **项目**: 修复注册组件名,CodeLogin => Register  -  由 @m-xlsea 在 https://github.com/soybeanjs/soybean-admin/issues/478 [<samp>(ddf38)</samp>](https://github.com/soybeanjs/soybean-admin/commit/ddf3823) | ||||
|  | ||||
| ###    🏡 杂务 | ||||
|  | ||||
| - **依赖**: 更新依赖  -  由 @soybeanjs [<samp>(060c0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/060c0a9) | ||||
| - **项目**: 更新 vscode 设置: vue 官方  -  由 @soybeanjs [<samp>(76649)</samp>](https://github.com/soybeanjs/soybean-admin/commit/76649e2) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/m-xlsea)   | ||||
|  | ||||
| ## [v1.1.4](https://github.com/honghuangdc/soybean-admin/compare/v1.1.3...v1.1.4) (2024-06-06) | ||||
|  | ||||
| ###    🐞 错误修复 | ||||
|  | ||||
| - **utils**: 修复了按esc键时modalLogout的错误  -  由 @sigma-plus 在 https://github.com/honghuangdc/soybean-admin/issues/470 中提出 [<samp>(bd69c)</samp>](https://github.com/honghuangdc/soybean-admin/commit/bd69c00) | ||||
|  | ||||
| ###    🛠 优化 | ||||
|  | ||||
| - **projects**: 优化了RouteMeta的备注  -  由 @soybeanjs 提出 [<samp>(ffb48)</samp>](https://github.com/honghuangdc/soybean-admin/commit/ffb48b1) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **projects**: | ||||
|   - 更新了CHANGELOG  -  由 @soybeanjs 提出 [<samp>(756f8)</samp>](https://github.com/honghuangdc/soybean-admin/commit/756f84a) | ||||
|   - 更新了Node&pnpm版本  -  由 @Azir-11 在 https://github.com/honghuangdc/soybean-admin/issues/472 中提出 [<samp>(9b05d)</samp>](https://github.com/honghuangdc/soybean-admin/commit/9b05d73) | ||||
|  | ||||
| ###    🏡 杂项 | ||||
|  | ||||
| - **deps**: | ||||
|   - 更新了依赖  -  由 @soybeanjs 提出 [<samp>(d0380)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d0380ce) | ||||
|   - 更新了依赖  -  由 @soybeanjs 提出 [<samp>(1f464)</samp>](https://github.com/honghuangdc/soybean-admin/commit/1f4647b) | ||||
| - **projects**: | ||||
|   - 关闭了http代理  -  由 @soybeanjs 提出 [<samp>(d08a3)</samp>](https://github.com/honghuangdc/soybean-admin/commit/d08a381) | ||||
|   - 更新了mock url  -  由 @soybeanjs 提出 [<samp>(e6086)</samp>](https://github.com/honghuangdc/soybean-admin/commit/e6086f0) | ||||
|   - 更新了vscode设置  -  由 @soybeanjs 提出 [<samp>(910df)</samp>](https://github.com/honghuangdc/soybean-admin/commit/910dfca) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)  [](https://github.com/sigma-plus)   | ||||
|  | ||||
| ## [v1.1.3](https://github.com/soybeanjs/soybean-admin/compare/v1.1.2...v1.1.3) (2024-06-02) | ||||
|  | ||||
| ###    🐞 错误修复 | ||||
|  | ||||
| - **组件**: | ||||
|   - 修复了由于回车导致搜索框反复弹出的问题  -  由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/468 中修复 [<samp>(5bd96)</samp>](https://github.com/soybeanjs/soybean-admin/commit/5bd96b8) | ||||
| - **项目**: | ||||
|   - 修复点击菜单搜索。修复了 #466,关闭 #467  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/466 和 https://github.com/soybeanjs/soybean-admin/issues/467 中修复 [<samp>(8efdb)</samp>](https://github.com/soybeanjs/soybean-admin/commit/8efdb10) | ||||
|   - 修复 reCacheRoute。修复了 #464  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/464 中修复 [<samp>(59faf)</samp>](https://github.com/soybeanjs/soybean-admin/commit/59faf15) | ||||
| - **样式**: | ||||
|   - 修复 FirstLevelMenu 样式。修复了 #450  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/450 中修复 [<samp>(db64b)</samp>](https://github.com/soybeanjs/soybean-admin/commit/db64b0e) | ||||
|   - 修复 PinToggler 样式。修复了 #451  -  由 @soybeanjs 在 https://github.com/soybeanjs/soybean-admin/issues/451 中修复 [<samp>(42b12)</samp>](https://github.com/soybeanjs/soybean-admin/commit/42b121a) | ||||
|  | ||||
| ###    🛠 优化 | ||||
|  | ||||
| - **组件**: 提高 TableColumnSetting 的拖动区域精度,带有动画  -  由 @orangelckc 在 https://github.com/soybeanjs/soybean-admin/issues/465 中优化 [<samp>(2aa85)</samp>](https://github.com/soybeanjs/soybean-admin/commit/2aa85c6) | ||||
| - **项目**: unocss 边框快捷方式  -  由 @soybeanjs 优化 [<samp>(40d0f)</samp>](https://github.com/soybeanjs/soybean-admin/commit/40d0f8a) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **项目**: 更新 CHANGELOG  -  由 @soybeanjs 更新 [<samp>(87b18)</samp>](https://github.com/soybeanjs/soybean-admin/commit/87b1838) | ||||
|  | ||||
| ###    🏡 杂项 | ||||
|  | ||||
| - **其他**: | ||||
|   - 纠正拼写错误  -  由 @orangelckc 在 https://github.com/soybeanjs/soybean-admin/issues/460 中纠正 [<samp>(086ba)</samp>](https://github.com/soybeanjs/soybean-admin/commit/086bad4) | ||||
|   - 纠正拼写错误  -  由 @Azir-11 在 https://github.com/soybeanjs/soybean-admin/issues/462 中纠正 [<samp>(f1850)</samp>](https://github.com/soybeanjs/soybean-admin/commit/f185041) | ||||
| - **项目**: | ||||
|   - 更新 vscode launch.json  -  由 @soybeanjs 更新 [<samp>(4c1c7)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4c1c7e6) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/soybeanjs)  [](https://github.com/Azir-11)  [](https://github.com/orangelckc)   | ||||
|  | ||||
| ## [v1.1.2](https://github.com/soybeanjs/soybean-admin/compare/v1.1.1...v1.1.2) (2024-05-24) | ||||
|  | ||||
| ###    🐞 错误修复 | ||||
|  | ||||
| - **项目**: | ||||
|   - 修复头部样式 & 修复点击全局标签时按钮高亮。修复了 #446  -  由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/446 [<samp>(64fc0)</samp>](https://github.com/soybeanjs/soybean-admin/commit/64fc099) | ||||
|   - 修复多标签页只渲染一次。修复了 #441  -  由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/441 [<samp>(e379d)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e379d6c) | ||||
|  | ||||
| ###    🛠 优化 | ||||
|  | ||||
| - **项目**: 优化代码  -  由 @honghuangdc [<samp>(bc8dc)</samp>](https://github.com/soybeanjs/soybean-admin/commit/bc8dc47) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/honghuangdc)   | ||||
|  | ||||
| ## [v1.1.1](https://github.com/soybeanjs/soybean-admin/compare/v1.1.0...v1.1.1) (2024-05-20) | ||||
|  | ||||
| ###    🚀 功能 | ||||
|  | ||||
| - **hooks**: 为 useEcharts 添加 setOptions  -  由 @honghuangdc 提交 [<samp>(e4d53)</samp>](https://github.com/soybeanjs/soybean-admin/commit/e4d53aa) | ||||
|  | ||||
| ###    🐞 修复错误 | ||||
|  | ||||
| - **projects**: | ||||
|   - 修复 useRouter。修复了 #436  -  由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/436 提交 [<samp>(0774a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/0774a51) | ||||
|   - 在动态路由模式下获取路由时添加错误处理。修复了 440  -  由 @honghuangdc 提交 [<samp>(57b4a)</samp>](https://github.com/soybeanjs/soybean-admin/commit/57b4a9d) | ||||
| - **styles**: | ||||
|   - 修复 useTable 类型  -  由 @honghuangdc 提交 [<samp>(07124)</samp>](https://github.com/soybeanjs/soybean-admin/commit/071241f) | ||||
|  | ||||
| ###    📖 文档 | ||||
|  | ||||
| - **projects**: | ||||
|   - 更新 CHANGELOG  -  由 @honghuangdc 提交 [<samp>(19783)</samp>](https://github.com/soybeanjs/soybean-admin/commit/1978397) | ||||
|   - 更新 README.md  -  由 @honghuangdc 提交 [<samp>(fa56e)</samp>](https://github.com/soybeanjs/soybean-admin/commit/fa56e9c) | ||||
|   - 更新 README.md  -  由 @honghuangdc 提交 [<samp>(419ea)</samp>](https://github.com/soybeanjs/soybean-admin/commit/419ea42) | ||||
|  | ||||
| ###    🏡 杂项 | ||||
|  | ||||
| - **projects**: | ||||
|   - 更新依赖并修复 TS 错误  -  由 @honghuangdc 提交 [<samp>(4ea9c)</samp>](https://github.com/soybeanjs/soybean-admin/commit/4ea9c85) | ||||
|   - 更新 eslint-config 并修复代码  -  由 @honghuangdc 提交 [<samp>(68ea9)</samp>](https://github.com/soybeanjs/soybean-admin/commit/68ea974) | ||||
|   - 更新 @elegant-router/vue 并为 resolve route 添加错误处理。修复了 #442  -  由 @honghuangdc 在 https://github.com/soybeanjs/soybean-admin/issues/442 提交 [<samp>(24ff8)</samp>](https://github.com/soybeanjs/soybean-admin/commit/24ff852) | ||||
|  | ||||
| ###    ❤️ 贡献者 | ||||
|  | ||||
| [](https://github.com/honghuangdc)   | ||||
|  | ||||
| ## [v1.1.0](https://github.com/honghuangdc/soybean-admin/compare/v1.0.9...v1.1.0) (2024-05-07) | ||||
|  | ||||
| ###    🚀 功能 | ||||
|   | ||||
| @@ -11,6 +11,9 @@ | ||||
| [](https://github.com/soybeanjs/soybean-admin) | ||||
| [](https://gitee.com/honghuangdc/soybean-admin) | ||||
|  | ||||
| <a href="https://hellogithub.com/repository/1298f27d5fe54959a16cf9686516ddb3" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=1298f27d5fe54959a16cf9686516ddb3&claim_uid=IiDXWmP4TEntjbV" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a> | ||||
|  | ||||
|  | ||||
| > [!NOTE] | ||||
| > If you think `SoybeanAdmin` is helpful to you, or you like our project, please give us a ⭐️ on GitHub. Your support is the driving force for us to continue to improve and add new features! Thank you for your support! | ||||
|  | ||||
| @@ -78,8 +81,8 @@ | ||||
| Make sure your environment meets the following requirements: | ||||
|  | ||||
| - **git**: you need git to clone and manage project versions. | ||||
| - **NodeJS**: >=18.0.0, recommended 18.19.0 or higher. | ||||
| - **pnpm**: >= 8.0.0, recommended 8.14.0 or higher. | ||||
| - **NodeJS**: >=18.12.0, recommended 18.19.0 or higher. | ||||
| - **pnpm**: >= 8.7.0, recommended 8.14.0 or higher. | ||||
|  | ||||
| **Clone Project** | ||||
|  | ||||
| @@ -156,7 +159,7 @@ Thanks the following people for their contributions. If you want to contribute t | ||||
|   </div> | ||||
| 	<!-- <div> | ||||
| 		<p>WeChat Group</p> | ||||
| 		<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-0402.jpg" style="width:200px" /> | ||||
| 		<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/picgo/soybean-admin-wechat-0620.jpg" style="width:200px" /> | ||||
| 	</div> --> | ||||
| 	<div> | ||||
| 		<p>Add the following WeChat to invite to the WeChat group</p> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <div align="center"> | ||||
| 	<img src="./public/favicon.svg" width="160" /> | ||||
| 	<h1>SoybeanAdmin</h1> | ||||
|   <span><a href="./README.zh_CN.md">English</a> | 中文</span> | ||||
|   <span><a href="./README.md">English</a> | 中文</span> | ||||
| </div> | ||||
|  | ||||
| --- | ||||
| @@ -11,6 +11,8 @@ | ||||
| [](https://github.com/soybeanjs/soybean-admin) | ||||
| [](https://gitee.com/honghuangdc/soybean-admin) | ||||
|  | ||||
| <a href="https://hellogithub.com/repository/1298f27d5fe54959a16cf9686516ddb3" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=1298f27d5fe54959a16cf9686516ddb3&claim_uid=IiDXWmP4TEntjbV" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a> | ||||
|  | ||||
| > [!NOTE] | ||||
| > 如果您觉得 `SoybeanAdmin`对您有所帮助,或者您喜欢我们的项目,请在 GitHub 上给我们一个 ⭐️。您的支持是我们持续改进和增加新功能的动力!感谢您的支持! | ||||
|  | ||||
| @@ -77,8 +79,8 @@ | ||||
| 确保你的环境满足以下要求: | ||||
|  | ||||
| - **git**: 你需要git来克隆和管理项目版本。 | ||||
| - **NodeJS**: >=18.0.0,推荐 18.19.0 或更高。 | ||||
| - **pnpm**: >= 8.0.0,推荐 8.14.0 或更高。 | ||||
| - **NodeJS**: >=18.12.0,推荐 18.19.0 或更高。 | ||||
| - **pnpm**: >= 8.7.0,推荐 8.14.0 或更高。 | ||||
|  | ||||
| **克隆项目** | ||||
|  | ||||
| @@ -157,7 +159,7 @@ pnpm build | ||||
|   </div> | ||||
| 	<!-- <div> | ||||
| 		<p>微信群</p> | ||||
| 		<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/uPic/wechat-0402.jpg" style="width:200px" /> | ||||
| 		<img src="https://soybeanjs-1300612522.cos.ap-guangzhou.myqcloud.com/picgo/soybean-admin-wechat-0620.jpg" style="width:200px" /> | ||||
| 	</div> --> | ||||
| 	<div> | ||||
| 		<p>添加下面微信邀请进微信群</p> | ||||
|   | ||||
| @@ -1 +1,2 @@ | ||||
| export * from './proxy'; | ||||
| export * from './time'; | ||||
|   | ||||
							
								
								
									
										12
									
								
								build/config/time.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								build/config/time.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| import dayjs from 'dayjs'; | ||||
| import utc from 'dayjs/plugin/utc'; | ||||
| import timezone from 'dayjs/plugin/timezone'; | ||||
|  | ||||
| export function getBuildTime() { | ||||
|   dayjs.extend(utc); | ||||
|   dayjs.extend(timezone); | ||||
|  | ||||
|   const buildTime = dayjs.tz(Date.now(), 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss'); | ||||
|  | ||||
|   return buildTime; | ||||
| } | ||||
							
								
								
									
										13
									
								
								build/plugins/html.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								build/plugins/html.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| import type { Plugin } from 'vite'; | ||||
|  | ||||
| export function setupHtmlPlugin(buildTime: string) { | ||||
|   const plugin: Plugin = { | ||||
|     name: 'html-plugin', | ||||
|     apply: 'build', | ||||
|     transformIndexHtml(html) { | ||||
|       return html.replace('<head>', `<head>\n    <meta name="buildTime" content="${buildTime}">`); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   return plugin; | ||||
| } | ||||
| @@ -6,8 +6,9 @@ import progress from 'vite-plugin-progress'; | ||||
| import { setupElegantRouter } from './router'; | ||||
| import { setupUnocss } from './unocss'; | ||||
| import { setupUnplugin } from './unplugin'; | ||||
| import { setupHtmlPlugin } from './html'; | ||||
|  | ||||
| export function setupVitePlugins(viteEnv: Env.ImportMeta) { | ||||
| export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) { | ||||
|   const plugins: PluginOption = [ | ||||
|     vue({ | ||||
|       script: { | ||||
| @@ -19,7 +20,8 @@ export function setupVitePlugins(viteEnv: Env.ImportMeta) { | ||||
|     setupElegantRouter(), | ||||
|     setupUnocss(viteEnv), | ||||
|     ...setupUnplugin(viteEnv), | ||||
|     progress() | ||||
|     progress(), | ||||
|     setupHtmlPlugin(buildTime) | ||||
|   ]; | ||||
|  | ||||
|   return plugins; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ export default defineConfig( | ||||
|       'vue/multi-word-component-names': [ | ||||
|         'warn', | ||||
|         { | ||||
|           ignores: ['index', 'App', '[id]', '[url]'] | ||||
|           ignores: ['index', 'App', 'Register', '[id]', '[url]'] | ||||
|         } | ||||
|       ], | ||||
|       'vue/component-name-in-template-casing': [ | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|     <meta charset="UTF-8" /> | ||||
|     <link rel="icon" href="/favicon.svg" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <meta name="color-scheme" content="light dark" /> | ||||
|     <title>%VITE_APP_TITLE%</title> | ||||
|   </head> | ||||
|   <body> | ||||
|   | ||||
							
								
								
									
										57
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|   "name": "soybean-admin", | ||||
|   "type": "module", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "description": "A fresh and elegant admin template, based on Vue3、Vite3、TypeScript、NaiveUI and UnoCSS. 一个基于Vue3、Vite3、TypeScript、NaiveUI and UnoCSS的清新优雅的中后台模版。", | ||||
|   "author": { | ||||
|     "name": "Soybean", | ||||
| @@ -53,51 +53,52 @@ | ||||
|     "@sa/hooks": "workspace:*", | ||||
|     "@sa/materials": "workspace:*", | ||||
|     "@sa/utils": "workspace:*", | ||||
|     "@vueuse/core": "10.9.0", | ||||
|     "@vueuse/core": "10.11.0", | ||||
|     "clipboard": "2.0.11", | ||||
|     "dayjs": "1.11.11", | ||||
|     "echarts": "5.5.0", | ||||
|     "echarts": "5.5.1", | ||||
|     "lodash-es": "4.17.21", | ||||
|     "naive-ui": "2.38.2", | ||||
|     "nprogress": "0.2.0", | ||||
|     "pinia": "2.1.7", | ||||
|     "vue": "3.4.27", | ||||
|     "vue-draggable-plus": "0.4.1", | ||||
|     "tailwind-merge": "2.4.0", | ||||
|     "vue": "3.4.31", | ||||
|     "vue-draggable-plus": "0.5.2", | ||||
|     "vue-i18n": "9.13.1", | ||||
|     "vue-router": "4.3.2" | ||||
|     "vue-router": "4.4.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@elegant-router/vue": "0.3.7", | ||||
|     "@iconify/json": "2.2.211", | ||||
|     "@iconify/json": "2.2.226", | ||||
|     "@sa/scripts": "workspace:*", | ||||
|     "@sa/uno-preset": "workspace:*", | ||||
|     "@soybeanjs/eslint-config": "1.3.5", | ||||
|     "@soybeanjs/eslint-config": "1.3.7", | ||||
|     "@types/lodash-es": "4.17.12", | ||||
|     "@types/node": "20.12.12", | ||||
|     "@types/node": "20.14.10", | ||||
|     "@types/nprogress": "0.2.3", | ||||
|     "@unocss/eslint-config": "0.60.2", | ||||
|     "@unocss/preset-icons": "0.60.2", | ||||
|     "@unocss/preset-uno": "0.60.2", | ||||
|     "@unocss/transformer-directives": "0.60.2", | ||||
|     "@unocss/transformer-variant-group": "0.60.2", | ||||
|     "@unocss/vite": "0.60.2", | ||||
|     "@vitejs/plugin-vue": "5.0.4", | ||||
|     "@vitejs/plugin-vue-jsx": "3.1.0", | ||||
|     "eslint": "9.3.0", | ||||
|     "eslint-plugin-vue": "9.26.0", | ||||
|     "lint-staged": "15.2.2", | ||||
|     "sass": "1.77.2", | ||||
|     "@unocss/eslint-config": "0.61.3", | ||||
|     "@unocss/preset-icons": "0.61.3", | ||||
|     "@unocss/preset-uno": "0.61.3", | ||||
|     "@unocss/transformer-directives": "0.61.3", | ||||
|     "@unocss/transformer-variant-group": "0.61.3", | ||||
|     "@unocss/vite": "0.61.3", | ||||
|     "@vitejs/plugin-vue": "5.0.5", | ||||
|     "@vitejs/plugin-vue-jsx": "4.0.0", | ||||
|     "eslint": "9.6.0", | ||||
|     "eslint-plugin-vue": "9.27.0", | ||||
|     "lint-staged": "15.2.7", | ||||
|     "sass": "1.77.7", | ||||
|     "simple-git-hooks": "2.11.1", | ||||
|     "tsx": "4.10.5", | ||||
|     "typescript": "5.4.5", | ||||
|     "tsx": "4.16.2", | ||||
|     "typescript": "5.5.3", | ||||
|     "unplugin-icons": "0.19.0", | ||||
|     "unplugin-vue-components": "0.27.0", | ||||
|     "vite": "5.2.11", | ||||
|     "unplugin-vue-components": "0.27.2", | ||||
|     "vite": "5.3.3", | ||||
|     "vite-plugin-progress": "0.0.7", | ||||
|     "vite-plugin-svg-icons": "2.0.1", | ||||
|     "vite-plugin-vue-devtools": "7.2.0", | ||||
|     "vue-eslint-parser": "9.4.2", | ||||
|     "vue-tsc": "2.0.19" | ||||
|     "vite-plugin-vue-devtools": "7.3.5", | ||||
|     "vue-eslint-parser": "9.4.3", | ||||
|     "vue-tsc": "2.0.26" | ||||
|   }, | ||||
|   "simple-git-hooks": { | ||||
|     "commit-msg": "pnpm sa git-commit-verify", | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/axios", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
| @@ -11,9 +11,9 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@sa/utils": "workspace:*", | ||||
|     "axios": "1.6.8", | ||||
|     "axios-retry": "4.2.0", | ||||
|     "qs": "6.12.1" | ||||
|     "axios": "1.7.2", | ||||
|     "axios-retry": "4.4.1", | ||||
|     "qs": "6.12.3" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/qs": "6.9.15" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/color", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/hooks", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/materials", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
| @@ -11,7 +11,7 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@sa/utils": "workspace:*", | ||||
|     "simplebar-vue": "2.3.4" | ||||
|     "simplebar-vue": "2.3.5" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "typed-css-modules": "0.9.1" | ||||
|   | ||||
| @@ -36,7 +36,7 @@ defineSlots<Slots>(); | ||||
|  | ||||
| <template> | ||||
|   <div | ||||
|     class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-12px whitespace-nowrap border-1px rounded-4px border-solid px-12px py-4px" | ||||
|     class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-12px whitespace-nowrap border-(1px solid) rounded-4px px-12px py-4px" | ||||
|     :class="[ | ||||
|       style['button-tab'], | ||||
|       { [style['button-tab_dark']]: darkMode }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/fetch", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/scripts", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "bin": { | ||||
|     "sa": "./bin.ts" | ||||
|   }, | ||||
| @@ -13,15 +13,15 @@ | ||||
|     } | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@soybeanjs/changelog": "0.3.23", | ||||
|     "@soybeanjs/changelog": "0.3.24", | ||||
|     "bumpp": "9.4.1", | ||||
|     "c12": "1.10.0", | ||||
|     "c12": "1.11.1", | ||||
|     "cac": "6.7.14", | ||||
|     "consola": "3.2.3", | ||||
|     "enquirer": "2.4.1", | ||||
|     "execa": "9.1.0", | ||||
|     "execa": "9.3.0", | ||||
|     "kolorist": "1.8.0", | ||||
|     "npm-check-updates": "16.14.20", | ||||
|     "rimraf": "5.0.7" | ||||
|     "rimraf": "6.0.1" | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/uno-preset", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "@sa/utils", | ||||
|   "version": "1.1.1", | ||||
|   "version": "1.2.7", | ||||
|   "exports": { | ||||
|     ".": "./src/index.ts" | ||||
|   }, | ||||
|   | ||||
							
								
								
									
										3076
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3076
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,10 +21,10 @@ const columns = defineModel<NaiveUI.TableColumnCheck[]>('columns', { | ||||
|         {{ $t('common.columnSetting') }} | ||||
|       </NButton> | ||||
|     </template> | ||||
|     <VueDraggable v-model="columns"> | ||||
|     <VueDraggable v-model="columns" :animation="150" filter=".none_draggable"> | ||||
|       <div v-for="item in columns" :key="item.key" class="h-36px flex-y-center rd-4px hover:(bg-primary bg-opacity-20)"> | ||||
|         <icon-mdi-drag class="mr-8px cursor-move text-icon" /> | ||||
|         <NCheckbox v-model:checked="item.checked"> | ||||
|         <icon-mdi-drag class="mr-8px h-full cursor-move text-icon" /> | ||||
|         <NCheckbox v-model:checked="item.checked" class="none_draggable flex-1"> | ||||
|           {{ item.title }} | ||||
|         </NCheckbox> | ||||
|       </div> | ||||
|   | ||||
| @@ -41,6 +41,7 @@ const icon = computed(() => { | ||||
|  | ||||
| <template> | ||||
|   <ButtonIcon | ||||
|     :key="String(collapsed)" | ||||
|     :tooltip-content="collapsed ? $t('icon.expand') : $t('icon.collapse')" | ||||
|     tooltip-placement="bottom-start" | ||||
|     :z-index="zIndex" | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| <script setup lang="ts"> | ||||
| import { computed } from 'vue'; | ||||
| import { createReusableTemplate } from '@vueuse/core'; | ||||
| import type { PopoverPlacement } from 'naive-ui'; | ||||
| import { twMerge } from 'tailwind-merge'; | ||||
|  | ||||
| defineOptions({ | ||||
|   name: 'ButtonIcon', | ||||
| @@ -21,60 +20,29 @@ interface Props { | ||||
| } | ||||
|  | ||||
| const props = withDefaults(defineProps<Props>(), { | ||||
|   class: 'h-36px text-icon', | ||||
|   class: '', | ||||
|   icon: '', | ||||
|   tooltipContent: '', | ||||
|   tooltipPlacement: 'bottom', | ||||
|   zIndex: 98 | ||||
| }); | ||||
|  | ||||
| interface ButtonProps { | ||||
|   className: string; | ||||
| } | ||||
|  | ||||
| const [DefineButton, Button] = createReusableTemplate<ButtonProps>(); | ||||
|  | ||||
| const cls = computed(() => { | ||||
|   let clsStr = props.class; | ||||
|  | ||||
|   if (!clsStr.includes('h-')) { | ||||
|     clsStr += ' h-36px'; | ||||
|   } | ||||
|  | ||||
|   if (!clsStr.includes('text-')) { | ||||
|     clsStr += ' text-icon'; | ||||
|   } | ||||
|  | ||||
|   return clsStr; | ||||
| }); | ||||
| const DEFAULT_CLASS = 'h-[36px] text-icon'; | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <!-- define component start: Button --> | ||||
|   <DefineButton v-slot="{ $slots, className }"> | ||||
|     <NButton quaternary :class="className"> | ||||
|       <div class="flex-center gap-8px"> | ||||
|         <component :is="$slots.default" /> | ||||
|       </div> | ||||
|     </NButton> | ||||
|   </DefineButton> | ||||
|   <!-- define component end: Button --> | ||||
|  | ||||
|   <NTooltip v-if="tooltipContent" :placement="tooltipPlacement" :z-index="zIndex"> | ||||
|   <NTooltip :placement="tooltipPlacement" :z-index="zIndex" :disabled="!tooltipContent"> | ||||
|     <template #trigger> | ||||
|       <Button :class-name="cls" v-bind="$attrs"> | ||||
|         <slot> | ||||
|           <SvgIcon :icon="icon" /> | ||||
|         </slot> | ||||
|       </Button> | ||||
|       <NButton quaternary :class="twMerge(DEFAULT_CLASS, props.class)" v-bind="$attrs"> | ||||
|         <div class="flex-center gap-8px"> | ||||
|           <slot> | ||||
|             <SvgIcon :icon="icon" /> | ||||
|           </slot> | ||||
|         </div> | ||||
|       </NButton> | ||||
|     </template> | ||||
|     {{ tooltipContent }} | ||||
|   </NTooltip> | ||||
|   <Button v-else :class-name="cls" v-bind="$attrs"> | ||||
|     <slot> | ||||
|       <SvgIcon :icon="icon" /> | ||||
|     </slot> | ||||
|   </Button> | ||||
| </template> | ||||
|  | ||||
| <style scoped></style> | ||||
|   | ||||
| @@ -160,6 +160,24 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl | ||||
|     Object.assign(pagination, update); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * get data by page number | ||||
|    * | ||||
|    * @param pageNum the page number. default is 1 | ||||
|    */ | ||||
|   async function getDataByPage(pageNum: number = 1) { | ||||
|     updatePagination({ | ||||
|       page: pageNum | ||||
|     }); | ||||
|  | ||||
|     updateSearchParams({ | ||||
|       current: pageNum, | ||||
|       size: pagination.pageSize! | ||||
|     }); | ||||
|  | ||||
|     await getData(); | ||||
|   } | ||||
|  | ||||
|   scope.run(() => { | ||||
|     watch( | ||||
|       () => appStore.locale, | ||||
| @@ -184,6 +202,7 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl | ||||
|     mobilePagination, | ||||
|     updatePagination, | ||||
|     getData, | ||||
|     getDataByPage, | ||||
|     searchParams, | ||||
|     updateSearchParams, | ||||
|     resetSearchParams | ||||
|   | ||||
| @@ -1,8 +1,10 @@ | ||||
| <script setup lang="ts"> | ||||
| import { computed } from 'vue'; | ||||
| import { LAYOUT_SCROLL_EL_ID } from '@sa/materials'; | ||||
| import { useAppStore } from '@/store/modules/app'; | ||||
| import { useThemeStore } from '@/store/modules/theme'; | ||||
| import { useRouteStore } from '@/store/modules/route'; | ||||
| import { useTabStore } from '@/store/modules/tab'; | ||||
|  | ||||
| defineOptions({ | ||||
|   name: 'GlobalContent' | ||||
| @@ -20,8 +22,15 @@ withDefaults(defineProps<Props>(), { | ||||
| const appStore = useAppStore(); | ||||
| const themeStore = useThemeStore(); | ||||
| const routeStore = useRouteStore(); | ||||
| const tabStore = useTabStore(); | ||||
|  | ||||
| const transitionName = computed(() => (themeStore.page.animate ? themeStore.page.animateMode : '')); | ||||
|  | ||||
| function resetScroll() { | ||||
|   const el = document.querySelector(`#${LAYOUT_SCROLL_EL_ID}`); | ||||
|  | ||||
|   el?.scrollTo({ left: 0, top: 0 }); | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
| @@ -30,13 +39,14 @@ const transitionName = computed(() => (themeStore.page.animate ? themeStore.page | ||||
|       :name="transitionName" | ||||
|       mode="out-in" | ||||
|       @before-leave="appStore.setContentXScrollable(true)" | ||||
|       @after-leave="resetScroll" | ||||
|       @after-enter="appStore.setContentXScrollable(false)" | ||||
|     > | ||||
|       <KeepAlive :include="routeStore.cacheRoutes"> | ||||
|         <component | ||||
|           :is="Component" | ||||
|           v-if="appStore.reloadFlag" | ||||
|           :key="route.path" | ||||
|           :key="tabStore.getTabIdByRoute(route)" | ||||
|           :class="{ 'p-16px': showPadding }" | ||||
|           class="flex-grow bg-layout transition-300" | ||||
|         /> | ||||
|   | ||||
| @@ -47,7 +47,7 @@ const headerMenus = computed(() => { | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <DarkModeContainer class="h-full flex-y-center shadow-header"> | ||||
|   <DarkModeContainer class="h-full flex-y-center px-12px shadow-header"> | ||||
|     <GlobalLogo v-if="showLogo" class="h-full" :style="{ width: themeStore.sider.width + 'px' }" /> | ||||
|     <HorizontalMenu v-if="showMenu" mode="horizontal" :menus="headerMenus" class="px-12px" /> | ||||
|     <div v-else class="h-full flex-y-center flex-1-hidden"> | ||||
|   | ||||
| @@ -68,7 +68,7 @@ function handleClickMixMenu(menu: App.Global.Menu) { | ||||
|       <component :is="icon" :class="[isMini ? 'text-icon-small' : 'text-icon-large']" /> | ||||
|       <p | ||||
|         class="w-full ellipsis-text text-center text-12px transition-height-300" | ||||
|         :class="[isMini ? 'h-0 pt-0' : 'h-24px pt-4px']" | ||||
|         :class="[isMini ? 'h-0 pt-0' : 'h-20px pt-4px']" | ||||
|       > | ||||
|         {{ label }} | ||||
|       </p> | ||||
|   | ||||
| @@ -55,8 +55,8 @@ function handleResetActiveMenu() { | ||||
|         :inverted="siderInverted" | ||||
|         :style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }" | ||||
|       > | ||||
|         <header class="flex-y-center justify-between" :style="{ height: themeStore.header.height + 'px' }"> | ||||
|           <h2 class="pl-8px text-16px text-primary font-bold">{{ $t('system.title') }}</h2> | ||||
|         <header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }"> | ||||
|           <h2 class="text-16px text-primary font-bold">{{ $t('system.title') }}</h2> | ||||
|           <PinToggler | ||||
|             :pin="appStore.mixSiderFixed" | ||||
|             :class="{ 'text-white:88 !hover:text-white': siderInverted }" | ||||
|   | ||||
| @@ -34,9 +34,9 @@ function search() { | ||||
| } | ||||
|  | ||||
| function handleClose() { | ||||
|   visible.value = false; | ||||
|   // handle with setTimeout to prevent user from seeing some operations | ||||
|   setTimeout(() => { | ||||
|     visible.value = false; | ||||
|     resultOptions.value = []; | ||||
|     keyword.value = ''; | ||||
|   }, 200); | ||||
| @@ -112,7 +112,7 @@ registerShortcut(); | ||||
|  | ||||
|     <div class="mt-20px"> | ||||
|       <NEmpty v-if="resultOptions.length === 0" :description="$t('common.noData')" /> | ||||
|       <SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter.prevent="handleEnter" /> | ||||
|       <SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter="handleEnter" /> | ||||
|     </div> | ||||
|     <template #footer> | ||||
|       <SearchFooter v-if="!isMobile" /> | ||||
|   | ||||
| @@ -141,6 +141,10 @@ function init() { | ||||
|   tabStore.initTabStore(route); | ||||
| } | ||||
|  | ||||
| function removeFocus() { | ||||
|   (document.activeElement as HTMLElement)?.blur(); | ||||
| } | ||||
|  | ||||
| // watch | ||||
| watch( | ||||
|   () => route.fullPath, | ||||
| @@ -162,7 +166,11 @@ init(); | ||||
| <template> | ||||
|   <DarkModeContainer class="size-full flex-y-center px-16px shadow-tab"> | ||||
|     <div ref="bsWrapper" class="h-full flex-1-hidden"> | ||||
|       <BetterScroll ref="bsScroll" :options="{ scrollX: true, scrollY: false, click: appStore.isMobile }"> | ||||
|       <BetterScroll | ||||
|         ref="bsScroll" | ||||
|         :options="{ scrollX: true, scrollY: false, click: appStore.isMobile }" | ||||
|         @click="removeFocus" | ||||
|       > | ||||
|         <div | ||||
|           ref="tabRef" | ||||
|           class="h-full flex pr-18px" | ||||
|   | ||||
| @@ -1,6 +1,10 @@ | ||||
| const local: App.I18n.Schema = { | ||||
|   system: { | ||||
|     title: 'SoybeanAdmin' | ||||
|     title: 'SoybeanAdmin', | ||||
|     updateTitle: 'System Version Update Notification', | ||||
|     updateContent: 'A new version of the system has been detected. Do you want to refresh the page immediately?', | ||||
|     updateConfirm: 'Refresh immediately', | ||||
|     updateCancel: 'Later' | ||||
|   }, | ||||
|   common: { | ||||
|     action: 'Action', | ||||
| @@ -19,6 +23,7 @@ const local: App.I18n.Schema = { | ||||
|     deleteSuccess: 'Delete Success', | ||||
|     confirmDelete: 'Are you sure you want to delete?', | ||||
|     edit: 'Edit', | ||||
|     error: 'Error', | ||||
|     index: 'Index', | ||||
|     keywordSearch: 'Please enter keyword', | ||||
|     logout: 'Logout', | ||||
|   | ||||
| @@ -1,6 +1,10 @@ | ||||
| const local: App.I18n.Schema = { | ||||
|   system: { | ||||
|     title: 'Soybean 管理系统' | ||||
|     title: 'Soybean 管理系统', | ||||
|     updateTitle: '系统版本更新通知', | ||||
|     updateContent: '检测到系统有新版本发布,是否立即刷新页面?', | ||||
|     updateConfirm: '立即刷新', | ||||
|     updateCancel: '稍后再说' | ||||
|   }, | ||||
|   common: { | ||||
|     action: '操作', | ||||
| @@ -19,6 +23,7 @@ const local: App.I18n.Schema = { | ||||
|     deleteSuccess: '删除成功', | ||||
|     confirmDelete: '确认删除吗?', | ||||
|     edit: '编辑', | ||||
|     error: '错误', | ||||
|     index: '序号', | ||||
|     keywordSearch: '请输入关键词搜索', | ||||
|     logout: '退出登录', | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { createApp } from 'vue'; | ||||
| import './plugins/assets'; | ||||
| import { setupDayjs, setupIconifyOffline, setupLoading, setupNProgress } from './plugins'; | ||||
| import { setupAppVersionNotification, setupDayjs, setupIconifyOffline, setupLoading, setupNProgress } from './plugins'; | ||||
| import { setupStore } from './store'; | ||||
| import { setupRouter } from './router'; | ||||
| import { setupI18n } from './locales'; | ||||
| @@ -23,6 +23,8 @@ async function setupApp() { | ||||
|  | ||||
|   setupI18n(app); | ||||
|  | ||||
|   setupAppVersionNotification(); | ||||
|  | ||||
|   app.mount('#app'); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										66
									
								
								src/plugins/app.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/plugins/app.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| import { h } from 'vue'; | ||||
| import { NButton } from 'naive-ui'; | ||||
| import { $t } from '../locales'; | ||||
|  | ||||
| export function setupAppVersionNotification() { | ||||
|   let isShow = false; | ||||
|  | ||||
|   document.addEventListener('visibilitychange', async () => { | ||||
|     const preConditions = [!isShow, document.visibilityState === 'visible', !import.meta.env.DEV]; | ||||
|  | ||||
|     if (!preConditions.every(Boolean)) return; | ||||
|  | ||||
|     const buildTime = await getHtmlBuildTime(); | ||||
|  | ||||
|     if (buildTime === BUILD_TIME) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     isShow = true; | ||||
|  | ||||
|     const n = window.$notification?.create({ | ||||
|       title: $t('system.updateTitle'), | ||||
|       content: $t('system.updateContent'), | ||||
|       action() { | ||||
|         return h('div', { style: { display: 'flex', justifyContent: 'end', gap: '12px', width: '325px' } }, [ | ||||
|           h( | ||||
|             NButton, | ||||
|             { | ||||
|               onClick() { | ||||
|                 n?.destroy(); | ||||
|               } | ||||
|             }, | ||||
|             () => $t('system.updateCancel') | ||||
|           ), | ||||
|           h( | ||||
|             NButton, | ||||
|             { | ||||
|               type: 'primary', | ||||
|               onClick() { | ||||
|                 location.reload(); | ||||
|               } | ||||
|             }, | ||||
|             () => $t('system.updateConfirm') | ||||
|           ) | ||||
|         ]); | ||||
|       }, | ||||
|       onClose() { | ||||
|         isShow = false; | ||||
|       } | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| async function getHtmlBuildTime() { | ||||
|   const baseURL = import.meta.env.VITE_BASE_URL; | ||||
|  | ||||
|   const res = await fetch(`${baseURL}index.html`); | ||||
|  | ||||
|   const html = await res.text(); | ||||
|  | ||||
|   const match = html.match(/<meta name="buildTime" content="(.*)">/); | ||||
|  | ||||
|   const buildTime = match?.[1] || ''; | ||||
|  | ||||
|   return buildTime; | ||||
| } | ||||
| @@ -2,3 +2,4 @@ export * from './loading'; | ||||
| export * from './nprogress'; | ||||
| export * from './iconify'; | ||||
| export * from './dayjs'; | ||||
| export * from './app'; | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import type { | ||||
|   Router | ||||
| } from 'vue-router'; | ||||
| import type { RouteKey, RoutePath } from '@elegant-router/types'; | ||||
| import { getRouteName } from '@/router/elegant/transform'; | ||||
| import { useAuthStore } from '@/store/modules/auth'; | ||||
| import { useRouteStore } from '@/store/modules/route'; | ||||
| import { localStg } from '@/utils/storage'; | ||||
| @@ -46,7 +47,7 @@ export function createRouteGuard(router: Router) { | ||||
|           next({ name: rootRoute }); | ||||
|         } | ||||
|       }, | ||||
|       // if is is constant route, then it is allowed to access directly | ||||
|       // if it is constant route, then it is allowed to access directly | ||||
|       { | ||||
|         condition: !needLogin, | ||||
|         callback: () => { | ||||
| @@ -92,6 +93,7 @@ export function createRouteGuard(router: Router) { | ||||
|  * @param to to route | ||||
|  */ | ||||
| async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw | null> { | ||||
|   const authStore = useAuthStore(); | ||||
|   const routeStore = useRouteStore(); | ||||
|  | ||||
|   const notFoundRoute: RouteKey = 'not-found'; | ||||
| @@ -148,9 +150,7 @@ async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw | ||||
|   // initialize the auth route requires the user to be logged in, if not, redirect to the login page | ||||
|   if (!isLogin) { | ||||
|     const loginRoute: RouteKey = 'login'; | ||||
|     const redirect = to.fullPath; | ||||
|  | ||||
|     const query: LocationQueryRaw = to.name !== loginRoute ? { redirect } : {}; | ||||
|     const query = getRouteQueryOfLoginRoute(to, routeStore.routeHome); | ||||
|  | ||||
|     const location: RouteLocationRaw = { | ||||
|       name: loginRoute, | ||||
| @@ -160,6 +160,8 @@ async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw | ||||
|     return location; | ||||
|   } | ||||
|  | ||||
|   await authStore.initUserInfo(); | ||||
|  | ||||
|   // initialize the auth route | ||||
|   await routeStore.initAuthRoute(); | ||||
|  | ||||
| @@ -194,3 +196,20 @@ function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNorma | ||||
|  | ||||
|   next(); | ||||
| } | ||||
|  | ||||
| function getRouteQueryOfLoginRoute(to: RouteLocationNormalized, routeHome: RouteKey) { | ||||
|   const loginRoute: RouteKey = 'login'; | ||||
|   const redirect = to.fullPath; | ||||
|   const [redirectPath, redirectQuery] = redirect.split('?'); | ||||
|   const redirectName = getRouteName(redirectPath as RoutePath); | ||||
|  | ||||
|   const isRedirectHome = routeHome === redirectName; | ||||
|  | ||||
|   const query: LocationQueryRaw = to.name !== loginRoute && !isRedirectHome ? { redirect } : {}; | ||||
|  | ||||
|   if (isRedirectHome && redirectQuery) { | ||||
|     query.redirect = `/?${redirectQuery}`; | ||||
|   } | ||||
|  | ||||
|   return query; | ||||
| } | ||||
|   | ||||
| @@ -63,10 +63,11 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt | ||||
|         window.addEventListener('beforeunload', handleLogout); | ||||
|  | ||||
|         window.$dialog?.error({ | ||||
|           title: 'Error', | ||||
|           content: response.data.code, | ||||
|           title: $t('common.error'), | ||||
|           content: response.data.msg, | ||||
|           positiveText: $t('common.confirm'), | ||||
|           maskClosable: false, | ||||
|           closeOnEsc: false, | ||||
|           onPositiveClick() { | ||||
|             logoutAndCleanup(); | ||||
|           }, | ||||
|   | ||||
| @@ -123,7 +123,7 @@ export const useAppStore = defineStore(SetupStoreId.App, () => { | ||||
|       // update tabs by locale | ||||
|       tabStore.updateTabsByLocale(); | ||||
|  | ||||
|       // sey dayjs locale | ||||
|       // set dayjs locale | ||||
|       setDayjsLocale(locale.value); | ||||
|     }); | ||||
|   }); | ||||
|   | ||||
| @@ -8,17 +8,24 @@ import { fetchGetUserInfo, fetchLogin } from '@/service/api'; | ||||
| import { localStg } from '@/utils/storage'; | ||||
| import { $t } from '@/locales'; | ||||
| import { useRouteStore } from '../route'; | ||||
| import { clearAuthStorage, getToken, getUserInfo } from './shared'; | ||||
| import { useTabStore } from '../tab'; | ||||
| import { clearAuthStorage, getToken } from './shared'; | ||||
|  | ||||
| export const useAuthStore = defineStore(SetupStoreId.Auth, () => { | ||||
|   const route = useRoute(); | ||||
|   const routeStore = useRouteStore(); | ||||
|   const tabStore = useTabStore(); | ||||
|   const { toLogin, redirectFromLogin } = useRouterPush(false); | ||||
|   const { loading: loginLoading, startLoading, endLoading } = useLoading(); | ||||
|  | ||||
|   const token = ref(getToken()); | ||||
|  | ||||
|   const userInfo: Api.Auth.UserInfo = reactive(getUserInfo()); | ||||
|   const userInfo: Api.Auth.UserInfo = reactive({ | ||||
|     userId: '', | ||||
|     userName: '', | ||||
|     roles: [], | ||||
|     buttons: [] | ||||
|   }); | ||||
|  | ||||
|   /** is super role in static route */ | ||||
|   const isStaticSuper = computed(() => { | ||||
| @@ -42,6 +49,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => { | ||||
|       await toLogin(); | ||||
|     } | ||||
|  | ||||
|     tabStore.cacheTabs(); | ||||
|     routeStore.resetStore(); | ||||
|   } | ||||
|  | ||||
| @@ -87,14 +95,23 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => { | ||||
|     localStg.set('token', loginToken.token); | ||||
|     localStg.set('refreshToken', loginToken.refreshToken); | ||||
|  | ||||
|     // 2. get user info | ||||
|     const pass = await getUserInfo(); | ||||
|  | ||||
|     if (pass) { | ||||
|       token.value = loginToken.token; | ||||
|  | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   async function getUserInfo() { | ||||
|     const { data: info, error } = await fetchGetUserInfo(); | ||||
|  | ||||
|     if (!error) { | ||||
|       // 2. store user info | ||||
|       localStg.set('userInfo', info); | ||||
|  | ||||
|       // 3. update store | ||||
|       token.value = loginToken.token; | ||||
|       // update store | ||||
|       Object.assign(userInfo, info); | ||||
|  | ||||
|       return true; | ||||
| @@ -103,6 +120,18 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => { | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   async function initUserInfo() { | ||||
|     const hasToken = getToken(); | ||||
|  | ||||
|     if (hasToken) { | ||||
|       const pass = await getUserInfo(); | ||||
|  | ||||
|       if (!pass) { | ||||
|         resetStore(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return { | ||||
|     token, | ||||
|     userInfo, | ||||
| @@ -110,6 +139,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => { | ||||
|     isLogin, | ||||
|     loginLoading, | ||||
|     resetStore, | ||||
|     login | ||||
|     login, | ||||
|     initUserInfo | ||||
|   }; | ||||
| }); | ||||
|   | ||||
| @@ -5,27 +5,8 @@ export function getToken() { | ||||
|   return localStg.get('token') || ''; | ||||
| } | ||||
|  | ||||
| /** Get user info */ | ||||
| export function getUserInfo() { | ||||
|   const emptyInfo: Api.Auth.UserInfo = { | ||||
|     userId: '', | ||||
|     userName: '', | ||||
|     roles: [], | ||||
|     buttons: [] | ||||
|   }; | ||||
|   const userInfo = localStg.get('userInfo') || emptyInfo; | ||||
|  | ||||
|   // fix new property: buttons, this will be removed in the next version `1.1.0` | ||||
|   if (!userInfo.buttons) { | ||||
|     userInfo.buttons = []; | ||||
|   } | ||||
|  | ||||
|   return userInfo; | ||||
| } | ||||
|  | ||||
| /** Clear auth storage */ | ||||
| export function clearAuthStorage() { | ||||
|   localStg.remove('token'); | ||||
|   localStg.remove('refreshToken'); | ||||
|   localStg.remove('userInfo'); | ||||
| } | ||||
|   | ||||
| @@ -97,13 +97,19 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { | ||||
|   /** Cache routes */ | ||||
|   const cacheRoutes = ref<RouteKey[]>([]); | ||||
|  | ||||
|   /** All cache routes */ | ||||
|   const allCacheRoutes = shallowRef<RouteKey[]>([]); | ||||
|  | ||||
|   /** | ||||
|    * Get cache routes | ||||
|    * | ||||
|    * @param routes Vue routes | ||||
|    */ | ||||
|   function getCacheRoutes(routes: RouteRecordRaw[]) { | ||||
|     cacheRoutes.value = getCacheRouteNames(routes); | ||||
|     const alls = getCacheRouteNames(routes); | ||||
|  | ||||
|     cacheRoutes.value = alls; | ||||
|     allCacheRoutes.value = [...alls]; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
| @@ -130,12 +136,23 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { | ||||
|     cacheRoutes.value.splice(index, 1); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Is cached route | ||||
|    * | ||||
|    * @param routeKey | ||||
|    */ | ||||
|   function isCachedRoute(routeKey: RouteKey) { | ||||
|     return allCacheRoutes.value.includes(routeKey); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Re cache routes by route key | ||||
|    * | ||||
|    * @param routeKey | ||||
|    */ | ||||
|   async function reCacheRoutesByKey(routeKey: RouteKey) { | ||||
|     if (!isCachedRoute(routeKey)) return; | ||||
|  | ||||
|     removeCacheRoutes(routeKey); | ||||
|  | ||||
|     await appStore.reloadPage(); | ||||
| @@ -202,7 +219,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { | ||||
|   /** Init auth route */ | ||||
|   async function initAuthRoute() { | ||||
|     if (authRouteMode.value === 'static') { | ||||
|       await initStaticAuthRoute(); | ||||
|       initStaticAuthRoute(); | ||||
|     } else { | ||||
|       await initDynamicAuthRoute(); | ||||
|     } | ||||
| @@ -211,7 +228,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { | ||||
|   } | ||||
|  | ||||
|   /** Init static auth route */ | ||||
|   async function initStaticAuthRoute() { | ||||
|   function initStaticAuthRoute() { | ||||
|     const { authRoutes: staticAuthRoutes } = createStaticRoutes(); | ||||
|  | ||||
|     if (authStore.isStaticSuper) { | ||||
|   | ||||
| @@ -123,7 +123,7 @@ function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | Elegant | ||||
|   const { SvgIconVNode } = useSvgIcon(); | ||||
|  | ||||
|   const { name, path } = route; | ||||
|   const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon } = route.meta ?? {}; | ||||
|   const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon, iconFontSize } = route.meta ?? {}; | ||||
|  | ||||
|   const label = i18nKey ? $t(i18nKey) : title!; | ||||
|  | ||||
| @@ -133,7 +133,7 @@ function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | Elegant | ||||
|     i18nKey, | ||||
|     routeKey: name as RouteKey, | ||||
|     routePath: path as RouteMap[RouteKey], | ||||
|     icon: SvgIconVNode({ icon, localIcon, fontSize: 20 }) | ||||
|     icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 }) | ||||
|   }; | ||||
|  | ||||
|   return menu; | ||||
|   | ||||
| @@ -17,6 +17,7 @@ import { | ||||
|   getDefaultHomeTab, | ||||
|   getFixedTabIds, | ||||
|   getTabByRoute, | ||||
|   getTabIdByRoute, | ||||
|   isTabInTabs, | ||||
|   updateTabByI18nKey, | ||||
|   updateTabsByI18nKey | ||||
| @@ -288,6 +289,8 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => { | ||||
|     setTabLabel, | ||||
|     resetTabLabel, | ||||
|     isTabRetain, | ||||
|     updateTabsByLocale | ||||
|     updateTabsByLocale, | ||||
|     getTabIdByRoute, | ||||
|     cacheTabs | ||||
|   }; | ||||
| }); | ||||
|   | ||||
							
								
								
									
										5
									
								
								src/typings/app.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								src/typings/app.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -251,6 +251,10 @@ declare namespace App { | ||||
|     type Schema = { | ||||
|       system: { | ||||
|         title: string; | ||||
|         updateTitle: string; | ||||
|         updateContent: string; | ||||
|         updateConfirm: string; | ||||
|         updateCancel: string; | ||||
|       }; | ||||
|       common: { | ||||
|         action: string; | ||||
| @@ -269,6 +273,7 @@ declare namespace App { | ||||
|         deleteSuccess: string; | ||||
|         confirmDelete: string; | ||||
|         edit: string; | ||||
|         error: string; | ||||
|         index: string; | ||||
|         keywordSearch: string; | ||||
|         logout: string; | ||||
|   | ||||
							
								
								
									
										4
									
								
								src/typings/env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								src/typings/env.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -105,3 +105,7 @@ declare namespace Env { | ||||
|     readonly VITE_STORAGE_PREFIX?: string; | ||||
|   } | ||||
| } | ||||
|  | ||||
| interface ImportMeta { | ||||
|   readonly env: Env.ImportMeta; | ||||
| } | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/typings/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								src/typings/global.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -1,27 +1,27 @@ | ||||
| interface Window { | ||||
|   /** NProgress instance */ | ||||
|   NProgress?: import('nprogress').NProgress; | ||||
|   /** Loading bar instance */ | ||||
|   $loadingBar?: import('naive-ui').LoadingBarProviderInst; | ||||
|   /** Dialog instance */ | ||||
|   $dialog?: import('naive-ui').DialogProviderInst; | ||||
|   /** Message instance */ | ||||
|   $message?: import('naive-ui').MessageProviderInst; | ||||
|   /** Notification instance */ | ||||
|   $notification?: import('naive-ui').NotificationProviderInst; | ||||
| } | ||||
| export {}; | ||||
|  | ||||
| interface ViewTransition { | ||||
|   ready: Promise<void>; | ||||
| } | ||||
| declare global { | ||||
|   export interface Window { | ||||
|     /** NProgress instance */ | ||||
|     NProgress?: import('nprogress').NProgress; | ||||
|     /** Loading bar instance */ | ||||
|     $loadingBar?: import('naive-ui').LoadingBarProviderInst; | ||||
|     /** Dialog instance */ | ||||
|     $dialog?: import('naive-ui').DialogProviderInst; | ||||
|     /** Message instance */ | ||||
|     $message?: import('naive-ui').MessageProviderInst; | ||||
|     /** Notification instance */ | ||||
|     $notification?: import('naive-ui').NotificationProviderInst; | ||||
|   } | ||||
|  | ||||
| interface Document { | ||||
|   startViewTransition?: (callback: () => Promise<void> | void) => ViewTransition; | ||||
| } | ||||
|   interface ViewTransition { | ||||
|     ready: Promise<void>; | ||||
|   } | ||||
|  | ||||
| interface ImportMeta { | ||||
|   readonly env: Env.ImportMeta; | ||||
| } | ||||
|   export interface Document { | ||||
|     startViewTransition?: (callback: () => Promise<void> | void) => ViewTransition; | ||||
|   } | ||||
|  | ||||
| /** Build time of the project */ | ||||
| declare const BUILD_TIME: string; | ||||
|   /** Build time of the project */ | ||||
|   export const BUILD_TIME: string; | ||||
| } | ||||
|   | ||||
							
								
								
									
										9
									
								
								src/typings/router.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								src/typings/router.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -27,7 +27,7 @@ declare module 'vue-router' { | ||||
|     /** | ||||
|      * Is constant route | ||||
|      * | ||||
|      * Does not need to login, and the route is defined in the front-end | ||||
|      * when it is set to true, there will be no login verification and no permission verification to access the route | ||||
|      */ | ||||
|     constant?: boolean | null; | ||||
|     /** | ||||
| @@ -42,6 +42,8 @@ declare module 'vue-router' { | ||||
|      * In "src/assets/svg-icon", if it is set, the icon will be ignored | ||||
|      */ | ||||
|     localIcon?: string; | ||||
|     /** Icon size. width and height are the same. */ | ||||
|     iconFontSize?: number; | ||||
|     /** Router order */ | ||||
|     order?: number | null; | ||||
|     /** The outer link of the route */ | ||||
| @@ -57,7 +59,10 @@ declare module 'vue-router' { | ||||
|      *   the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated | ||||
|      */ | ||||
|     activeMenu?: import('@elegant-router/types').RouteKey | null; | ||||
|     /** By default, the same route path will use one tab, if set to true, it will use multiple tabs */ | ||||
|     /** | ||||
|      * By default, the same route path will use one tab, even with different query, if set true, the route with | ||||
|      * different query will use different tabs | ||||
|      */ | ||||
|     multiTab?: boolean | null; | ||||
|     /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ | ||||
|     fixedIndexInTab?: number | null; | ||||
|   | ||||
							
								
								
									
										2
									
								
								src/typings/storage.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/typings/storage.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -18,8 +18,6 @@ declare namespace StorageType { | ||||
|     mixSiderFixed: CommonType.YesOrNo; | ||||
|     /** The refresh token */ | ||||
|     refreshToken: string; | ||||
|     /** The user info */ | ||||
|     userInfo: Api.Auth.UserInfo; | ||||
|     /** The theme color */ | ||||
|     themeColor: string; | ||||
|     /** The theme settings */ | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import { useFormRules, useNaiveForm } from '@/hooks/common/form'; | ||||
| import { useCaptcha } from '@/hooks/business/captcha'; | ||||
|  | ||||
| defineOptions({ | ||||
|   name: 'CodeLogin' | ||||
|   name: 'Register' | ||||
| }); | ||||
|  | ||||
| const { toggleLoginModule } = useRouterPush(); | ||||
|   | ||||
| @@ -18,7 +18,7 @@ const { bool: visible, setTrue: openModal } = useBoolean(); | ||||
|  | ||||
| const wrapperRef = ref<HTMLElement | null>(null); | ||||
|  | ||||
| const { columns, columnChecks, data, loading, pagination, getData } = useTable({ | ||||
| const { columns, columnChecks, data, loading, pagination, getData, getDataByPage } = useTable({ | ||||
|   apiFn: fetchGetMenuList, | ||||
|   columns: () => [ | ||||
|     { | ||||
| @@ -257,7 +257,7 @@ init(); | ||||
|         :operate-type="operateType" | ||||
|         :row-data="editingData" | ||||
|         :all-pages="allPages" | ||||
|         @submitted="getData" | ||||
|         @submitted="getDataByPage" | ||||
|       /> | ||||
|     </NCard> | ||||
|   </div> | ||||
|   | ||||
| @@ -374,7 +374,6 @@ watch( | ||||
|           </NFormItemGi> | ||||
|           <NFormItemGi span="24 m:12" :label="$t('page.manage.menu.hideInMenu')" path="hideInMenu"> | ||||
|             <NRadioGroup v-model:value="model.hideInMenu"> | ||||
|               <!-- eslint-disable-next-line vue/prefer-true-attribute-shorthand --> | ||||
|               <NRadio :value="true" :label="$t('common.yesOrNo.yes')" /> | ||||
|               <NRadio :value="false" :label="$t('common.yesOrNo.no')" /> | ||||
|             </NRadioGroup> | ||||
|   | ||||
| @@ -6,7 +6,7 @@ export function getLayoutAndPage(component?: string | null) { | ||||
|   let layout = ''; | ||||
|   let page = ''; | ||||
|  | ||||
|   const [layoutOrPage, pageItem] = component?.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT) || []; | ||||
|   const [layoutOrPage = '', pageItem = ''] = component?.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT) || []; | ||||
|  | ||||
|   layout = getLayout(layoutOrPage); | ||||
|   page = getPage(pageItem || layoutOrPage); | ||||
|   | ||||
| @@ -10,7 +10,17 @@ import RoleSearch from './modules/role-search.vue'; | ||||
|  | ||||
| const appStore = useAppStore(); | ||||
|  | ||||
| const { columns, columnChecks, data, loading, getData, mobilePagination, searchParams, resetSearchParams } = useTable({ | ||||
| const { | ||||
|   columns, | ||||
|   columnChecks, | ||||
|   data, | ||||
|   loading, | ||||
|   getData, | ||||
|   getDataByPage, | ||||
|   mobilePagination, | ||||
|   searchParams, | ||||
|   resetSearchParams | ||||
| } = useTable({ | ||||
|   apiFn: fetchGetRoleList, | ||||
|   apiParams: { | ||||
|     current: 1, | ||||
| @@ -129,7 +139,7 @@ function edit(id: number) { | ||||
|  | ||||
| <template> | ||||
|   <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto"> | ||||
|     <RoleSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" /> | ||||
|     <RoleSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" /> | ||||
|     <NCard :title="$t('page.manage.role.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper"> | ||||
|       <template #header-extra> | ||||
|         <TableHeaderOperation | ||||
| @@ -158,7 +168,7 @@ function edit(id: number) { | ||||
|         v-model:visible="drawerVisible" | ||||
|         :operate-type="operateType" | ||||
|         :row-data="editingData" | ||||
|         @submitted="getData" | ||||
|         @submitted="getDataByPage" | ||||
|       /> | ||||
|     </NCard> | ||||
|   </div> | ||||
|   | ||||
| @@ -10,7 +10,17 @@ import UserSearch from './modules/user-search.vue'; | ||||
|  | ||||
| const appStore = useAppStore(); | ||||
|  | ||||
| const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams } = useTable({ | ||||
| const { | ||||
|   columns, | ||||
|   columnChecks, | ||||
|   data, | ||||
|   getData, | ||||
|   getDataByPage, | ||||
|   loading, | ||||
|   mobilePagination, | ||||
|   searchParams, | ||||
|   resetSearchParams | ||||
| } = useTable({ | ||||
|   apiFn: fetchGetUserList, | ||||
|   showTotal: true, | ||||
|   apiParams: { | ||||
| @@ -160,7 +170,7 @@ function edit(id: number) { | ||||
|  | ||||
| <template> | ||||
|   <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto"> | ||||
|     <UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" /> | ||||
|     <UserSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" /> | ||||
|     <NCard :title="$t('page.manage.user.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper"> | ||||
|       <template #header-extra> | ||||
|         <TableHeaderOperation | ||||
| @@ -189,7 +199,7 @@ function edit(id: number) { | ||||
|         v-model:visible="drawerVisible" | ||||
|         :operate-type="operateType" | ||||
|         :row-data="editingData" | ||||
|         @submitted="getData" | ||||
|         @submitted="getDataByPage" | ||||
|       /> | ||||
|     </NCard> | ||||
|   </div> | ||||
|   | ||||
| @@ -1,14 +1,13 @@ | ||||
| import process from 'node:process'; | ||||
| import { URL, fileURLToPath } from 'node:url'; | ||||
| import { defineConfig, loadEnv } from 'vite'; | ||||
| import dayjs from 'dayjs'; | ||||
| import { setupVitePlugins } from './build/plugins'; | ||||
| import { createViteProxy } from './build/config'; | ||||
| import { createViteProxy, getBuildTime } from './build/config'; | ||||
|  | ||||
| export default defineConfig(configEnv => { | ||||
|   const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as Env.ImportMeta; | ||||
|  | ||||
|   const buildTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); | ||||
|   const buildTime = getBuildTime(); | ||||
|  | ||||
|   return { | ||||
|     base: viteEnv.VITE_BASE_URL, | ||||
| @@ -25,7 +24,7 @@ export default defineConfig(configEnv => { | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     plugins: setupVitePlugins(viteEnv), | ||||
|     plugins: setupVitePlugins(viteEnv, buildTime), | ||||
|     define: { | ||||
|       BUILD_TIME: JSON.stringify(buildTime) | ||||
|     }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user