- 
					2.env
 - 
					2.env.development
 - 
					5.gitignore
 - 
					2.husky/common.sh
 - 
					11.markdownlint.json
 - 
					4.prettierrc.js
 - 
					51.vscode/settings.json
 - 
					22.vscode/vue3.0.code-snippets
 - 
					20.vscode/vue3.2.setup-snippets
 - 
					14README.en-US.md
 - 
					10README.md
 - 
					37index.html
 - 
					3mock/asyncRoutes.ts
 - 
					109package.json
 - 
					6529pnpm-lock.yaml
 - 
					BINpublic/favicon.ico
 - 
					17public/serverConfig.json
 - 
					8src/App.vue
 - 
					2src/api/routes.ts
 - 
					BINsrc/assets/401.gif
 - 
					BINsrc/assets/bg.png
 - 
					BINsrc/assets/car.png
 - 
					26src/assets/iconfont/iconfont.css
 - 
					44src/assets/iconfont/iconfont.js
 - 
					38src/assets/iconfont/iconfont.json
 - 
					BINsrc/assets/iconfont/iconfont.ttf
 - 
					BINsrc/assets/iconfont/iconfont.woff
 - 
					BINsrc/assets/iconfont/iconfont.woff2
 - 
					BINsrc/assets/login.png
 - 
					1src/assets/login/avatar.svg
 - 
					BINsrc/assets/login/bg.png
 - 
					1src/assets/login/illustration0.svg
 - 
					1src/assets/login/illustration1.svg
 - 
					1src/assets/login/illustration2.svg
 - 
					1src/assets/login/illustration3.svg
 - 
					1src/assets/login/illustration4.svg
 - 
					1src/assets/login/illustration5.svg
 - 
					1src/assets/login/illustration6.svg
 - 
					1src/assets/svg/back_top.svg
 - 
					195src/components/ReInfo/index.vue
 - 
					138src/layout/components/appMain.vue
 - 
					26src/layout/components/navbar.vue
 - 
					25src/layout/components/panel/index.vue
 - 
					408src/layout/components/setting/index.vue
 - 
					6src/layout/components/sidebar/hamBurger.vue
 - 
					25src/layout/components/sidebar/horizontal.vue
 - 
					25src/layout/components/sidebar/logo.vue
 - 
					97src/layout/components/sidebar/sidebarItem.vue
 - 
					2src/layout/components/sidebar/vertical.vue
 - 
					18src/layout/components/tag/index.vue
 - 
					157src/layout/index.vue
 - 
					12src/layout/theme/auroraGreen-vars.scss
 - 
					24src/layout/theme/default-vars.scss
 - 
					12src/layout/theme/dusk-vars.scss
 - 
					11src/layout/theme/light-vars.scss
 - 
					12src/layout/theme/mingQing-vars.scss
 - 
					12src/layout/theme/pink-vars.scss
 - 
					12src/layout/theme/saucePurple-vars.scss
 - 
					12src/layout/theme/volcano-vars.scss
 - 
					12src/layout/theme/yellow-vars.scss
 - 
					7src/layout/types.ts
 - 
					4src/main.ts
 - 
					44src/plugins/element-plus/index.ts
 - 
					75src/plugins/i18n/config.ts
 - 
					1src/plugins/i18n/index.ts
 - 
					119src/plugins/vxe-table/index.ts
 - 
					11src/router/index.ts
 - 
					2src/router/modules/error.ts
 - 
					25src/router/modules/externalLink.ts
 - 
					2src/router/modules/home.ts
 - 
					12src/router/modules/remaining.ts
 - 
					5src/store/modules/app.ts
 - 
					4src/style/element-plus.scss
 - 
					14src/style/index.scss
 - 
					227src/style/login.css
 - 
					320src/style/sidebar.scss
 - 
					28src/utils/http/core.ts
 - 
					13src/utils/storage/responsive.ts
 - 
					184src/views/login.vue
 - 
					2src/views/permission/button/index.vue
 - 
					4src/views/permission/page/index.vue
 - 
					17src/views/register.vue
 - 
					4types/global.d.ts
 - 
					76vite.config.ts
 - 
					4583yarn.lock
 
@ -0,0 +1,11 @@ | 
				
			|||
{ | 
				
			|||
  "default": true, | 
				
			|||
  "MD003": false, | 
				
			|||
  "MD033": false, | 
				
			|||
  "MD013": false, | 
				
			|||
  "MD001": false, | 
				
			|||
  "MD025": false, | 
				
			|||
  "MD024": false, | 
				
			|||
  "MD007": { "indent": 4 }, | 
				
			|||
  "no-hard-tabs": false | 
				
			|||
} | 
				
			|||
@ -0,0 +1,51 @@ | 
				
			|||
{ | 
				
			|||
  // You should install these plugins: | 
				
			|||
  // ESLint | 
				
			|||
  // Prettier - Code formatter | 
				
			|||
  // stylelint | 
				
			|||
  // vscode-icons | 
				
			|||
  // TypeScript Vue Plugin (Volar) | 
				
			|||
  // Vue Language Features (Volar) | 
				
			|||
  "terminal.integrated.rendererType": "dom", | 
				
			|||
  "editor.formatOnType": true, | 
				
			|||
  "editor.formatOnSave": true, | 
				
			|||
  "javascript.updateImportsOnFileMove.enabled": "always", | 
				
			|||
  "[vue]": { | 
				
			|||
    "editor.defaultFormatter": "esbenp.prettier-vscode" | 
				
			|||
  }, | 
				
			|||
  "[javascript]": { | 
				
			|||
    "editor.defaultFormatter": "vscode.typescript-language-features" | 
				
			|||
  }, | 
				
			|||
  "editor.tabSize": 2, | 
				
			|||
  "editor.formatOnPaste": true, | 
				
			|||
  "files.autoSave": "afterDelay", | 
				
			|||
  "git.confirmSync": false, | 
				
			|||
  "workbench.startupEditor": "newUntitledFile", | 
				
			|||
  "editor.suggestSelection": "first", | 
				
			|||
  "editor.acceptSuggestionOnCommitCharacter": false, | 
				
			|||
  "css.lint.propertyIgnoredDueToDisplay": "ignore", | 
				
			|||
  // Prevent inline styles from being automatically formatted to all lowercase | 
				
			|||
  "editor.quickSuggestions": { | 
				
			|||
    "other": true, | 
				
			|||
    "comments": true, | 
				
			|||
    "strings": true | 
				
			|||
  }, | 
				
			|||
  // Automatically fix some syntax errors of ts | 
				
			|||
  "tslint.autoFixOnSave": true, | 
				
			|||
  "files.associations": { | 
				
			|||
    // Specifies the location of snippets in the suggestion widget | 
				
			|||
    "editor.snippetSuggestions": "top" | 
				
			|||
  }, | 
				
			|||
  "[css]": { | 
				
			|||
    "editor.defaultFormatter": "esbenp.prettier-vscode" | 
				
			|||
  }, | 
				
			|||
  "cSpell.userWords": ["sourcemap", "vite"], | 
				
			|||
  "editor.codeActionsOnSave": { | 
				
			|||
    "source.fixAll.eslint": true | 
				
			|||
  }, | 
				
			|||
  "volar.tsPlugin": true, | 
				
			|||
  "typescript.tsdk": "node_modules/typescript/lib", | 
				
			|||
  "i18n-ally.localesPaths": [ | 
				
			|||
    "src/plugins/i18n" | 
				
			|||
  ] | 
				
			|||
} | 
				
			|||
