mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: 初始化基本配置
This commit is contained in:
parent
64e93679f8
commit
5511769673
|
|
@ -1,3 +1,4 @@
|
|||
VITE_APP_NAME=ui
|
||||
VITE_BASE_PATH=/ui/
|
||||
VITE_APP_PORT=3000
|
||||
VITE_APP_PORT=3000
|
||||
VITE_APP_TITLE = '智能知识库'
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
<title>%VITE_APP_TITLE%</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"element-plus": "^2.3.7",
|
||||
"element-plus": "^2.3.14",
|
||||
"lodash": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.6",
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
"prettier": "^3.0.0",
|
||||
"sass": "^1.66.1",
|
||||
"typescript": "~5.1.6",
|
||||
"unplugin-vue-define-options": "^1.3.18",
|
||||
"vite": "^4.4.9",
|
||||
"vitest": "^0.34.2",
|
||||
"vue-tsc": "^1.8.8"
|
||||
|
|
@ -48,6 +49,24 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.15.tgz",
|
||||
|
|
@ -59,6 +78,20 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.23.0.tgz",
|
||||
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||
|
|
@ -290,6 +323,28 @@
|
|||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
|
||||
"integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz",
|
||||
|
|
@ -332,6 +387,12 @@
|
|||
"@types/chai": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.2.tgz",
|
||||
"integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/jsdom": {
|
||||
"version": "21.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.2.tgz",
|
||||
|
|
@ -714,6 +775,31 @@
|
|||
"@volar/language-core": "1.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue-macros/common": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vue-macros/common/-/common-1.8.0.tgz",
|
||||
"integrity": "sha512-auDJJzE0z3uRe3867e0DsqcseKImktNf5ojCZgUKqiVxb2yTlwlgOVAYCgoep9oITqxkXQymSvFeKhedi8PhaA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.22.17",
|
||||
"@rollup/pluginutils": "^5.0.4",
|
||||
"@vue/compiler-sfc": "^3.3.4",
|
||||
"ast-kit": "^0.11.2",
|
||||
"local-pkg": "^0.4.3",
|
||||
"magic-string-ast": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.7.0 || ^3.2.25"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
|
|
@ -1189,6 +1275,47 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-kit": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmmirror.com/ast-kit/-/ast-kit-0.11.2.tgz",
|
||||
"integrity": "sha512-Q0DjXK4ApbVoIf9GLyCo252tUH44iTnD/hiJ2TQaJeydYWSpKk0sI34+WMel8S9Wt5pbLgG02oJ+gkgX5DV3sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.22.14",
|
||||
"@rollup/pluginutils": "^5.0.4",
|
||||
"pathe": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-walker-scope": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/ast-walker-scope/-/ast-walker-scope-0.5.0.tgz",
|
||||
"integrity": "sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.22.7",
|
||||
"ast-kit": "^0.9.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-walker-scope/node_modules/ast-kit": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmmirror.com/ast-kit/-/ast-kit-0.9.5.tgz",
|
||||
"integrity": "sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.22.7",
|
||||
"@rollup/pluginutils": "^5.0.2",
|
||||
"pathe": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/async-validator": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||
|
|
@ -1733,9 +1860,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/element-plus": {
|
||||
"version": "2.3.12",
|
||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.12.tgz",
|
||||
"integrity": "sha512-fAWpbKCyt+l1dsqSNPOs/F/dBN4Wp5CGAyxbiS5zqDwI4q3QPM+LxLU2h3GUHMIBtMGCvmsG98j5HPMkTKkvcA==",
|
||||
"version": "2.3.14",
|
||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.14.tgz",
|
||||
"integrity": "sha512-9yvxUaU4jXf2ZNPdmIxoj/f8BG8CDcGM6oHa9JIqxLjQlfY4bpzR1E5CjNimnOX3rxO93w1TQ0jTVt0RSxh9kA==",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"@element-plus/icons-vue": "^2.0.6",
|
||||
|
|
@ -3378,6 +3505,18 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string-ast": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/magic-string-ast/-/magic-string-ast-0.3.0.tgz",
|
||||
"integrity": "sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"magic-string": "^0.30.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
|
|
@ -4945,6 +5084,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
|
@ -5152,6 +5300,32 @@
|
|||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.5.0.tgz",
|
||||
"integrity": "sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.10.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"webpack-sources": "^3.2.3",
|
||||
"webpack-virtual-modules": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-vue-define-options": {
|
||||
"version": "1.3.18",
|
||||
"resolved": "https://registry.npmmirror.com/unplugin-vue-define-options/-/unplugin-vue-define-options-1.3.18.tgz",
|
||||
"integrity": "sha512-AaE10FCccfezT48yyYuUXdnTF9z8vQuXrlpNF5uQtq/AOD2pdkf38vnmJm8bJjpoqEkR6u72wNCJLZKXSUw+Og==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue-macros/common": "1.8.0",
|
||||
"ast-walker-scope": "^0.5.0",
|
||||
"unplugin": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/untildify": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
|
||||
|
|
@ -5480,6 +5654,21 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-virtual-modules": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
|
||||
"integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/whatwg-encoding": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
|
||||
|
|
@ -5648,11 +5837,34 @@
|
|||
"integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helper-string-parser": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.22.15",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.15.tgz",
|
||||
"integrity": "sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.23.0.tgz",
|
||||
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.22.5",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@ctrl/tinycolor": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||
|
|
@ -5819,6 +6031,17 @@
|
|||
"resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
|
||||
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
|
||||
},
|
||||
"@rollup/pluginutils": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz",
|
||||
"integrity": "sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@rushstack/eslint-patch": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz",
|
||||
|
|
@ -5858,6 +6081,12 @@
|
|||
"@types/chai": "*"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.2.tgz",
|
||||
"integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/jsdom": {
|
||||
"version": "21.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.2.tgz",
|
||||
|
|
@ -6120,6 +6349,20 @@
|
|||
"@volar/language-core": "1.10.1"
|
||||
}
|
||||
},
|
||||
"@vue-macros/common": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vue-macros/common/-/common-1.8.0.tgz",
|
||||
"integrity": "sha512-auDJJzE0z3uRe3867e0DsqcseKImktNf5ojCZgUKqiVxb2yTlwlgOVAYCgoep9oITqxkXQymSvFeKhedi8PhaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.22.17",
|
||||
"@rollup/pluginutils": "^5.0.4",
|
||||
"@vue/compiler-sfc": "^3.3.4",
|
||||
"ast-kit": "^0.11.2",
|
||||
"local-pkg": "^0.4.3",
|
||||
"magic-string-ast": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
|
|
@ -6466,6 +6709,40 @@
|
|||
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
|
||||
"dev": true
|
||||
},
|
||||
"ast-kit": {
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmmirror.com/ast-kit/-/ast-kit-0.11.2.tgz",
|
||||
"integrity": "sha512-Q0DjXK4ApbVoIf9GLyCo252tUH44iTnD/hiJ2TQaJeydYWSpKk0sI34+WMel8S9Wt5pbLgG02oJ+gkgX5DV3sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.22.14",
|
||||
"@rollup/pluginutils": "^5.0.4",
|
||||
"pathe": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"ast-walker-scope": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/ast-walker-scope/-/ast-walker-scope-0.5.0.tgz",
|
||||
"integrity": "sha512-NsyHMxBh4dmdEHjBo1/TBZvCKxffmZxRYhmclfu0PP6Aftre47jOHYaYaNqJcV0bxihxFXhDkzLHUwHc0ocd0Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.22.7",
|
||||
"ast-kit": "^0.9.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ast-kit": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmmirror.com/ast-kit/-/ast-kit-0.9.5.tgz",
|
||||
"integrity": "sha512-kbL7ERlqjXubdDd+szuwdlQ1xUxEz9mCz1+m07ftNVStgwRb2RWw+U6oKo08PAvOishMxiqz1mlJyLl8yQx2Qg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.22.7",
|
||||
"@rollup/pluginutils": "^5.0.2",
|
||||
"pathe": "^1.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"async-validator": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||
|
|
@ -6869,9 +7146,9 @@
|
|||
}
|
||||
},
|
||||
"element-plus": {
|
||||
"version": "2.3.12",
|
||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.3.12.tgz",
|
||||
"integrity": "sha512-fAWpbKCyt+l1dsqSNPOs/F/dBN4Wp5CGAyxbiS5zqDwI4q3QPM+LxLU2h3GUHMIBtMGCvmsG98j5HPMkTKkvcA==",
|
||||
"version": "2.3.14",
|
||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.14.tgz",
|
||||
"integrity": "sha512-9yvxUaU4jXf2ZNPdmIxoj/f8BG8CDcGM6oHa9JIqxLjQlfY4bpzR1E5CjNimnOX3rxO93w1TQ0jTVt0RSxh9kA==",
|
||||
"requires": {
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"@element-plus/icons-vue": "^2.0.6",
|
||||
|
|
@ -8064,6 +8341,15 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
}
|
||||
},
|
||||
"magic-string-ast": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/magic-string-ast/-/magic-string-ast-0.3.0.tgz",
|
||||
"integrity": "sha512-0shqecEPgdFpnI3AP90epXyxZy9g6CRZ+SZ7BcqFwYmtFEnZ1jpevcV5HoyVnlDS9gCnc1UIg3Rsvp3Ci7r8OA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"magic-string": "^0.30.2"
|
||||
}
|
||||
},
|
||||
"memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
|
|
@ -9164,6 +9450,12 @@
|
|||
"integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"dev": true
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
|
@ -9315,6 +9607,29 @@
|
|||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||
"dev": true
|
||||
},
|
||||
"unplugin": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.5.0.tgz",
|
||||
"integrity": "sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^8.10.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"webpack-sources": "^3.2.3",
|
||||
"webpack-virtual-modules": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"unplugin-vue-define-options": {
|
||||
"version": "1.3.18",
|
||||
"resolved": "https://registry.npmmirror.com/unplugin-vue-define-options/-/unplugin-vue-define-options-1.3.18.tgz",
|
||||
"integrity": "sha512-AaE10FCccfezT48yyYuUXdnTF9z8vQuXrlpNF5uQtq/AOD2pdkf38vnmJm8bJjpoqEkR6u72wNCJLZKXSUw+Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue-macros/common": "1.8.0",
|
||||
"ast-walker-scope": "^0.5.0",
|
||||
"unplugin": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"untildify": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
|
||||
|
|
@ -9509,6 +9824,18 @@
|
|||
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
|
||||
"dev": true
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true
|
||||
},
|
||||
"webpack-virtual-modules": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz",
|
||||
"integrity": "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==",
|
||||
"dev": true
|
||||
},
|
||||
"whatwg-encoding": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"element-plus": "^2.3.7",
|
||||
"element-plus": "^2.3.14",
|
||||
"lodash": "^4.17.21",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.6",
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
"prettier": "^3.0.0",
|
||||
"sass": "^1.66.1",
|
||||
"typescript": "~5.1.6",
|
||||
"unplugin-vue-define-options": "^1.3.18",
|
||||
"vite": "^4.4.9",
|
||||
"vitest": "^0.34.2",
|
||||
"vue-tsc": "^1.8.8"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
|
|||
const userStore = useUserStore(store)
|
||||
const permissions = userStore.getPermissions()
|
||||
const role = userStore.getRole()
|
||||
if (!permission) {
|
||||
return true
|
||||
}
|
||||
if (permission instanceof Role) {
|
||||
return role === permission.role
|
||||
}
|
||||
|
|
@ -24,6 +27,7 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
|
|||
if (typeof permission === 'string') {
|
||||
return permissions.includes(permission)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { iconMap } from "@/components/icons/index"
|
||||
defineOptions({ name: 'AppIcon' });
|
||||
withDefaults(defineProps<{
|
||||
iconName?: string;
|
||||
}>(), {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import { type App } from 'vue'
|
||||
import AppIcon from './icons/AppIcon.vue'
|
||||
import LoginLayout from './layout/login-layout/index.vue'
|
||||
import LoginContainer from './layout/login-container/index.vue'
|
||||
|
||||
export default {
|
||||
install(app: App) {
|
||||
app.component(AppIcon.name, AppIcon)
|
||||
app.component(LoginLayout.name, LoginLayout)
|
||||
app.component(LoginContainer.name, LoginContainer)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<div class="login-form-container">
|
||||
<div class="login-title">
|
||||
<div class="title flex-center">
|
||||
<div class="logo"></div>
|
||||
<div>{{ title || defaultTitle }}</div>
|
||||
</div>
|
||||
<div class="sub-title" v-if="subTitle">{{ subTitle }}</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
const defaultTitle = import.meta.env.VITE_APP_TITLE
|
||||
defineOptions({ name: 'LoginContainer' })
|
||||
defineProps({
|
||||
title: String,
|
||||
subTitle: String
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.login-form-container {
|
||||
width: 420px;
|
||||
|
||||
.login-title {
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #101010;
|
||||
height: 60px;
|
||||
.logo {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
text-align: center;
|
||||
color: #101010;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,66 +1,48 @@
|
|||
<template>
|
||||
<div class="login-warp">
|
||||
<div class="login-container">
|
||||
<el-row class="container">
|
||||
<el-col :span="14" class="left-container">
|
||||
<div class="login-image"></div>
|
||||
</el-col>
|
||||
<el-col :span="10" class="right-container">
|
||||
<slot></slot>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div class="login-warp flex-center">
|
||||
<div class="login-container w-full h-full">
|
||||
<el-row class="container w-full h-full">
|
||||
<el-col
|
||||
:xs="8"
|
||||
:sm="6"
|
||||
:md="14"
|
||||
:lg="14"
|
||||
:xl="14"
|
||||
class="left-container"
|
||||
v-if="screenWidth && screenWidth >= 990"
|
||||
>
|
||||
<div class="login-image"></div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="10" :lg="10" :xl="10" class="right-container flex-center">
|
||||
<slot></slot>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
defineOptions({ name: 'LoginLayout' })
|
||||
const screenWidth: Ref<number | null> = ref(null)
|
||||
onMounted(() => {
|
||||
screenWidth.value = document.body.clientWidth
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
screenWidth.value = document.body.clientWidth
|
||||
})()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.login-warp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
height: 100%;
|
||||
height: 100vh;
|
||||
|
||||
.login-image {
|
||||
background: url(@/assets/login.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
|
||||
.login-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.right-container {
|
||||
display: flex;
|
||||
margin-top: 20vh;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.left-container {
|
||||
.login-image {
|
||||
background-image: url('@/assets/login.png');
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="top-bar-container">
|
||||
<div class="app-title-container">
|
||||
<div class="app-title-icon"></div>
|
||||
<div class="app-title-text">智能客服</div>
|
||||
<div class="app-title-text">{{ defaultTitle }}</div>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="app-top-menu-container">
|
||||
|
|
@ -15,8 +15,9 @@
|
|||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TopMenu from "@/components/layout/top-bar/components/top-menu/index.vue"
|
||||
import Avatar from "@/components/layout/top-bar/components/avatar/index.vue"
|
||||
import TopMenu from '@/components/layout/top-bar/components/top-menu/index.vue'
|
||||
import Avatar from '@/components/layout/top-bar/components/avatar/index.vue'
|
||||
const defaultTitle = import.meta.env.VITE_APP_TITLE
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.top-bar-container {
|
||||
|
|
@ -46,20 +47,18 @@ import Avatar from "@/components/layout/top-bar/components/avatar/index.vue"
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.app-title-icon {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.app-title-text {
|
||||
color: var(--app-base-action-text-color);
|
||||
font-size: 28px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.line {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { hasPermission } from '@/common/permission'
|
|||
|
||||
const display = async (el: any, binding: any) => {
|
||||
const has = hasPermission(
|
||||
binding.value.permission ? binding.value.permission : binding.value,
|
||||
binding.value.compare ? binding.value.compare : 'OR'
|
||||
binding.value?.permission || binding.value,
|
||||
binding.value?.compare || 'OR'
|
||||
)
|
||||
if (!has) {
|
||||
el.style.display = 'none'
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
import 'nprogress/nprogress.css'
|
||||
import '@/styles/index.scss'
|
||||
import ElementPlus from 'element-plus'
|
||||
import * as ElementPlusIcons from '@element-plus/icons-vue'
|
||||
import 'element-plus/dist/index.css'
|
||||
import { createApp } from 'vue'
|
||||
import { store } from '@/stores'
|
||||
import theme from '@/theme'
|
||||
import directives from '@/directives'
|
||||
import App from './App.vue'
|
||||
import router from '@/router'
|
||||
import Components from '@/components'
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(store)
|
||||
app.use(directives)
|
||||
const ElementPlusIconsVue: object = ElementPlusIcons
|
||||
// 将elementIcon放到全局
|
||||
app.config.globalProperties.$antIcons = ElementPlusIconsVue
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIcons)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
app.use(ElementPlus)
|
||||
|
||||
app.use(theme)
|
||||
|
||||
app.use(router)
|
||||
|
||||
app.use(Components)
|
||||
app.mount('#app')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('@/views/home/index.vue'),
|
||||
component: () => import('@/components/layout/home-layout/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/first',
|
||||
|
|
@ -27,7 +27,7 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
{
|
||||
path: '/setting',
|
||||
name: 'setting',
|
||||
meta: { icon: 'setting', title: '数据设置', permission: 'SETTING:READ' },
|
||||
meta: { icon: 'setting', title: '系统设置', permission: 'SETTING:READ' },
|
||||
component: () => import('@/views/setting/index.vue')
|
||||
}
|
||||
]
|
||||
|
|
@ -40,17 +40,17 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
{
|
||||
path: '/register',
|
||||
name: 'register',
|
||||
component: () => import('@/views/register/index.vue')
|
||||
component: () => import('@/views/login/register/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/forgot_password',
|
||||
name: 'forgot_password',
|
||||
component: () => import('@/views/forgot-password/index.vue')
|
||||
component: () => import('@/views/login/forgot-password/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/reset_password/:code/:email',
|
||||
name: 'reset_password',
|
||||
component: () => import('@/views/reset-password/index.vue')
|
||||
component: () => import('@/views/login/reset-password/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)',
|
||||
|
|
|
|||
|
|
@ -1,10 +1,19 @@
|
|||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Helvetica, PingFang SC, Arial, sans-serif;
|
||||
font-family:
|
||||
Helvetica,
|
||||
PingFang SC,
|
||||
Arial,
|
||||
sans-serif;
|
||||
font-size: 14px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
|
@ -15,7 +24,7 @@ body {
|
|||
}
|
||||
|
||||
#app {
|
||||
height:100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:focus {
|
||||
|
|
@ -34,6 +43,16 @@ a:hover {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
div:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// 滚动条整体部分
|
||||
::-webkit-scrollbar {
|
||||
width: 6px; // 纵向滚动条宽度
|
||||
|
|
@ -52,30 +71,68 @@ a:hover {
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mt-1 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.mr-1 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mb-1 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.mb-2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 创建表单
|
||||
.create-catalog-container {
|
||||
height: 100%;
|
||||
margin-top: -20px;
|
||||
.padding-top-30{
|
||||
padding-top:30px;
|
||||
.padding-top-30 {
|
||||
padding-top: 30px;
|
||||
}
|
||||
.padding-top-40{
|
||||
padding-top:40px;
|
||||
.padding-top-40 {
|
||||
padding-top: 40px;
|
||||
}
|
||||
// 表单外套
|
||||
.form-div{
|
||||
.form-div {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
width: 80%;
|
||||
min-width: 300px;
|
||||
form{
|
||||
.el-form-item {margin-bottom: 28px;}
|
||||
label{
|
||||
form {
|
||||
.el-form-item {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
label {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #1F2329;
|
||||
color: #1f2329;
|
||||
flex: none;
|
||||
order: 0;
|
||||
flex-grow: 0;
|
||||
|
|
@ -84,13 +141,13 @@ a:hover {
|
|||
}
|
||||
|
||||
// 删除按钮样式
|
||||
.delete-button-class{
|
||||
.delete-button-class {
|
||||
cursor: pointer;
|
||||
color: #646a73
|
||||
color: #646a73;
|
||||
}
|
||||
|
||||
// 添加按钮样式
|
||||
.add-button-class{
|
||||
.add-button-class {
|
||||
cursor: pointer;
|
||||
border: 0 solid;
|
||||
//width: 105px;
|
||||
|
|
@ -102,23 +159,22 @@ a:hover {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
letter-spacing: -0.1px;
|
||||
color: #3370FF;
|
||||
.span-class{
|
||||
vertical-align:2px;
|
||||
color: #3370FF;
|
||||
padding-left: 5px
|
||||
color: #3370ff;
|
||||
.span-class {
|
||||
vertical-align: 2px;
|
||||
color: #3370ff;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
button{
|
||||
button {
|
||||
height: 32px;
|
||||
min-width: 80px
|
||||
min-width: 80px;
|
||||
}
|
||||
.save-btn{
|
||||
background-color: #3370FF;
|
||||
.save-btn {
|
||||
background-color: #3370ff;
|
||||
}
|
||||
.cancel-btn{
|
||||
|
||||
.cancel-btn {
|
||||
}
|
||||
|
||||
// 下方操作按钮区域
|
||||
|
|
@ -159,70 +215,65 @@ a:hover {
|
|||
}
|
||||
|
||||
// 自定义弹出框样式
|
||||
.custom-dialog{
|
||||
.custom-dialog {
|
||||
//标题样式
|
||||
.el-dialog__header{
|
||||
.el-dialog__header {
|
||||
padding: 24px !important;
|
||||
}
|
||||
//关闭按钮样式
|
||||
.el-dialog__headerbtn .el-dialog__close{
|
||||
.el-dialog__headerbtn .el-dialog__close {
|
||||
height: auto !important;
|
||||
color: #646A73 !important;
|
||||
color: #646a73 !important;
|
||||
font-size: x-large !important;
|
||||
}
|
||||
.el-dialog__headerbtn .el-dialog__close:hover{
|
||||
.el-dialog__headerbtn .el-dialog__close:hover {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
//内容间距
|
||||
.el-dialog__body{
|
||||
.el-dialog__body {
|
||||
padding: 0px 24px 0px 24px;
|
||||
}
|
||||
.el-dialog__footer{
|
||||
.el-dialog__footer {
|
||||
padding-bottom: 29px !important;
|
||||
}
|
||||
//下方按钮
|
||||
.footer-btn{
|
||||
button{
|
||||
.footer-btn {
|
||||
button {
|
||||
height: 32px;
|
||||
min-width: 80px
|
||||
min-width: 80px;
|
||||
}
|
||||
.save-btn{
|
||||
background-color: #3370FF;
|
||||
.save-btn {
|
||||
background-color: #3370ff;
|
||||
}
|
||||
.cancel-btn{
|
||||
|
||||
.cancel-btn {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-radio-group.el-radio-group{
|
||||
border: 1px solid #BBBFC4;
|
||||
.custom-radio-group.el-radio-group {
|
||||
border: 1px solid #bbbfc4;
|
||||
border-radius: 5px;
|
||||
height: 30px;
|
||||
label{
|
||||
label {
|
||||
border: 0px solid;
|
||||
padding: 2px 10px 2px 4px;
|
||||
}
|
||||
.el-radio-button__inner{
|
||||
.el-radio-button__inner {
|
||||
padding: 4px;
|
||||
border: 0px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.el-radio-button{
|
||||
.el-radio-button {
|
||||
height: auto;
|
||||
}
|
||||
.el-radio-button is-active{
|
||||
.el-radio-button is-active {
|
||||
height: auto;
|
||||
}
|
||||
.el-radio-button__original-radio:checked + .el-radio-button__inner{
|
||||
color: #3370FF;
|
||||
.el-radio-button__original-radio:checked + .el-radio-button__inner {
|
||||
color: #3370ff;
|
||||
border: 0;
|
||||
box-shadow: 0 0 0 0;
|
||||
background: rgba(51, 112, 255, 0.1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
|
||||
// 抽屉样式整体修改
|
||||
.el-drawer{
|
||||
|
||||
.el-drawer__header{
|
||||
padding: 0;
|
||||
margin: 0 24px;
|
||||
height: 56px;
|
||||
border-bottom: 1px solid #D5D6D8;
|
||||
.el-drawer__title {
|
||||
color: #1f2329;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
}
|
||||
.el-drawer__body{
|
||||
--el-drawer-padding-primary:24px
|
||||
}
|
||||
}
|
||||
|
|
@ -5,4 +5,24 @@
|
|||
.el-form {
|
||||
--el-form-inline-content-width: 100%;
|
||||
}
|
||||
|
||||
|
||||
// 抽屉样式整体修改
|
||||
.el-drawer{
|
||||
|
||||
.el-drawer__header{
|
||||
padding: 0;
|
||||
margin: 0 24px;
|
||||
height: 56px;
|
||||
border-bottom: 1px solid #D5D6D8;
|
||||
.el-drawer__title {
|
||||
color: #1f2329;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
}
|
||||
.el-drawer__body{
|
||||
--el-drawer-padding-primary:24px
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
@use "./variables/index.scss";
|
||||
@use "./app.scss";
|
||||
@use "./element-plus.scss";
|
||||
@use "./drawer.scss";
|
||||
|
||||
@import 'element-plus/dist/index.css';
|
||||
@import './variables.scss';
|
||||
@import './app.scss';
|
||||
@import './element-plus.scss';
|
||||
@import 'nprogress/nprogress.css'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
@mixin flex-row($justify: flex-start, $align: stretch) {
|
||||
display: flex;
|
||||
@if $justify != flex-start {
|
||||
justify-content: $justify;
|
||||
}
|
||||
@if $align != stretch {
|
||||
align-items: $align;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin variant($color, $background-color, $border-color) {
|
||||
color: $color;
|
||||
background-color: $background-color;
|
||||
border-color: $border-color;
|
||||
}
|
||||
|
|
@ -4,4 +4,8 @@
|
|||
--app-base-text-hover-color:rgba(51, 112, 255, 1);
|
||||
--app-base-text-hover-bg-color:rgba(51, 112, 255, 0.1);
|
||||
--app-base-action-text-color:var(--app-base-text-hover-color );
|
||||
/** header 组件 */
|
||||
--app-header-height: 56px;
|
||||
--app-header-padding: 0 20px;
|
||||
--app-header-bg-color: #252b3c;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
:root{
|
||||
--app-header-height: 56px;
|
||||
--app-header-padding: 0 20px;
|
||||
--app-header-bg-color: #252b3c;
|
||||
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
@use "./header.scss";
|
||||
@use "./app.scss";
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
<template>
|
||||
<LoiginLayout>
|
||||
<div class="register-form-container">
|
||||
<div class="register-form-title">
|
||||
<div class="title">
|
||||
<div class="logo"></div>
|
||||
<div>智能客服</div>
|
||||
</div>
|
||||
<div class="sub-title">忘记密码</div>
|
||||
</div>
|
||||
<el-form class="register-form" ref="resetPasswordFormRef" :model="CheckEmailForm" :rules="rules">
|
||||
|
||||
<el-form-item prop="email">
|
||||
<el-input size="large" class="input-item" v-model="CheckEmailForm.email" placeholder="请输入邮箱">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input size="large" class="code-input" v-model="CheckEmailForm.code" placeholder="请输入验证码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Key" />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button size="large" class="send-email-button" @click="sendEmail"
|
||||
:loading="loading">获取验证码</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="register-button" @click="checkCode">立即验证</el-button>
|
||||
<div class="operate-container">
|
||||
<span class="register" @click="router.push('login')">< 返回登陆</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</LoiginLayout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { UserFilled, Key } from '@element-plus/icons-vue'
|
||||
import type {
|
||||
CheckCodeRequest
|
||||
} from "@/api/user/type"
|
||||
import LoiginLayout from "@/components/layout/login-layout/index.vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import UserApi from "@/api/user/index"
|
||||
import { ElMessage } from "element-plus"
|
||||
|
||||
const router = useRouter()
|
||||
const CheckEmailForm = ref<CheckCodeRequest>({
|
||||
email: "",
|
||||
code: "",
|
||||
type: 'reset_password'
|
||||
});
|
||||
|
||||
const resetPasswordFormRef = ref<FormInstance>()
|
||||
const rules = ref<FormRules<CheckCodeRequest>>({
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
|
||||
if ((!emailRegExp.test(value) && value != '')) {
|
||||
callback(new Error('请输入有效邮箱格式!'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入验证码' }
|
||||
]
|
||||
|
||||
})
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const checkCode = () => {
|
||||
resetPasswordFormRef.value?.validate()
|
||||
.then(() => UserApi.checkCode(CheckEmailForm.value, loading))
|
||||
.then(() => router.push({ name: 'reset_password', params: CheckEmailForm.value }))
|
||||
}
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
const sendEmail = () => {
|
||||
resetPasswordFormRef.value?.validateField("email", (v: boolean) => {
|
||||
if (v) {
|
||||
UserApi.sendEmit(CheckEmailForm.value.email, "reset_password", loading)
|
||||
.then(() => {
|
||||
ElMessage.success("发送验证码成功")
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.register-form-container {
|
||||
width: 420px;
|
||||
|
||||
.code-input {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.send-email-button {
|
||||
margin-left: 12px;
|
||||
width: 158px;
|
||||
}
|
||||
|
||||
.register-form-title {
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #101010;
|
||||
height: 60px;
|
||||
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
color: #101010;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.operate-container {
|
||||
margin-top: 12px;
|
||||
color: rgba(51, 112, 255, 1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.register {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.register-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer>
|
||||
<h3 class="mb-2">忘记密码</h3>
|
||||
<el-form
|
||||
class="register-form"
|
||||
ref="resetPasswordFormRef"
|
||||
:model="CheckEmailForm"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item prop="email">
|
||||
<el-input
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="CheckEmailForm.email"
|
||||
placeholder="请输入邮箱"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<div class="flex-between w-full">
|
||||
<el-input
|
||||
size="large"
|
||||
class="code-input"
|
||||
v-model="CheckEmailForm.code"
|
||||
placeholder="请输入验证码"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Key" />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button
|
||||
size="large"
|
||||
class="send-email-button ml-1"
|
||||
@click="sendEmail"
|
||||
:loading="loading"
|
||||
>获取验证码</el-button
|
||||
>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="login-submit-button w-full" @click="checkCode"
|
||||
>立即验证</el-button
|
||||
>
|
||||
<div class="operate-container mt-1">
|
||||
<el-button
|
||||
class="register"
|
||||
@click="router.push('/login')"
|
||||
link
|
||||
type="primary"
|
||||
icon="DArrowLeft"
|
||||
>
|
||||
返回登录
|
||||
</el-button>
|
||||
</div>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { UserFilled, Key } from '@element-plus/icons-vue'
|
||||
import type { CheckCodeRequest } from '@/api/user/type'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import UserApi from '@/api/user/index'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
const CheckEmailForm = ref<CheckCodeRequest>({
|
||||
email: '',
|
||||
code: '',
|
||||
type: 'reset_password'
|
||||
})
|
||||
|
||||
const resetPasswordFormRef = ref<FormInstance>()
|
||||
const rules = ref<FormRules<CheckCodeRequest>>({
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
|
||||
if (!emailRegExp.test(value) && value != '') {
|
||||
callback(new Error('请输入有效邮箱格式!'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [{ required: true, message: '请输入验证码' }]
|
||||
})
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
const checkCode = () => {
|
||||
resetPasswordFormRef.value
|
||||
?.validate()
|
||||
.then(() => UserApi.checkCode(CheckEmailForm.value, loading))
|
||||
.then(() => router.push({ name: 'reset_password', params: CheckEmailForm.value }))
|
||||
}
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
const sendEmail = () => {
|
||||
resetPasswordFormRef.value?.validateField('email', (v: boolean) => {
|
||||
if (v) {
|
||||
UserApi.sendEmit(CheckEmailForm.value.email, 'reset_password', loading).then(() => {
|
||||
ElMessage.success('发送验证码成功')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import '../index.scss';
|
||||
</style>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.login-submit-button {
|
||||
margin-top: 12px;
|
||||
height: 40px;
|
||||
}
|
||||
|
|
@ -1,152 +1,102 @@
|
|||
<template>
|
||||
<LoiginLayout v-loading="loading">
|
||||
<div class="login-form-container">
|
||||
<div class="login-form-title">
|
||||
<div class="title">
|
||||
<div class="logo"></div>
|
||||
<div>智能客服</div>
|
||||
</div>
|
||||
<div class="sub-title">欢迎使用智能客服管理平台</div>
|
||||
</div>
|
||||
<el-form class="login-form" :rules="rules" :model="loginForm" ref="loginFormRef">
|
||||
<el-form-item>
|
||||
<el-input size="large" class="input-item" v-model="loginForm.username" placeholder="请输入用户名">
|
||||
<template #prepend>
|
||||
<el-button :icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input type="password" size="large" class="input-item" v-model="loginForm.password"
|
||||
placeholder="请输入密码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="operate-container">
|
||||
<span class="register" @click="router.push('register')">注册</span>
|
||||
<span class="forgot-password" @click="router.push('forgot_password')">忘记密码</span>
|
||||
</div>
|
||||
<el-button type="primary" class="login-button" @click="login">登录</el-button>
|
||||
</div>
|
||||
</LoiginLayout>
|
||||
<login-layout v-loading="loading">
|
||||
<LoginContainer subTitle="欢迎使用智能客服管理平台">
|
||||
<el-form class="login-form" :rules="rules" :model="loginForm" ref="loginFormRef">
|
||||
<el-form-item>
|
||||
<el-input
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.username"
|
||||
placeholder="请输入用户名"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="loginForm.password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="operate-container flex-between">
|
||||
<el-button class="register" @click="router.push('/register')" link type="primary">
|
||||
注册
|
||||
</el-button>
|
||||
<el-button
|
||||
class="forgot-password"
|
||||
@click="router.push('/forgot_password')"
|
||||
link
|
||||
type="primary"
|
||||
>
|
||||
忘记密码
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button type="primary" class="login-submit-button w-full" @click="login">登录</el-button>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import type { LoginRequest } from "@/api/user/type"
|
||||
import { UserFilled, Lock } from '@element-plus/icons-vue'
|
||||
import LoiginLayout from "@/components/layout/login-layout/index.vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import { ref } from 'vue'
|
||||
import type { LoginRequest } from '@/api/user/type'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { useUserStore } from "@/stores/user"
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const userStore = useUserStore();
|
||||
const loading = ref<boolean>(false)
|
||||
const userStore = useUserStore()
|
||||
const router = useRouter()
|
||||
const loginForm = ref<LoginRequest>({
|
||||
username: '',
|
||||
password: ''
|
||||
});
|
||||
|
||||
username: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
const rules = ref<FormRules<LoginRequest>>({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: "长度在 6 到 30 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: '长度在 6 到 30 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
const loginFormRef = ref<FormInstance>()
|
||||
|
||||
const login = () => {
|
||||
loginFormRef.value?.validate().then(() => {
|
||||
loading.value = true
|
||||
userStore.login(loginForm.value.username, loginForm.value.password)
|
||||
.then(() => { router.push({ name: 'home' }) })
|
||||
.finally(() => loading.value = false)
|
||||
})
|
||||
loginFormRef.value?.validate().then(() => {
|
||||
loading.value = true
|
||||
userStore
|
||||
.login(loginForm.value.username, loginForm.value.password)
|
||||
.then(() => {
|
||||
router.push({ name: 'home' })
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.login-form-container {
|
||||
width: 420px;
|
||||
|
||||
|
||||
.login-form-title {
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #101010;
|
||||
height: 60px;
|
||||
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #101010;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.operate-container {
|
||||
color: rgba(51, 112, 255, 1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.register {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
@import './index.scss';
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,203 @@
|
|||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer>
|
||||
<h3 class="mb-2">注册</h3>
|
||||
<el-form class="register-form" :model="registerForm" :rules="rules" ref="registerFormRef">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="registerForm.username"
|
||||
placeholder="请输入用户名"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="registerForm.password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="repassword">
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="registerForm.re_password"
|
||||
placeholder="请输入确认密码"
|
||||
show-password
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="email">
|
||||
<el-input
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="registerForm.email"
|
||||
placeholder="请输入邮箱"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Message" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<div class="flex-between w-full">
|
||||
<el-input
|
||||
size="large"
|
||||
class="code-input"
|
||||
v-model="registerForm.code"
|
||||
placeholder="请输入验证码"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Key" />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button
|
||||
size="large"
|
||||
class="send-email-button ml-1"
|
||||
@click="sendEmail"
|
||||
:loading="sendEmailLoading"
|
||||
>获取验证码</el-button
|
||||
>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="login-submit-button w-full" @click="register"
|
||||
>注册</el-button
|
||||
>
|
||||
<div class="operate-container mt-1">
|
||||
<el-button
|
||||
class="register"
|
||||
@click="router.push('/login')"
|
||||
link
|
||||
type="primary"
|
||||
icon="DArrowLeft"
|
||||
>
|
||||
返回登录
|
||||
</el-button>
|
||||
</div>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import type { RegisterRequest } from '@/api/user/type'
|
||||
import { UserFilled, Lock, Message, Key } from '@element-plus/icons-vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import UserApi from '@/api/user/index'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
const registerForm = ref<RegisterRequest>({
|
||||
username: '',
|
||||
password: '',
|
||||
re_password: '',
|
||||
email: '',
|
||||
code: ''
|
||||
})
|
||||
|
||||
const rules = ref<FormRules<RegisterRequest>>({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: '长度在 6 到 30 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
re_password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入确认密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: '长度在 6 到 30 个字符',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (registerForm.value.password != registerForm.value.re_password) {
|
||||
callback(new Error('密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
|
||||
if (!emailRegExp.test(value) && value != '') {
|
||||
callback(new Error('请输入有效邮箱格式!'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [{ required: true, message: '请输入验证码' }]
|
||||
})
|
||||
|
||||
const registerFormRef = ref<FormInstance>()
|
||||
const register = () => {
|
||||
registerFormRef.value
|
||||
?.validate()
|
||||
.then(() => {
|
||||
return UserApi.register(registerForm.value)
|
||||
})
|
||||
.then(() => {
|
||||
router.push('login')
|
||||
})
|
||||
}
|
||||
const sendEmailLoading = ref<boolean>(false)
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
const sendEmail = () => {
|
||||
registerFormRef.value?.validateField('email', (v: boolean) => {
|
||||
if (v) {
|
||||
UserApi.sendEmit(registerForm.value.email, 'register', sendEmailLoading).then(() => {
|
||||
ElMessage.success('发送验证码成功')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import '../index.scss';
|
||||
</style>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<login-layout>
|
||||
<LoginContainer>
|
||||
<h3 class="mb-2">修改密码</h3>
|
||||
<el-form
|
||||
class="reset-password-form"
|
||||
ref="resetPasswordFormRef"
|
||||
:model="resetPasswordForm"
|
||||
:rules="rules"
|
||||
>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="resetPasswordForm.password"
|
||||
placeholder="请输入密码"
|
||||
show-password
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="re_password">
|
||||
<el-input
|
||||
type="password"
|
||||
size="large"
|
||||
class="input-item"
|
||||
v-model="resetPasswordForm.re_password"
|
||||
placeholder="请输入确认密码"
|
||||
show-password
|
||||
>
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="login-submit-button w-full" @click="resetPassword"
|
||||
>确认修改</el-button
|
||||
>
|
||||
<div class="operate-container mt-1">
|
||||
<el-button
|
||||
class="register"
|
||||
@click="router.push('/login')"
|
||||
link
|
||||
type="primary"
|
||||
icon="DArrowLeft"
|
||||
>
|
||||
返回登录
|
||||
</el-button>
|
||||
</div>
|
||||
</LoginContainer>
|
||||
</login-layout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import type { ResetPasswordRequest } from '@/api/user/type'
|
||||
import { Lock } from '@element-plus/icons-vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import UserApi from '@/api/user/index'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const resetPasswordForm = ref<ResetPasswordRequest>({
|
||||
password: '',
|
||||
re_password: '',
|
||||
email: '',
|
||||
code: ''
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const code = route.params.code
|
||||
const email = route.params.email
|
||||
if (code && email) {
|
||||
resetPasswordForm.value.code = code as string
|
||||
resetPasswordForm.value.email = email as string
|
||||
} else {
|
||||
router.push('forgot_password')
|
||||
}
|
||||
})
|
||||
|
||||
const rules = ref<FormRules<ResetPasswordRequest>>({
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: '长度在 6 到 30 个字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
re_password: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入确认密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: '长度在 6 到 30 个字符',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) {
|
||||
callback(new Error('密码不一致'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
const resetPasswordFormRef = ref<FormInstance>()
|
||||
const loading = ref<boolean>(false)
|
||||
const resetPassword = () => {
|
||||
resetPasswordFormRef.value
|
||||
?.validate()
|
||||
.then(() => UserApi.resetPassword(resetPasswordForm.value, loading))
|
||||
.then(() => {
|
||||
ElMessage.success('修改密码成功')
|
||||
router.push({ name: 'login' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
@import '../index.scss';
|
||||
</style>
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
<template>
|
||||
<LoiginLayout>
|
||||
<div class="register-form-container">
|
||||
<div class="register-form-title">
|
||||
<div class="title">
|
||||
<div class="logo"></div>
|
||||
<div>智能客服</div>
|
||||
</div>
|
||||
<div class="sub-title">修改密码</div>
|
||||
</div>
|
||||
<el-form class="register-form" :model="registerForm" :rules="rules" ref="registerFormRef">
|
||||
<el-form-item prop="username">
|
||||
<el-input size="large" class="input-item" v-model="registerForm.username" placeholder="请输入用户名">
|
||||
<template #prepend>
|
||||
<el-button :icon="UserFilled" />
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" size="large" class="input-item" v-model="registerForm.password"
|
||||
placeholder="请输入密码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="repassword">
|
||||
<el-input type="password" size="large" class="input-item" v-model="registerForm.re_password"
|
||||
placeholder="请输入确认密码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="email">
|
||||
<el-input size="large" class="input-item" v-model="registerForm.email" placeholder="请输入邮箱">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Message" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="code">
|
||||
<el-input size="large" class="code-input" v-model="registerForm.code" placeholder="请输入验证码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Key" />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button size="large" class="send-email-button" @click="sendEmail"
|
||||
:loading="sendEmailLoading">获取验证码</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="register-button" @click="register">注册</el-button>
|
||||
<div class="operate-container">
|
||||
<span class="register" @click="router.push('login')">< 返回登陆</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</LoiginLayout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import type { RegisterRequest } from "@/api/user/type"
|
||||
import { UserFilled, Lock, Message, Key } from '@element-plus/icons-vue'
|
||||
import LoiginLayout from "@/components/layout/login-layout/index.vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import UserApi from "@/api/user/index"
|
||||
import { ElMessage } from "element-plus"
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
const registerForm = ref<RegisterRequest>({
|
||||
username: '',
|
||||
password: '',
|
||||
re_password: '',
|
||||
email: '',
|
||||
code: ''
|
||||
});
|
||||
|
||||
const rules = ref<FormRules<RegisterRequest>>({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: "长度在 6 到 30 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
re_password: [{
|
||||
required: true,
|
||||
message: '请输入确认密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: "长度在 6 到 30 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (registerForm.value.password != registerForm.value.re_password) {
|
||||
callback(new Error('密码不一致'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}],
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
|
||||
if ((!emailRegExp.test(value) && value != '')) {
|
||||
callback(new Error('请输入有效邮箱格式!'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: '请输入验证码' }
|
||||
]
|
||||
|
||||
})
|
||||
|
||||
const registerFormRef = ref<FormInstance>();
|
||||
const register = () => {
|
||||
registerFormRef.value?.validate().then(() => {
|
||||
return UserApi.register(registerForm.value)
|
||||
}).then(() => {
|
||||
router.push("login")
|
||||
})
|
||||
}
|
||||
const sendEmailLoading = ref<boolean>(false);
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
const sendEmail = () => {
|
||||
registerFormRef.value?.validateField("email", (v: boolean) => {
|
||||
if (v) {
|
||||
UserApi.sendEmit(registerForm.value.email, "register",sendEmailLoading)
|
||||
.then(() => {
|
||||
ElMessage.success("发送验证码成功")
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.register-form-container {
|
||||
width: 420px;
|
||||
|
||||
.code-input {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.send-email-button {
|
||||
margin-left: 12px;
|
||||
width: 158px;
|
||||
}
|
||||
|
||||
.register-form-title {
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #101010;
|
||||
height: 60px;
|
||||
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
color: #101010;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.operate-container {
|
||||
margin-top: 12px;
|
||||
color: rgba(51, 112, 255, 1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.register {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.register-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
<template>
|
||||
<LoiginLayout>
|
||||
<div class="register-form-container">
|
||||
<div class="register-form-title">
|
||||
<div class="title">
|
||||
<div class="logo"></div>
|
||||
<div>智能客服</div>
|
||||
</div>
|
||||
<div class="sub-title">修改密码</div>
|
||||
</div>
|
||||
<el-form class="reset-password-form" ref="resetPasswordFormRef" :model="resetPasswordForm" :rules="rules">
|
||||
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" size="large" class="input-item" v-model="resetPasswordForm.password"
|
||||
placeholder="请输入密码">
|
||||
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="re_password">
|
||||
<el-input type="password" size="large" class="input-item" v-model="resetPasswordForm.re_password"
|
||||
placeholder="请输入确认密码">
|
||||
<template #prepend>
|
||||
<el-button :icon="Lock" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button type="primary" class="register-button" @click="resetPassword">确认修改</el-button>
|
||||
<div class="operate-container">
|
||||
<span class="register" @click="router.push('login')">< 返回登陆</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</LoiginLayout>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue"
|
||||
import type { ResetPasswordRequest } from "@/api/user/type"
|
||||
import { Lock } from '@element-plus/icons-vue'
|
||||
import LoiginLayout from "@/components/layout/login-layout/index.vue"
|
||||
import { useRouter, useRoute } from "vue-router"
|
||||
import { ElMessage } from "element-plus"
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import UserApi from "@/api/user/index"
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const resetPasswordForm = ref<ResetPasswordRequest>({
|
||||
password: '',
|
||||
re_password: '',
|
||||
email: '',
|
||||
code: ''
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const code = route.params.code;
|
||||
const email = route.params.email;
|
||||
if (code && email) {
|
||||
resetPasswordForm.value.code = code as string;
|
||||
resetPasswordForm.value.email = email as string;
|
||||
} else {
|
||||
router.push('forgot_password')
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const rules = ref<FormRules<ResetPasswordRequest>>({
|
||||
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: "长度在 6 到 30 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
re_password: [{
|
||||
required: true,
|
||||
message: '请输入确认密码',
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 6,
|
||||
max: 30,
|
||||
message: "长度在 6 到 30 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) {
|
||||
callback(new Error('密码不一致'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}],
|
||||
|
||||
})
|
||||
const resetPasswordFormRef = ref<FormInstance>();
|
||||
const loading = ref<boolean>(false);
|
||||
const resetPassword = () => {
|
||||
resetPasswordFormRef.value?.validate()
|
||||
.then(() => UserApi.resetPassword(resetPasswordForm.value, loading))
|
||||
.then(() => {
|
||||
ElMessage.success("修改密码成功")
|
||||
router.push({ name: 'login' })
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scope>
|
||||
.register-form-container {
|
||||
width: 420px;
|
||||
|
||||
.code-input {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.send-email-button {
|
||||
margin-left: 12px;
|
||||
width: 158px;
|
||||
}
|
||||
|
||||
.register-form-title {
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
.logo {
|
||||
background-image: url('@/assets/logo.png');
|
||||
background-size: 100% 100%;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
color: #101010;
|
||||
height: 60px;
|
||||
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
color: #101010;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.operate-container {
|
||||
margin-top: 12px;
|
||||
color: rgba(51, 112, 255, 1);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.register {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.register-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
import type { ProxyOptions } from 'vite'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import DefineOptions from 'unplugin-vue-define-options/vite'
|
||||
|
||||
const envDir = './env'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
|
|
@ -13,10 +16,11 @@ export default defineConfig(({ mode }) => {
|
|||
rewrite: (path) => path.replace(ENV.VITE_BASE_PATH, '/')
|
||||
}
|
||||
return {
|
||||
preflight: false,
|
||||
lintOnSave: false,
|
||||
base: ENV.VITE_BASE_PATH,
|
||||
envDir: envDir,
|
||||
plugins: [vue()],
|
||||
plugins: [vue(), DefineOptions()],
|
||||
server: {
|
||||
cors: true,
|
||||
host: '0.0.0.0',
|
||||
|
|
|
|||
Loading…
Reference in New Issue