mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-27 18:59:26 +08:00
feat(web): 实现能源站监控与运行管理系统的登录功能
- 新增登录页面组件 LoginView.vue - 添加全局样式和布局调整 - 实现用户登录逻辑,包括表单验证、验证码校验和 token 存储 - 集成 ant-design-vue 组件库 - 添加请求拦截器和错误处理
This commit is contained in:
116
web/package-lock.json
generated
116
web/package-lock.json
generated
@@ -9,7 +9,9 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.11.0",
|
||||
"core-js": "^3.8.3",
|
||||
"moment": "^2.30.1",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
@@ -3903,6 +3905,12 @@
|
||||
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
@@ -3951,6 +3959,17 @@
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.11.0.tgz",
|
||||
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-loader": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.4.1.tgz",
|
||||
@@ -4297,7 +4316,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -4632,6 +4650,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
|
||||
@@ -5462,6 +5492,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||
@@ -5666,7 +5705,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
@@ -5809,7 +5847,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -5819,7 +5856,6 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -5836,7 +5872,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
@@ -5845,6 +5880,21 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
|
||||
@@ -6807,7 +6857,6 @@
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -6824,6 +6873,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@@ -6907,7 +6972,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@@ -6944,7 +7008,6 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
@@ -6969,7 +7032,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
@@ -7088,7 +7150,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -7154,7 +7215,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -7163,6 +7223,21 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-sum": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-2.0.0.tgz",
|
||||
@@ -7174,7 +7249,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
@@ -8368,7 +8442,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -8482,7 +8555,6 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
@@ -8492,7 +8564,6 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
@@ -8646,6 +8717,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz",
|
||||
@@ -10116,6 +10196,12 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.11.0",
|
||||
"core-js": "^3.8.3",
|
||||
"moment": "^2.30.1",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
<template>
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</nav>
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
|
||||
BIN
web/src/assets/images/loginBg.png
Normal file
BIN
web/src/assets/images/loginBg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
@@ -1,130 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br />
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-cli documentation</a
|
||||
>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>babel</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>router</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>vuex</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>eslint</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
|
||||
>Forum</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
|
||||
>Community Chat</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
|
||||
>Twitter</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-router</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-devtools#vue-devtools"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>vue-devtools</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-loader</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/awesome-vue"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>awesome-vue</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "HelloWorld",
|
||||
props: {
|
||||
msg: String,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="scss">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
16
web/src/request/api.js
Normal file
16
web/src/request/api.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import request from "@/request/index.js";
|
||||
export function postReq(data, url) {
|
||||
return request({
|
||||
method: "post",
|
||||
url,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function getReq(data, url) {
|
||||
// const query = qs.stringify(data, { indices: false })
|
||||
return request({
|
||||
method: "get",
|
||||
url: url + "?" + data,
|
||||
});
|
||||
}
|
||||
61
web/src/request/index.js
Normal file
61
web/src/request/index.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import axios from "axios";
|
||||
// import openNotification from "../utils/notification";
|
||||
// let { config } = window;
|
||||
// let { baseUrl } = config;
|
||||
|
||||
const service = axios.create({
|
||||
// baseURL: baseUrl,
|
||||
baseURL: "",
|
||||
timeout: 120000,
|
||||
});
|
||||
|
||||
service.interceptors.request.use((config) => {
|
||||
const webConfig = config;
|
||||
// if (!["/user/login", "/config/getConfig"].includes(config.url)) {
|
||||
// if (localStorage.getItem("token")) {
|
||||
// webConfig.headers = {
|
||||
// Authorization: localStorage.getItem("token"),
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
|
||||
return webConfig;
|
||||
});
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
// 排除以下接口的错误提示
|
||||
const { url } = response.config;
|
||||
const urls = ["/light/", "/serve/delete", "/user/checkRandom"];
|
||||
const urlFlag = urls.map((item) => {
|
||||
return url.includes(item);
|
||||
});
|
||||
|
||||
const res = response.data;
|
||||
|
||||
if (res.code !== 200) {
|
||||
if (res.code == 401 || res.tip == "校验token过期") {
|
||||
setTimeout(() => {
|
||||
window.$wujie?.props.jump({ path: "/login" });
|
||||
}, 1000);
|
||||
} else if (urlFlag.every((item) => item === false)) {
|
||||
// openNotification({
|
||||
// status: "error",
|
||||
// desc: res.tip,
|
||||
// });
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
(error) => {
|
||||
// console.log(error, 'error 此处添加监控超时处理')
|
||||
if (
|
||||
error.name === "AxiosError" &&
|
||||
error.message === "timeout of 120000ms exceeded" &&
|
||||
error.code === "ECONNABORTED"
|
||||
) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
||||
@@ -21,7 +21,7 @@ const routes = [
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(process.env.BASE_URL),
|
||||
history: createWebHistory(""),
|
||||
routes,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,441 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>login</h1>
|
||||
<a-config-provider
|
||||
:theme="{
|
||||
token: {
|
||||
colorPrimary: '#065758',
|
||||
},
|
||||
}"
|
||||
>
|
||||
<div class="login">
|
||||
<div class="main-title">能源站监控与运行管理系统</div>
|
||||
<div class="login-content">
|
||||
<div class="title" style="">账号登录</div>
|
||||
<a-form ref="ruleForm" :model="form" :rules="rules">
|
||||
<a-form-item label="" name="user">
|
||||
<a-input
|
||||
:bordered="false"
|
||||
v-model:value="form.user"
|
||||
placeholder="请输入账号"
|
||||
autocomplete
|
||||
>
|
||||
<template #prefix>
|
||||
<span class="iconfont icon-a-xingzhuangjiehe1x"></span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="" name="passwd">
|
||||
<a-input-password
|
||||
:bordered="false"
|
||||
v-model:value="form.passwd"
|
||||
placeholder="请输入密码"
|
||||
autocomplete
|
||||
@pressEnter="login"
|
||||
style="background-color: #fff; margin-top: 6px"
|
||||
>
|
||||
<template #prefix>
|
||||
<span class="iconfont icon-a-xingzhuangjiehe1x1"></span>
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-button class="login-btn" @click="login" :loading="loading"
|
||||
>登录
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-config-provider>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getReq, postReq } from "@/request/api.js";
|
||||
// import { sm2Encrypt, sm2Decrypt } from "@c/utils/sm2Utils.js";
|
||||
// import { getSysConfig } from "@/utils/index.js";
|
||||
// import { copyRight } from "@c/utils/config.js";
|
||||
import // EyeInvisibleOutlined,
|
||||
// EyeTwoTone,
|
||||
// LockOutlined,
|
||||
// UserOutlined,
|
||||
"@ant-design/icons-vue";
|
||||
// import moment from "moment";
|
||||
// import { themeColor } from "@c/utils/config.js";
|
||||
export default {
|
||||
name: "loginView",
|
||||
// components: { EyeTwoTone, EyeInvisibleOutlined },
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
copyRight: "",
|
||||
loading: false,
|
||||
companyName: "",
|
||||
publickey: "",
|
||||
form: {},
|
||||
rules: {
|
||||
user: [{ required: true, message: "请输入用户名", trigger: "blur" }],
|
||||
passwd: [
|
||||
{ required: true, message: "请输入登录密码", trigger: "blur" },
|
||||
],
|
||||
code: [{ required: true, message: "请输入验证码", trigger: "blur" }],
|
||||
},
|
||||
// rules: {
|
||||
// user: [{ validator: this.checkUser, trigger: 'blur' }],
|
||||
// passwd: [{ validator: this.checkPasswd, trigger: 'blur' }],
|
||||
// code: [
|
||||
// { required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
// // { validator: this.asynCheckRandom, },
|
||||
|
||||
// ]
|
||||
// },
|
||||
codeId: Math.random(),
|
||||
codeString: "", // 验证码字符串
|
||||
};
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
// await this.getRandom();
|
||||
// this.companyName = await getSysConfig("app-name");
|
||||
// this.copyRight = await getSysConfig("app-version");
|
||||
// this.publickey = await getSysConfig("secret-pub-key");
|
||||
document.title = this.companyName;
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 验证码校验
|
||||
async asynCheckRandom(code) {
|
||||
const res = await getReq({ id: this.codeId, code }, "/user/checkRandom");
|
||||
if (res.code == 200 && res.data) {
|
||||
return Promise.resolve({ success: true, msg: "" });
|
||||
} else {
|
||||
return Promise.resolve({ success: false, msg: "验证码输入错误" });
|
||||
}
|
||||
},
|
||||
// })
|
||||
|
||||
// 登录后首次判断主题色
|
||||
// async changeTheme() {
|
||||
// const res = await getSysConfig("app-map-center");
|
||||
// const theme = localStorage.getItem("theme");
|
||||
// if (!theme) {
|
||||
// const { sunriseSunset } = JSON.parse(res).weather;
|
||||
// const sunrise = sunriseSunset.sunrise.trim().split(/\s+/)[1] || "04:00";
|
||||
// const sunset = sunriseSunset.sunset.trim().split(/\s+/)[1] || "20:00";
|
||||
|
||||
// const current = moment().locale("zh-cn").format("HH:mm");
|
||||
|
||||
// if (sunrise < current && current < sunset) {
|
||||
// localStorage.setItem("theme", "light");
|
||||
// Object.keys(themeColor).forEach((key) => {
|
||||
// document.documentElement.style.setProperty(
|
||||
// key,
|
||||
// themeColor[key].light
|
||||
// );
|
||||
// });
|
||||
// } else {
|
||||
// localStorage.setItem("theme", "dark");
|
||||
// Object.keys(themeColor).forEach((key) => {
|
||||
// document.documentElement.style.setProperty(
|
||||
// key,
|
||||
// themeColor[key].dark
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
// } else {
|
||||
// Object.keys(themeColor).forEach((key) => {
|
||||
// document.documentElement.style.setProperty(
|
||||
// key,
|
||||
// themeColor[key][theme]
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
|
||||
// 填充密码
|
||||
async fillPassword() {
|
||||
let userName = localStorage.getItem("userName");
|
||||
if (userName) {
|
||||
// this.form.user = localStorage.getItem('userName')
|
||||
// const key = await getSysConfig('secret-pub-key')
|
||||
// this.form.passwd = sm2Decrypt(localStorage.getItem('passwd'), key)
|
||||
this.form.remember = true;
|
||||
}
|
||||
},
|
||||
// 获取验证码
|
||||
async getRandom() {
|
||||
const res = await getReq({ id: this.codeId }, "/user/getRandom");
|
||||
if (res.code == 200) {
|
||||
this.codeString = res.data;
|
||||
} else {
|
||||
this.codeString = "获取失败";
|
||||
}
|
||||
},
|
||||
async login() {
|
||||
this.$refs.ruleForm
|
||||
.validate()
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
this.asynCheckRandom(res.code).then((res) => {
|
||||
if (!res.success) {
|
||||
this.$openNotification({
|
||||
name: "",
|
||||
type: "",
|
||||
status: "error",
|
||||
desc: res.msg,
|
||||
});
|
||||
this.form.code = "";
|
||||
} else {
|
||||
this.submitLoginForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
async submitLoginForm() {
|
||||
// let newPsdSM2 = sm2Encrypt(this.form.passwd, this.publickey);
|
||||
// if (newPsdSM2) {
|
||||
let paramsDate = {
|
||||
user: this.form.user,
|
||||
// passwd: newPsdSM2,
|
||||
};
|
||||
if (this.form.remember) {
|
||||
localStorage.setItem("userName", this.form.user);
|
||||
// localStorage.setItem("passwd", newPsdSM2);
|
||||
}
|
||||
try {
|
||||
const res = await postReq(paramsDate, "/user/login");
|
||||
|
||||
// 记住密码
|
||||
|
||||
if (res.code == 200) {
|
||||
const { token, user } = res.data;
|
||||
this.$openNotification({
|
||||
name: "",
|
||||
type: "",
|
||||
status: "success",
|
||||
desc: "登录成功",
|
||||
});
|
||||
localStorage.setItem("token", token);
|
||||
localStorage.setItem("showNotice", true);
|
||||
|
||||
// this.changeTheme();
|
||||
this.getUserRoute(user);
|
||||
} else {
|
||||
this.loading = false;
|
||||
throw new Error(res);
|
||||
}
|
||||
} catch (error) {
|
||||
this.loading = false;
|
||||
this.form.code = "";
|
||||
this.getRandom();
|
||||
}
|
||||
// }
|
||||
},
|
||||
async getUserRoute(user) {
|
||||
const { userExtend } = user;
|
||||
const { role } = userExtend;
|
||||
localStorage.setItem("user", JSON.stringify(user));
|
||||
if (role && role.permissionList.length > 0) {
|
||||
const allMenus = [];
|
||||
role.permissionList.forEach((item) => {
|
||||
allMenus.push(...item.menusList);
|
||||
});
|
||||
const uniqueArray = [
|
||||
...new Map(allMenus.map((item) => [item.id, item])).values(),
|
||||
];
|
||||
const treeMunes = this.buildTree(uniqueArray);
|
||||
|
||||
const pcMunes = treeMunes.filter((item) => item.type == 0);
|
||||
localStorage.setItem("menuList", JSON.stringify(pcMunes));
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.$router.push("/");
|
||||
}, 1000);
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
buildTree(items, parentId = null) {
|
||||
const result = [];
|
||||
const itemMap = {}; // 用于存储id和对应节点的映射,方便快速查找父节点
|
||||
|
||||
items.forEach((item) => {
|
||||
if (!itemMap[item.id]) {
|
||||
itemMap[item.id] = { ...item, children: [] };
|
||||
}
|
||||
|
||||
const node = itemMap[item.id];
|
||||
if (item.parentId === parentId || item.parentId == 0) {
|
||||
result.push(node);
|
||||
} else {
|
||||
if (!itemMap[item.parentId]) {
|
||||
itemMap[item.parentId] = { children: [] };
|
||||
}
|
||||
itemMap[item.parentId].children.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
result.sort((a, b) => a.seq - b.seq);
|
||||
result.forEach((item) => {
|
||||
if (item.children.length == 0) {
|
||||
delete item.children;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
},
|
||||
onChange() {},
|
||||
forgetPassword() {
|
||||
this.$openNotification({
|
||||
name: "",
|
||||
type: "",
|
||||
status: "warning",
|
||||
desc: "请联系平台管理员",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: 1440px;
|
||||
min-height: 900px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url("@/assets/images/loginBg.png");
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
|
||||
.main-title {
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(255, 255, 255, 1) 0%,
|
||||
rgba(40, 235, 231, 1) 100%
|
||||
);
|
||||
color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
font-size: 50px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 5px;
|
||||
line-height: 53px;
|
||||
}
|
||||
|
||||
.login-content {
|
||||
width: 390px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 40px;
|
||||
|
||||
.title {
|
||||
margin-bottom: 10px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
}
|
||||
:deep(.ant-input-prefix) {
|
||||
color: #217575;
|
||||
}
|
||||
:deep(.ant-form-item) {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
:deep(.ant-form-item-explain-error) {
|
||||
font-size: 12px;
|
||||
}
|
||||
.iconfont {
|
||||
margin: 0 10px 0 5px;
|
||||
}
|
||||
}
|
||||
.yanzhengma {
|
||||
width: 60px;
|
||||
font-family: yanzhengma;
|
||||
font-size: 23px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.rememberPass {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 290px;
|
||||
.ant-checkbox-wrapper,
|
||||
span {
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ant-checkbox-wrapper:hover {
|
||||
color: #065758;
|
||||
}
|
||||
span:hover {
|
||||
color: #065758;
|
||||
}
|
||||
}
|
||||
.login-btn {
|
||||
width: 335px;
|
||||
height: 45px;
|
||||
border-radius: 4px;
|
||||
background: #2a82e4;
|
||||
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
.btn-text {
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
:deep(.ant-input) {
|
||||
&::placeholder {
|
||||
// font-size: 12px !important;
|
||||
// line-height: 12px;
|
||||
// line-height: 100px !important;
|
||||
// height: 40px !important;
|
||||
// line-height: 40px !important;
|
||||
}
|
||||
}
|
||||
:deep(span.ant-input-affix-wrapper) {
|
||||
height: 40px !important;
|
||||
background: #eceff4 !important;
|
||||
color: #065758 !important;
|
||||
border: none !important;
|
||||
border-radius: 8px !important;
|
||||
.ant-input {
|
||||
// height: 40px !important;
|
||||
border-radius: 0 !important;
|
||||
background: #eceff4 !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #0caf60 !important;
|
||||
}
|
||||
&:focus {
|
||||
border: none !important;
|
||||
background-color: #eceff4;
|
||||
}
|
||||
}
|
||||
:deep(.ant-input-affix-wrapper) {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
// 输入框自动填充后的背景改色
|
||||
input:-internal-autofill-previewed,
|
||||
input:-internal-autofill-selected {
|
||||
-webkit-text-fill-color: #000000 !important;
|
||||
transition: background-color 500s ease-out 0.5s;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,12 +7,9 @@
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
import HelloWorld from "@/components/HelloWorld.vue";
|
||||
|
||||
export default {
|
||||
name: "HomeView",
|
||||
components: {
|
||||
HelloWorld,
|
||||
},
|
||||
components: {},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,15 @@ module.exports = defineConfig({
|
||||
chunkFilename: `css/.[contenthash:8].chunk.css`,
|
||||
},
|
||||
},
|
||||
// webpack相关配置
|
||||
configureWebpack: {
|
||||
// 自定义打包入口
|
||||
entry: "./src/main.js",
|
||||
|
||||
// 扩展 webpack 配置
|
||||
plugins: [
|
||||
// 添加插件
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.join(__dirname, "src"),
|
||||
@@ -60,17 +68,6 @@ module.exports = defineConfig({
|
||||
// 生产环境的 source map
|
||||
productionSourceMap: true,
|
||||
|
||||
// webpack相关配置
|
||||
configureWebpack: {
|
||||
// 自定义打包入口
|
||||
entry: "./src/main.js",
|
||||
|
||||
// 扩展 webpack 配置
|
||||
plugins: [
|
||||
// 添加插件
|
||||
],
|
||||
},
|
||||
|
||||
// 第三方插件配置
|
||||
pluginOptions: {
|
||||
// ...
|
||||
|
||||
Reference in New Issue
Block a user