@ -0,0 +1,22 @@ | 
				
			|||
{ | 
				
			|||
  "Vue3.0快速生成模板": { | 
				
			|||
    "prefix": "Vue3.0", | 
				
			|||
    "body": [ | 
				
			|||
      "<template>", | 
				
			|||
      "\t<div>\n", | 
				
			|||
      "\t</div>", | 
				
			|||
      "</template>\n", | 
				
			|||
      "<script lang='ts'>", | 
				
			|||
      "export default {", | 
				
			|||
      "\tsetup(){", | 
				
			|||
      "\t\treturn{\n\n\t\t}", | 
				
			|||
      "\t},", | 
				
			|||
      "}", | 
				
			|||
      "</script>\n", | 
				
			|||
      "<style scoped>\n", | 
				
			|||
      "</style>", | 
				
			|||
      "$2" | 
				
			|||
    ], | 
				
			|||
    "description": "Vue3.0" | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,20 @@ | 
				
			|||
{ | 
				
			|||
  "Vue3.2快速生成模板": { | 
				
			|||
    "prefix": "Vue3.2", | 
				
			|||
    "body": [ | 
				
			|||
      "<!-- $1 -->", | 
				
			|||
      "<script setup lang='ts'>", | 
				
			|||
      "\t$2", | 
				
			|||
      "</script>\n", | 
				
			|||
      "<template>", | 
				
			|||
      "\t<div>", | 
				
			|||
      "\t\t$3", | 
				
			|||
      "\t</div>", | 
				
			|||
      "</template>\n", | 
				
			|||
      "<style scoped>", | 
				
			|||
      "\t$4", | 
				
			|||
      "</style>" | 
				
			|||
    ], | 
				
			|||
    "description": "Vue3.2" | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
@ -1 +1,13 @@ | 
				
			|||
<h1>vue-pure-admin精简版</h1> | 
				
			|||
<h1>vue-pure-admin Lite Edition</h1> | 
				
			|||
 | 
				
			|||
## introduce | 
				
			|||
 | 
				
			|||
The lite version is based on the shelf extracted from https://github.com/xiaoxian521/vue-pure-admin, which contains the main functions and is more suitable for actual project development | 
				
			|||
 | 
				
			|||
## Supporting video tutorial | 
				
			|||
 | 
				
			|||
bilibili: https://www.bilibili.com/video/BV1534y1S7HV/ | 
				
			|||
 | 
				
			|||
## ⚠️ Note | 
				
			|||
 | 
				
			|||
The lite version does not accept any issues and prs. If you have any questions, please go to the full version https://github.com/xiaoxian521/vue-pure-admin/issues/new/choose to mention it, thank you! ! ! | 
				
			|||
@ -1,11 +1,13 @@ | 
				
			|||
<h1>vue-pure-admin精简版</h1> | 
				
			|||
 | 
				
			|||
## 介绍 | 
				
			|||
 | 
				
			|||
精简版是基于 https://github.com/xiaoxian521/vue-pure-admin 提炼出的架子,包含主体功能,更适合实际项目开发 | 
				
			|||
 | 
				
			|||
## 配套视频教程 | 
				
			|||
 | 
				
			|||
bilibili:https://www.bilibili.com/video/BV1534y1S7HV/ | 
				
			|||
 | 
				
			|||
## 交流群 | 
				
			|||
 | 
				
			|||
[微信交流群,点击扫码进群](https://juejin.cn/post/6948419379566477342/) | 
				
			|||
## ⚠️ 注意 | 
				
			|||
 | 
				
			|||
本人微信:18237613535,拉你进群 | 
				
			|||
精简版不接受任何 issues 和 pr,如果有问题请到完整版 https://github.com/xiaoxian521/vue-pure-admin/issues/new/choose 去提,谢谢!!! | 
				
			|||
						
							
						
						
							6529
	
						
						pnpm-lock.yaml
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				| 
		 After Width: 32 | Height: 32 | Size: 1.2 KiB  | 
@ -1,9 +1,22 @@ | 
				
			|||
{ | 
				
			|||
  "Version": "2.1.0", | 
				
			|||
  "Version": "2.6.0", | 
				
			|||
  "Title": "PureAdmin", | 
				
			|||
  "FixedHeader": true, | 
				
			|||
  "HiddenSideBar": false, | 
				
			|||
  "KeepAlive": true, | 
				
			|||
  "Locale": "zh", | 
				
			|||
  "Layout": "vertical-dark" | 
				
			|||
  "Layout": "vertical", | 
				
			|||
  "Theme": "default", | 
				
			|||
  "Grey": false, | 
				
			|||
  "Weak": false, | 
				
			|||
  "HideTabs": false, | 
				
			|||
  "MapConfigure": { | 
				
			|||
    "amapKey": "97b3248d1553172e81f168cf94ea667e", | 
				
			|||
    "baiduKey": "wTHbkkEweiFqZLKunMIjcrb2RcqNXkhc", | 
				
			|||
    "options": { | 
				
			|||
      "resizeEnable": true, | 
				
			|||
      "center": [113.6401, 34.72468], | 
				
			|||
      "zoom": 12 | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
@ -1,4 +1,4 @@ | 
				
			|||
import { http } from "/@/utils/http"; | 
				
			|||
import { http } from "../utils/http"; | 
				
			|||
 | 
				
			|||
export const getAsyncRoutes = (data?: object) => { | 
				
			|||
  return http.request("get", "/getAsyncRoutes", data); | 
				
			|||
 | 
				
			|||
| 
		 Before Width: 313 | Height: 428 | Size: 160 KiB After Width: 313 | Height: 428 | Size: 680 KiB  | 
| 
		 Before Width: 1920 | Height: 1080 | Size: 1.1 MiB  | 
| 
		 After Width: 36 | Height: 20 | Size: 1.4 KiB  | 
						
							
						
						
							44
	
						
						src/assets/iconfont/iconfont.js
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				| 
		 Before Width: 607 | Height: 716 | Size: 9.9 KiB  | 
@ -0,0 +1 @@ | 
				
			|||
<svg t="1636193306629" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1847" width="32" height="32"><path d="M410.558481 0.10861C410.558481 211.083075 109.682285 361.860579 109.682285 633.656511c0 174.943176 134.703259 316.787527 300.876196 316.787527s300.876197-141.817198 300.876197-316.787527C711.407525 361.751969 410.558481 210.974465 410.558481 0.10861z" fill="#386BF3" p-id="1848"></path><path d="M613.468671 73.664572c0 211.055922-300.876197 361.914883-300.876196 633.547901 0 174.943176 134.703259 316.787527 300.876196 316.787527s300.876197-141.817198 300.876197-316.787527c-0.054305-271.633018-300.876197-422.491979-300.876197-633.547901z" fill="#C3D2FB" p-id="1849"></path><path d="M312.592475 707.212473c0-183.713414 137.635722-312.171612 226.72288-441.390078 81.701694 106.111739 172.119322 218.740063 172.119323 367.725506a309.755045 309.755045 0 0 1-291.074166 316.516003 323.114046 323.114046 0 0 1-107.768037-242.851431z" fill="#303F5B" p-id="1850"></path></svg> | 
				
			|||
| 
		 After Width: 1920 | Height: 1080 | Size: 17 KiB  | 
						
							
						
						
							1
	
						
						src/assets/login/illustration0.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				
						
							
						
						
							1
	
						
						src/assets/login/illustration1.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				@ -0,0 +1 @@ | 
				
			|||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="500" height="380" viewBox="0 0 896 529.1129" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M832.06729,623.22778s-26.37759,9.89441-38.806,32.94348S787.06,706.69574,787.06,706.69574s26.37759-9.89447,38.806-32.94348S832.06729,623.22778,832.06729,623.22778Z" transform="translate(-158 -185.8871)" fill="#3f3d56"/><path d="M867.5,657.59637s-8.64182,26.814-31.0802,40.31373-50.17651,8.57293-50.17651,8.57293,8.64175-26.81408,31.08017-40.31378S867.5,657.59637,867.5,657.59637Z" transform="translate(-158 -185.8871)" fill="#5392f0"/><rect y="527.1129" width="896" height="2" fill="#2f2e41"/><path d="M519.87238,620.97461a95.44448,95.44448,0,0,1-35.748-14.44629L485.306,604.915a93.36283,93.36283,0,0,0,34.999,14.10547c18.93164,3.40137,47.26075,1.73144,74.707-25.52735,53.41358-53.04785,104.39307-58.39062,104.90186-58.43847l.18652,1.99219c-.50146.04687-50.76806,5.31738-103.67822,57.86621-21.61328,21.46386-43.792,27.40234-61.71777,27.40234A83.49962,83.49962,0,0,1,519.87238,620.97461Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><circle cx="515.15271" cy="381.1129" r="12" fill="#2f2e41"/><circle cx="430.15271" cy="437.1129" r="12" fill="#2f2e41"/><path d="M841.5,714s-17.46191-5.41315-52.26129-10.84192L790,692.5c6-60-34-150-34-150a401.561,401.561,0,0,1,21.4693,139.0246C772.13214,672.2124,761.82056,662.16638,742,656c0,0,25.77765,22.106,33.15918,45.10175a997.84042,997.84042,0,0,0-102.02258-8.21589L682,672.5l-17,17s-7-51-22-53l11,50s-13-10-16-9l7.39746,14.79486c-49.819-.51654-109.08453,1.7356-177.76581,8.95227L476,682l-17,17s-7-51-22-53l11,50s-13-10-16-9l8.64288,17.28583Q406.9763,708.2897,370.5,714Z" transform="translate(-158 -185.8871)" fill="#3f3d56"/><path d="M565.64813,230.37817c-10.89964,11.74783,17.59745,40.25959,17.59745,40.25959s-57.70662,9.73051-53.12783,9.14083,2.20622-49.13151,2.20622-49.13151S576.54777,218.63035,565.64813,230.37817Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M605.81236,356.10945l-50.139,25.6141-27.22969,15.6059s-32.09862,40.43116-38.08709,64.39234,25.92963,68.247,29.54371,72.82286a54.36088,54.36088,0,0,1,4.98908,7.42355c1.24727,1.85589,12.02944-.541,23.80342-3.06554S547.13,518.93875,547.13,518.93875s-15.02732-38.39505-16.14686-39.25912c-1.04554-.807-4.60093-7.44631-2.04309-10.35234a25.94993,25.94993,0,0,0,5.44489-8.89825,30.09064,30.09064,0,0,1,4.18709-7.94151s45.361-36.83645,59.52776-49.37835,51.82952-4.65839,51.82952-4.65839-17.78167,68.20027-22.22979,72.80616-4.929,8.70085-2.91535,16.50759,28.28157.39078,28.28157.39078L662.766,461.6996s15.74879-34.2925,24.29946-69.67451c4.27533-17.691-3.88828-28.23462-13.12073-34.35549a41.39094,41.39094,0,0,0-30.02983-5.97766l-46.34848,8.1308,32.14706-13.84923Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><path d="M420.87777,290.19133,361.02366,271.685s-24.179-31.16689-12.78824-36.6669,25.65172,26.94419,25.65172,26.94419l41.686,2.69751Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M672.49431,257.78673l53.2121-33.06768s15.49333-36.27612,3.0807-38.71059-17.98787,32.56435-17.98787,32.56435l-39.64232,13.17143Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M682.45318,220.40023l1.01427,39.19147-89.68779,16.025c13.19231,28.22441,9.84118,60.34675,43.04725,74.4259L524.9027,404.78717c4.9871-43.03806-15.81748-75.456-35.263-115.75876-23.68547-8.58589-51.19594-2.29078-80.33649,10.34619l-5.237-40.66416,123.87841-8.896,20.34848,7.77932,21.81842-9.17677C602.17891,238.88953,648.22076,220.77584,682.45318,220.40023Z" transform="translate(-158 -185.8871)" fill="#5392f0"/><path d="M626.64006,486.51727c-2.72,2.36681-5.25213,21.84984-5.34982,28.92023s9.21178,8.89624,14.29855,9.2494,4.47816,3.45631,7.83678,6.04854,14.39625,2.179,28.89019-2.71238-9.75274-20.92568-11.86409-21.662-11-22.78156-11-22.78156S629.36,484.15046,626.64006,486.51727Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><path d="M547.368,531.00717c3.23089,1.60043,10.61681,19.80614,12.50274,26.62107s-6.65716,10.93994-11.48848,12.5704-3.45631,4.47816-6.04855,7.83678-13.3744,5.75546-28.63472,4.696,4.13258-22.71391,5.98847-23.96118,4.86893-24.82526,4.86893-24.82526S544.13715,529.40674,547.368,531.00717Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><circle cx="389.47074" cy="35.42904" r="23.99585" fill="#a0616a"/><path d="M519.73448,218.90923a22.82668,22.82668,0,0,1-.83378-18.59281c2.35891-5.8153,7.59174-11.65569,18.87309-13.4,24.61387-3.80572,37.71267,13.43543,37.02452,19.07449s-3.99294,19.27051-3.99294,19.27051,1.47587-12.90619-4.85883-13.362-30.90178-2.37835-37.12217,4.145a14.23268,14.23268,0,0,0-3.71042,13.82977Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/></svg> | 
				
			|||
						
							
						
						
							1
	
						
						src/assets/login/illustration3.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				
						
							
						
						
							1
	
						
						src/assets/login/illustration4.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				
						
							
						
						
							1
	
						
						src/assets/login/illustration5.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				
						
							
						
						
							1
	
						
						src/assets/login/illustration6.svg
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				@ -0,0 +1 @@ | 
				
			|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2.88 18.054a35.897 35.897 0 0 1 8.531-16.32.8.8 0 0 1 1.178 0c.166.18.304.332.413.455a35.897 35.897 0 0 1 8.118 15.865c-2.141.451-4.34.747-6.584.874l-2.089 4.178a.5.5 0 0 1-.894 0l-2.089-4.178a44.019 44.019 0 0 1-6.584-.874zm6.698-1.123l1.157.066L12 19.527l1.265-2.53 1.157-.066a42.137 42.137 0 0 0 4.227-.454A33.913 33.913 0 0 0 12 4.09a33.913 33.913 0 0 0-6.649 12.387c1.395.222 2.805.374 4.227.454zM12 15a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg> | 
				
			|||
@ -1,195 +0,0 @@ | 
				
			|||
<script setup lang="ts"> | 
				
			|||
import { ref, PropType, getCurrentInstance, watch, nextTick, toRef } from "vue"; | 
				
			|||
import { useRouter, useRoute } from "vue-router"; | 
				
			|||
import { initRouter } from "/@/router"; | 
				
			|||
import { storageSession } from "/@/utils/storage"; | 
				
			|||
 | 
				
			|||
export interface ContextProps { | 
				
			|||
  userName: string; | 
				
			|||
  passWord: string; | 
				
			|||
  verify: number | null; | 
				
			|||
  svg: any; | 
				
			|||
  telephone?: number; | 
				
			|||
  dynamicText?: string; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
const props = defineProps({ | 
				
			|||
  ruleForm: { | 
				
			|||
    type: Object as PropType<ContextProps> | 
				
			|||
  } | 
				
			|||
}); | 
				
			|||
 | 
				
			|||
const emit = defineEmits<{ | 
				
			|||
  (e: "onBehavior", evt: Object): void; | 
				
			|||
  (e: "refreshVerify"): void; | 
				
			|||
}>(); | 
				
			|||
 | 
				
			|||
const instance = getCurrentInstance(); | 
				
			|||
 | 
				
			|||
const model = toRef(props, "ruleForm"); | 
				
			|||
let tips = ref<string>("注册"); | 
				
			|||
let tipsFalse = ref<string>("登录"); | 
				
			|||
 | 
				
			|||
const route = useRoute(); | 
				
			|||
const router = useRouter(); | 
				
			|||
 | 
				
			|||
watch( | 
				
			|||
  route, | 
				
			|||
  async ({ path }): Promise<void> => { | 
				
			|||
    await nextTick(); | 
				
			|||
    path.includes("register") | 
				
			|||
      ? (tips.value = "登录") && (tipsFalse.value = "注册") | 
				
			|||
      : (tips.value = "注册") && (tipsFalse.value = "登录"); | 
				
			|||
  }, | 
				
			|||
  { immediate: true } | 
				
			|||
); | 
				
			|||
 | 
				
			|||
const rules = ref<any>({ | 
				
			|||
  userName: [{ required: true, message: "请输入用户名", trigger: "blur" }], | 
				
			|||
  passWord: [ | 
				
			|||
    { required: true, message: "请输入密码", trigger: "blur" }, | 
				
			|||
    { min: 6, message: "密码长度必须不小于6位", trigger: "blur" } | 
				
			|||
  ], | 
				
			|||
  verify: [ | 
				
			|||
    { required: true, message: "请输入验证码", trigger: "blur" }, | 
				
			|||
    { type: "number", message: "验证码必须是数字类型", trigger: "blur" } | 
				
			|||
  ] | 
				
			|||
}); | 
				
			|||
 | 
				
			|||
// 点击登录或注册 | 
				
			|||
const onBehavior = (evt: Object): void => { | 
				
			|||
  // @ts-expect-error | 
				
			|||
  instance.refs.ruleForm.validate((valid: boolean) => { | 
				
			|||
    if (valid) { | 
				
			|||
      emit("onBehavior", evt); | 
				
			|||
    } else { | 
				
			|||
      return false; | 
				
			|||
    } | 
				
			|||
  }); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 刷新验证码 | 
				
			|||
const refreshVerify = (): void => { | 
				
			|||
  emit("refreshVerify"); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 表单重置 | 
				
			|||
const resetForm = (): void => { | 
				
			|||
  // @ts-expect-error | 
				
			|||
  instance.refs.ruleForm.resetFields(); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
// 登录、注册页面切换 | 
				
			|||
const changPage = (): void => { | 
				
			|||
  tips.value === "注册" ? router.push("/register") : router.push("/login"); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
const noSecret = (): void => { | 
				
			|||
  storageSession.setItem("info", { | 
				
			|||
    username: "admin", | 
				
			|||
    accessToken: "eyJhbGciOiJIUzUxMiJ9.test" | 
				
			|||
  }); | 
				
			|||
  initRouter("admin").then(() => {}); | 
				
			|||
  router.push("/"); | 
				
			|||
}; | 
				
			|||
</script> | 
				
			|||
 | 
				
			|||
<template> | 
				
			|||
  <div class="info"> | 
				
			|||
    <el-form :model="model" :rules="rules" ref="ruleForm" class="rule-form"> | 
				
			|||
      <el-form-item prop="userName"> | 
				
			|||
        <el-input | 
				
			|||
          clearable | 
				
			|||
          v-model="model.userName" | 
				
			|||
          placeholder="请输入用户名" | 
				
			|||
          prefix-icon="el-icon-user" | 
				
			|||
        ></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item prop="passWord"> | 
				
			|||
        <el-input | 
				
			|||
          clearable | 
				
			|||
          type="password" | 
				
			|||
          show-password | 
				
			|||
          v-model="model.passWord" | 
				
			|||
          placeholder="请输入密码" | 
				
			|||
          prefix-icon="el-icon-lock" | 
				
			|||
        ></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item prop="verify"> | 
				
			|||
        <el-input | 
				
			|||
          maxlength="2" | 
				
			|||
          onkeyup="this.value=this.value.replace(/[^\d.]/g,'');" | 
				
			|||
          v-model.number="model.verify" | 
				
			|||
          placeholder="请输入验证码" | 
				
			|||
        ></el-input> | 
				
			|||
        <span | 
				
			|||
          class="verify" | 
				
			|||
          title="刷新" | 
				
			|||
          v-html="model.svg" | 
				
			|||
          @click.prevent="refreshVerify" | 
				
			|||
        ></span> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item> | 
				
			|||
        <el-button type="primary" @click.prevent="onBehavior">{{ | 
				
			|||
          tipsFalse | 
				
			|||
        }}</el-button> | 
				
			|||
        <el-button @click="resetForm">重置</el-button> | 
				
			|||
        <span class="tips" @click="changPage">{{ tips }}</span> | 
				
			|||
      </el-form-item> | 
				
			|||
      <span title="测试用户 直接登录" class="secret" @click="noSecret" | 
				
			|||
        >免密登录</span | 
				
			|||
      > | 
				
			|||
    </el-form> | 
				
			|||
  </div> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<style lang="scss" scoped> | 
				
			|||
.info { | 
				
			|||
  width: 30vw; | 
				
			|||
  height: 48vh; | 
				
			|||
  background: url("../../assets/login.png") no-repeat center; | 
				
			|||
  background-size: cover; | 
				
			|||
  position: absolute; | 
				
			|||
  border-radius: 20px; | 
				
			|||
  right: 100px; | 
				
			|||
  top: 30vh; | 
				
			|||
  display: flex; | 
				
			|||
  justify-content: center; | 
				
			|||
  align-items: center; | 
				
			|||
  @media screen and (max-width: 750px) { | 
				
			|||
    width: 88vw; | 
				
			|||
    right: 25px; | 
				
			|||
    top: 22vh; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .rule-form { | 
				
			|||
    width: 80%; | 
				
			|||
 | 
				
			|||
    .verify { | 
				
			|||
      position: absolute; | 
				
			|||
      margin: -10px 0 0 -120px; | 
				
			|||
 | 
				
			|||
      &:hover { | 
				
			|||
        cursor: pointer; | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    .tips { | 
				
			|||
      color: #409eff; | 
				
			|||
      float: right; | 
				
			|||
 | 
				
			|||
      &:hover { | 
				
			|||
        cursor: pointer; | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .secret { | 
				
			|||
    color: #409eff; | 
				
			|||
 | 
				
			|||
    &:hover { | 
				
			|||
      cursor: pointer; | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</style> | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 极光绿 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #0b1e15; | 
				
			|||
$menuHover: #60ac80; | 
				
			|||
$subMenuBg: #000; | 
				
			|||
$subMenuActiveBg: #60ac80; | 
				
			|||
$navTextColor: #7a80b4; | 
				
			|||
$menuText: #7a80b4; | 
				
			|||
$sidebarLogo: #112f21; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #60ac80; | 
				
			|||
@ -0,0 +1,24 @@ | 
				
			|||
/** | 
				
			|||
*此scss变量文件作为multipleScopeVars去编译时,会自动移除!default以达到变量提升 | 
				
			|||
*同时此scss变量文件作为默认主题变量文件,被其他.scss通过 @import 时,必需 !default | 
				
			|||
*/ | 
				
			|||
 | 
				
			|||
// 暗雅(默认) | 
				
			|||
 | 
				
			|||
// 菜单选中后字体样式 | 
				
			|||
$subMenuActiveText: #fff !default; | 
				
			|||
//菜单背景 | 
				
			|||
$menuBg: #001529 !default; | 
				
			|||
// 鼠标覆盖到菜单时的背景 | 
				
			|||
$menuHover: #4091f7 !default; | 
				
			|||
// 子菜单背景 | 
				
			|||
$subMenuBg: #0f0303 !default; | 
				
			|||
// 有无子集的激活菜单背景 | 
				
			|||
$subMenuActiveBg: #4091f7 !default; | 
				
			|||
$navTextColor: #fff !default; | 
				
			|||
$menuText: rgba(254, 254, 254, 0.65) !default; | 
				
			|||
// logo背景颜色 | 
				
			|||
$sidebarLogo: #002140 !default; | 
				
			|||
// 鼠标覆盖到菜单时的字体颜色 | 
				
			|||
$menuTitleHover: #fff !default; | 
				
			|||
$menuActiveBefore: #4091f7 !default; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 薄暮 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #2a0608; | 
				
			|||
$menuHover: #e13c39; | 
				
			|||
$subMenuBg: #000; | 
				
			|||
$subMenuActiveBg: #e13c39; | 
				
			|||
$navTextColor: red; | 
				
			|||
$menuText: rgba(254, 254, 254, 0.651); | 
				
			|||
$sidebarLogo: #42090c; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #e13c39; | 
				
			|||
@ -0,0 +1,11 @@ | 
				
			|||
// 明亮 | 
				
			|||
$subMenuActiveText: #409eff; | 
				
			|||
$menuBg: #fff; | 
				
			|||
$menuHover: #e0ebf6; | 
				
			|||
$subMenuBg: #fff; | 
				
			|||
$subMenuActiveBg: #e0ebf6; | 
				
			|||
$navTextColor: #7a80b4; | 
				
			|||
$menuText: #7a80b4; | 
				
			|||
$sidebarLogo: #fff; | 
				
			|||
$menuTitleHover: #000; | 
				
			|||
$menuActiveBefore: #4091f7; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 明青 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #032121; | 
				
			|||
$menuHover: #59bfc1; | 
				
			|||
$subMenuBg: #000; | 
				
			|||
$subMenuActiveBg: #59bfc1; | 
				
			|||
$navTextColor: #7a80b4; | 
				
			|||
$menuText: #7a80b4; | 
				
			|||
$sidebarLogo: #053434; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #59bfc1; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 粉红 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #28081a; | 
				
			|||
$menuHover: #d84493; | 
				
			|||
$subMenuBg: #000; | 
				
			|||
$subMenuActiveBg: #d84493; | 
				
			|||
$navTextColor: #7a80b4; | 
				
			|||
$menuText: #7a80b4; | 
				
			|||
$sidebarLogo: #3f0d29; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #d84493; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 酱紫 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #130824; | 
				
			|||
$menuHover: #693ac9; | 
				
			|||
$subMenuBg: #000; | 
				
			|||
$subMenuActiveBg: #693ac9; | 
				
			|||
$navTextColor: #7a80b4; | 
				
			|||
$menuText: #7a80b4; | 
				
			|||
$sidebarLogo: #1f0c38; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #693ac9; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 火山 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #fff; | 
				
			|||
$menuBg: #2b0e05; | 
				
			|||
$menuHover: #e85f33; | 
				
			|||
$subMenuBg: #0f0603; | 
				
			|||
$subMenuActiveBg: #e85f33; | 
				
			|||
$navTextColor: #fff; | 
				
			|||
$menuText: rgba(254, 254, 254, 0.65); | 
				
			|||
$sidebarLogo: #441708; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #e85f33; | 
				
			|||
@ -0,0 +1,12 @@ | 
				
			|||
// 黄色 | 
				
			|||
 | 
				
			|||
$subMenuActiveText: #d25f00; | 
				
			|||
$menuBg: #2b2503; | 
				
			|||
$menuHover: #f6da4d; | 
				
			|||
$subMenuBg: #0f0603; | 
				
			|||
$subMenuActiveBg: #f6da4d; | 
				
			|||
$navTextColor: #fff; | 
				
			|||
$menuText: rgba(254, 254, 254, 0.65); | 
				
			|||
$sidebarLogo: #443b05; | 
				
			|||
$menuTitleHover: #fff; | 
				
			|||
$menuActiveBefore: #f6da4d; | 
				
			|||
@ -1,119 +0,0 @@ | 
				
			|||
import "xe-utils"; | 
				
			|||
import { App } from "vue"; | 
				
			|||
import { i18n } from "../i18n/index"; | 
				
			|||
import "font-awesome/css/font-awesome.css"; | 
				
			|||
import { | 
				
			|||
  // 核心
 | 
				
			|||
  VXETable, | 
				
			|||
 | 
				
			|||
  // 表格功能
 | 
				
			|||
  Header, | 
				
			|||
  Footer, | 
				
			|||
  Icon, | 
				
			|||
  Filter, | 
				
			|||
  Edit, | 
				
			|||
  Menu, | 
				
			|||
  Export, | 
				
			|||
  Keyboard, | 
				
			|||
  Validator, | 
				
			|||
 | 
				
			|||
  // 可选组件
 | 
				
			|||
  Column, | 
				
			|||
  Colgroup, | 
				
			|||
  Grid, | 
				
			|||
  Tooltip, | 
				
			|||
  Toolbar, | 
				
			|||
  Pager, | 
				
			|||
  Form, | 
				
			|||
  FormItem, | 
				
			|||
  FormGather, | 
				
			|||
  Checkbox, | 
				
			|||
  CheckboxGroup, | 
				
			|||
  Radio, | 
				
			|||
  RadioGroup, | 
				
			|||
  RadioButton, | 
				
			|||
  Switch, | 
				
			|||
  Input, | 
				
			|||
  Select, | 
				
			|||
  Optgroup, | 
				
			|||
  Option, | 
				
			|||
  Textarea, | 
				
			|||
  Button, | 
				
			|||
  Modal, | 
				
			|||
  List, | 
				
			|||
  Pulldown, | 
				
			|||
 | 
				
			|||
  // 表格
 | 
				
			|||
  Table | 
				
			|||
} from "vxe-table"; | 
				
			|||
 | 
				
			|||
// 全局默认参数
 | 
				
			|||
VXETable.setup({ | 
				
			|||
  size: "medium", | 
				
			|||
  version: 0, | 
				
			|||
  zIndex: 1002, | 
				
			|||
  table: { | 
				
			|||
    // 自动监听父元素的变化去重新计算表格
 | 
				
			|||
    autoResize: true, | 
				
			|||
    // 鼠标移到行是否要高亮显示
 | 
				
			|||
    highlightHoverRow: true | 
				
			|||
  }, | 
				
			|||
  input: { | 
				
			|||
    clearable: true | 
				
			|||
  }, | 
				
			|||
  // 对组件内置的提示语进行国际化翻译
 | 
				
			|||
  // @ts-ignore
 | 
				
			|||
  i18n: (key, args) => i18n.global.t(key, args), | 
				
			|||
  // 可选,对参数中的列头、校验提示..等进行自动翻译(只对支持国际化的有效)
 | 
				
			|||
  translate(key, args) { | 
				
			|||
    // 例如,只翻译 "message." 开头的键值
 | 
				
			|||
    if (key && key.indexOf("message.") > -1) { | 
				
			|||
      return i18n.global.t(key, args); | 
				
			|||
    } | 
				
			|||
    if (key && key.indexOf("el.") > -1) { | 
				
			|||
      return i18n.global.t(key, args); | 
				
			|||
    } | 
				
			|||
    return key; | 
				
			|||
  } | 
				
			|||
}); | 
				
			|||
 | 
				
			|||
export function useTable(app: App) { | 
				
			|||
  app | 
				
			|||
    .use(Header) | 
				
			|||
    .use(Footer) | 
				
			|||
    .use(Icon) | 
				
			|||
    .use(Filter) | 
				
			|||
    .use(Edit) | 
				
			|||
    .use(Menu) | 
				
			|||
    .use(Export) | 
				
			|||
    .use(Keyboard) | 
				
			|||
    .use(Validator) | 
				
			|||
 | 
				
			|||
    // 可选组件
 | 
				
			|||
    .use(Column) | 
				
			|||
    .use(Colgroup) | 
				
			|||
    .use(Grid) | 
				
			|||
    .use(Tooltip) | 
				
			|||
    .use(Toolbar) | 
				
			|||
    .use(Pager) | 
				
			|||
    .use(Form) | 
				
			|||
    .use(FormItem) | 
				
			|||
    .use(FormGather) | 
				
			|||
    .use(Checkbox) | 
				
			|||
    .use(CheckboxGroup) | 
				
			|||
    .use(Radio) | 
				
			|||
    .use(RadioGroup) | 
				
			|||
    .use(RadioButton) | 
				
			|||
    .use(Switch) | 
				
			|||
    .use(Input) | 
				
			|||
    .use(Select) | 
				
			|||
    .use(Optgroup) | 
				
			|||
    .use(Option) | 
				
			|||
    .use(Textarea) | 
				
			|||
    .use(Button) | 
				
			|||
    .use(Modal) | 
				
			|||
    .use(List) | 
				
			|||
    .use(Pulldown) | 
				
			|||
    // 安装表格
 | 
				
			|||
    .use(Table); | 
				
			|||
} | 
				
			|||
@ -0,0 +1,25 @@ | 
				
			|||
import Layout from "/@/layout/index.vue"; | 
				
			|||
 | 
				
			|||
const externalLink = { | 
				
			|||
  path: "/external", | 
				
			|||
  name: "external", | 
				
			|||
  component: Layout, | 
				
			|||
  meta: { | 
				
			|||
    icon: "Link", | 
				
			|||
    title: "message.externalLink", | 
				
			|||
    showLink: true, | 
				
			|||
    rank: 190 | 
				
			|||
  }, | 
				
			|||
  children: [ | 
				
			|||
    { | 
				
			|||
      path: "https://github.com/xiaoxian521/vue-pure-admin", | 
				
			|||
      meta: { | 
				
			|||
        title: "message.externalLink", | 
				
			|||
        showLink: true, | 
				
			|||
        rank: 191 | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  ] | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
export default externalLink; | 
				
			|||
@ -0,0 +1,227 @@ | 
				
			|||
.wave { | 
				
			|||
  position: fixed; | 
				
			|||
  height: 100%; | 
				
			|||
  left: 0; | 
				
			|||
  bottom: 0; | 
				
			|||
  z-index: -1; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.container { | 
				
			|||
  width: 100vw; | 
				
			|||
  height: 100vh; | 
				
			|||
  display: grid; | 
				
			|||
  grid-template-columns: repeat(2, 1fr); | 
				
			|||
  grid-gap: 18rem; | 
				
			|||
  padding: 0 2rem; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.img { | 
				
			|||
  display: flex; | 
				
			|||
  justify-content: flex-end; | 
				
			|||
  align-items: center; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.img img { | 
				
			|||
  width: 500px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.login-box { | 
				
			|||
  display: flex; | 
				
			|||
  align-items: center; | 
				
			|||
  text-align: center; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.login-form { | 
				
			|||
  width: 360px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.avatar { | 
				
			|||
  width: 350px; | 
				
			|||
  height: 80px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.login-form h2 { | 
				
			|||
  text-transform: uppercase; | 
				
			|||
  margin: 15px 0; | 
				
			|||
  color: #999; | 
				
			|||
  font: bold 200% Consolas, Monaco, monospace; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group { | 
				
			|||
  position: relative; | 
				
			|||
  display: grid; | 
				
			|||
  grid-template-columns: 7% 93%; | 
				
			|||
  margin: 25px 0; | 
				
			|||
  padding: 5px 0; | 
				
			|||
  border-bottom: 2px solid #d9d9d9; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group:nth-child(1) { | 
				
			|||
  margin-bottom: 4px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group::before, | 
				
			|||
.input-group::after { | 
				
			|||
  content: ""; | 
				
			|||
  position: absolute; | 
				
			|||
  bottom: -2px; | 
				
			|||
  width: 0; | 
				
			|||
  height: 2px; | 
				
			|||
  background-color: #c5d3f7; | 
				
			|||
  transition: 0.5s; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group::after { | 
				
			|||
  right: 50%; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group::before { | 
				
			|||
  left: 50%; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.icon { | 
				
			|||
  display: flex; | 
				
			|||
  justify-content: center; | 
				
			|||
  align-items: center; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.icon i { | 
				
			|||
  color: #d9d9d9; | 
				
			|||
  transition: 0.5s; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group > div { | 
				
			|||
  position: relative; | 
				
			|||
  height: 45px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group > div > h5 { | 
				
			|||
  position: absolute; | 
				
			|||
  left: 10px; | 
				
			|||
  top: 50%; | 
				
			|||
  transform: translateY(-50%); | 
				
			|||
  color: #d9d9d9; | 
				
			|||
  font-size: 18px; | 
				
			|||
  transition: 0.3s; | 
				
			|||
  margin: 0; | 
				
			|||
  padding: 0; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group.focus .icon i { | 
				
			|||
  color: #5392f0; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group.focus div h5 { | 
				
			|||
  top: -5px; | 
				
			|||
  font-size: 15px; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input-group.focus::after, | 
				
			|||
.input-group.focus::before { | 
				
			|||
  width: 50%; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.input { | 
				
			|||
  position: absolute; | 
				
			|||
  width: 100%; | 
				
			|||
  height: 100%; | 
				
			|||
  top: 0; | 
				
			|||
  left: 0; | 
				
			|||
  border: none; | 
				
			|||
  outline: none; | 
				
			|||
  background: none; | 
				
			|||
  padding: 0.5rem 0.7rem; | 
				
			|||
  font-size: 1.2rem; | 
				
			|||
  color: #555; | 
				
			|||
  font-family: "Roboto", sans-serif; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
a { | 
				
			|||
  display: block; | 
				
			|||
  text-align: right; | 
				
			|||
  text-decoration: none; | 
				
			|||
  color: #999; | 
				
			|||
  font-size: 0.9rem; | 
				
			|||
  transition: 0.3s; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
a:hover { | 
				
			|||
  color: #5392f0; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.btn { | 
				
			|||
  display: block; | 
				
			|||
  width: 100%; | 
				
			|||
  height: 50px; | 
				
			|||
  border-radius: 25px; | 
				
			|||
  margin: 1rem 0; | 
				
			|||
  font-size: 1.2rem; | 
				
			|||
  outline: none; | 
				
			|||
  border: none; | 
				
			|||
  background-image: linear-gradient(to right, #567dbe, #5392f0, #567dbe); | 
				
			|||
  cursor: pointer; | 
				
			|||
  color: #fff; | 
				
			|||
  text-transform: uppercase; | 
				
			|||
  font-family: "Roboto", sans-serif; | 
				
			|||
  background-size: 200%; | 
				
			|||
  transition: 0.5s; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.btn:hover { | 
				
			|||
  background-position: right; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
.copyright { | 
				
			|||
  position: absolute; | 
				
			|||
  width: 100%; | 
				
			|||
  height: 50px; | 
				
			|||
  bottom: 2px; | 
				
			|||
  color: #5392f0; | 
				
			|||
  text-align: center; | 
				
			|||
  font-size: 18px; | 
				
			|||
  font-family: "Roboto", sans-serif; | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@media screen and (max-width: 1080px) { | 
				
			|||
  .container { | 
				
			|||
    grid-gap: 9rem; | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@media screen and (max-width: 1024px) { | 
				
			|||
  .login-form { | 
				
			|||
    width: 290px; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .login-form h2 { | 
				
			|||
    font-size: 2.4rem; | 
				
			|||
    margin: 8px 0; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .img img { | 
				
			|||
    width: 360px; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .avatar { | 
				
			|||
    width: 280px; | 
				
			|||
    height: 80px; | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@media screen and (max-width: 768px) { | 
				
			|||
  .wave { | 
				
			|||
    display: none; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .img { | 
				
			|||
    display: none; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .container { | 
				
			|||
    grid-template-columns: 1fr; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  .login-box { | 
				
			|||
    justify-content: center; | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
@ -1,20 +1,180 @@ | 
				
			|||
<script setup lang="ts"> | 
				
			|||
import { reactive } from "vue"; | 
				
			|||
import info, { ContextProps } from "../components/ReInfo/index.vue"; | 
				
			|||
 | 
				
			|||
const contextInfo: ContextProps = reactive({ | 
				
			|||
  userName: "", | 
				
			|||
  passWord: "", | 
				
			|||
  verify: null, | 
				
			|||
  svg: null | 
				
			|||
import { ref, computed } from "vue"; | 
				
			|||
import { useRouter } from "vue-router"; | 
				
			|||
import { initRouter } from "/@/router"; | 
				
			|||
import { storageSession } from "/@/utils/storage"; | 
				
			|||
import { addClass, removeClass } from "/@/utils/operate"; | 
				
			|||
import bg from "/@/assets/login/bg.png"; | 
				
			|||
import avatar from "/@/assets/login/avatar.svg"; | 
				
			|||
import illustration0 from "/@/assets/login/illustration0.svg"; | 
				
			|||
import illustration1 from "/@/assets/login/illustration1.svg"; | 
				
			|||
import illustration2 from "/@/assets/login/illustration2.svg"; | 
				
			|||
import illustration3 from "/@/assets/login/illustration3.svg"; | 
				
			|||
import illustration4 from "/@/assets/login/illustration4.svg"; | 
				
			|||
import illustration5 from "/@/assets/login/illustration5.svg"; | 
				
			|||
import illustration6 from "/@/assets/login/illustration6.svg"; | 
				
			|||
 | 
				
			|||
const router = useRouter(); | 
				
			|||
 | 
				
			|||
// eslint-disable-next-line vue/return-in-computed-property | 
				
			|||
const currentWeek = computed(() => { | 
				
			|||
  switch (String(new Date().getDay())) { | 
				
			|||
    case "0": | 
				
			|||
      return illustration0; | 
				
			|||
    case "1": | 
				
			|||
      return illustration1; | 
				
			|||
    case "2": | 
				
			|||
      return illustration2; | 
				
			|||
    case "3": | 
				
			|||
      return illustration3; | 
				
			|||
    case "4": | 
				
			|||
      return illustration4; | 
				
			|||
    case "5": | 
				
			|||
      return illustration5; | 
				
			|||
    case "6": | 
				
			|||
      return illustration6; | 
				
			|||
    default: | 
				
			|||
      return illustration4; | 
				
			|||
  } | 
				
			|||
}); | 
				
			|||
 | 
				
			|||
// 登录 | 
				
			|||
const onLogin = () => {}; | 
				
			|||
let user = ref("admin"); | 
				
			|||
let pwd = ref("123456"); | 
				
			|||
 | 
				
			|||
const onLogin = (): void => { | 
				
			|||
  storageSession.setItem("info", { | 
				
			|||
    username: "admin", | 
				
			|||
    accessToken: "eyJhbGciOiJIUzUxMiJ9.test" | 
				
			|||
  }); | 
				
			|||
  initRouter("admin").then(() => {}); | 
				
			|||
  router.push("/"); | 
				
			|||
}; | 
				
			|||
 | 
				
			|||
function onUserFocus() { | 
				
			|||
  addClass(document.querySelector(".user"), "focus"); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function onUserBlur() { | 
				
			|||
  if (user.value.length === 0) | 
				
			|||
    removeClass(document.querySelector(".user"), "focus"); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function onPwdFocus() { | 
				
			|||
  addClass(document.querySelector(".pwd"), "focus"); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
function onPwdBlur() { | 
				
			|||
  if (pwd.value.length === 0) | 
				
			|||
    removeClass(document.querySelector(".pwd"), "focus"); | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
 | 
				
			|||
<template> | 
				
			|||
  <div class="login"> | 
				
			|||
    <info :ruleForm="contextInfo" @on-behavior="onLogin" /> | 
				
			|||
  <img :src="bg" class="wave" /> | 
				
			|||
  <div class="container"> | 
				
			|||
    <div class="img"> | 
				
			|||
      <component :is="currentWeek"></component> | 
				
			|||
    </div> | 
				
			|||
    <div class="login-box"> | 
				
			|||
      <div class="login-form"> | 
				
			|||
        <avatar class="avatar" /> | 
				
			|||
        <h2 | 
				
			|||
          v-motion | 
				
			|||
          :initial="{ | 
				
			|||
            opacity: 0, | 
				
			|||
            y: 100 | 
				
			|||
          }" | 
				
			|||
          :enter="{ | 
				
			|||
            opacity: 1, | 
				
			|||
            y: 0, | 
				
			|||
            transition: { | 
				
			|||
              delay: 100 | 
				
			|||
            } | 
				
			|||
          }" | 
				
			|||
        > | 
				
			|||
          Pure Admin | 
				
			|||
        </h2> | 
				
			|||
        <div | 
				
			|||
          class="input-group user focus" | 
				
			|||
          v-motion | 
				
			|||
          :initial="{ | 
				
			|||
            opacity: 0, | 
				
			|||
            y: 100 | 
				
			|||
          }" | 
				
			|||
          :enter="{ | 
				
			|||
            opacity: 1, | 
				
			|||
            y: 0, | 
				
			|||
            transition: { | 
				
			|||
              delay: 200 | 
				
			|||
            } | 
				
			|||
          }" | 
				
			|||
        > | 
				
			|||
          <div class="icon"> | 
				
			|||
            <i class="fa fa-user"></i> | 
				
			|||
          </div> | 
				
			|||
          <div> | 
				
			|||
            <h5>用户名</h5> | 
				
			|||
            <input | 
				
			|||
              type="text" | 
				
			|||
              class="input" | 
				
			|||
              v-model="user" | 
				
			|||
              @focus="onUserFocus" | 
				
			|||
              @blur="onUserBlur" | 
				
			|||
            /> | 
				
			|||
          </div> | 
				
			|||
        </div> | 
				
			|||
        <div | 
				
			|||
          class="input-group pwd focus" | 
				
			|||
          v-motion | 
				
			|||
          :initial="{ | 
				
			|||
            opacity: 0, | 
				
			|||
            y: 100 | 
				
			|||
          }" | 
				
			|||
          :enter="{ | 
				
			|||
            opacity: 1, | 
				
			|||
            y: 0, | 
				
			|||
            transition: { | 
				
			|||
              delay: 300 | 
				
			|||
            } | 
				
			|||
          }" | 
				
			|||
        > | 
				
			|||
          <div class="icon"> | 
				
			|||
            <i class="fa fa-lock"></i> | 
				
			|||
          </div> | 
				
			|||
          <div> | 
				
			|||
            <h5>密码</h5> | 
				
			|||
            <input | 
				
			|||
              type="password" | 
				
			|||
              class="input" | 
				
			|||
              v-model="pwd" | 
				
			|||
              @focus="onPwdFocus" | 
				
			|||
              @blur="onPwdBlur" | 
				
			|||
            /> | 
				
			|||
          </div> | 
				
			|||
        </div> | 
				
			|||
        <button | 
				
			|||
          class="btn" | 
				
			|||
          v-motion | 
				
			|||
          :initial="{ | 
				
			|||
            opacity: 0, | 
				
			|||
            y: 10 | 
				
			|||
          }" | 
				
			|||
          :enter="{ | 
				
			|||
            opacity: 1, | 
				
			|||
            y: 0, | 
				
			|||
            transition: { | 
				
			|||
              delay: 400 | 
				
			|||
            } | 
				
			|||
          }" | 
				
			|||
          @click="onLogin" | 
				
			|||
        > | 
				
			|||
          登录 | 
				
			|||
        </button> | 
				
			|||
      </div> | 
				
			|||
    </div> | 
				
			|||
  </div> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<style scoped> | 
				
			|||
@import url("/@/style/login.css"); | 
				
			|||
</style> | 
				
			|||
@ -1,17 +0,0 @@ | 
				
			|||
<script setup lang="ts"> | 
				
			|||
import { reactive } from "vue"; | 
				
			|||
import info, { ContextProps } from "../components/ReInfo/index.vue"; | 
				
			|||
 | 
				
			|||
const contextInfo: ContextProps = reactive({ | 
				
			|||
  userName: "", | 
				
			|||
  passWord: "", | 
				
			|||
  verify: null, | 
				
			|||
  svg: null | 
				
			|||
}); | 
				
			|||
</script> | 
				
			|||
 | 
				
			|||
<template> | 
				
			|||
  <div class="register"> | 
				
			|||
    <info :ruleForm="contextInfo" /> | 
				
			|||
  </div> | 
				
			|||
</template> | 
				
			|||