mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-27 18:59:26 +08:00
build(web): 添加 ESLint 和 Prettier 配置文件
- 新增 .eslintrc.js 文件,配置 ESLint 规则和插件 - 新增 .prettierrc.json 文件,设置 Prettier 格式化选项
This commit is contained in:
95
web/.eslintrc.js
Normal file
95
web/.eslintrc.js
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:vue/vue3-recommended', // Vue 项目
|
||||||
|
'prettier' // 必须放在最后
|
||||||
|
],
|
||||||
|
parser: 'vue-eslint-parser', // 解析 .vue 文件
|
||||||
|
|
||||||
|
globals: {
|
||||||
|
T: 'readonly' // 声明 T 是只读的全局变量
|
||||||
|
},
|
||||||
|
plugins: ['react', '@typescript-eslint', 'prettier'], // 添加 prettier 插件
|
||||||
|
rules: {
|
||||||
|
'vue/v-on-event-hyphenation': 'off',
|
||||||
|
'prettier/prettier': 'off',
|
||||||
|
'react/react-in-jsx-scope': 'off', // React 17+ 可关闭 JSX 运行时检查
|
||||||
|
// off=0, warn=1, error=2, 如果是数组, 第二项表示参数option
|
||||||
|
'vue/attributes-order': 0,
|
||||||
|
indent: [2, 2], // 控制缩进为2
|
||||||
|
eqeqeq: 0, // 警告使用全等
|
||||||
|
quotes: [0, 'single'], // 单引号
|
||||||
|
singleQuote: 0,
|
||||||
|
'no-console': 2, // 不禁用console
|
||||||
|
'no-debugger': 2, // 警告debugger
|
||||||
|
'no-var': 2, // 对var禁止
|
||||||
|
'no-eval': 0,
|
||||||
|
semi: 0, // 强制使用分号
|
||||||
|
'comma-dangle': 0,
|
||||||
|
'semi-spacing': [0, { before: false, after: false }], // 强制分号前后不允许空格
|
||||||
|
// 'no-irregular-whitespace': 0, // 不规则的空白不允许
|
||||||
|
// 'no-trailing-spaces': 1, // 一行结束后面有空格就发出警告
|
||||||
|
'eol-last': 0, // 文件以单一的换行符结束
|
||||||
|
'no-unused-vars': 0, // 不能有声明后未被使用的变量或参数
|
||||||
|
'no-underscore-dangle': 0, // 标识符不能以_开头或结尾
|
||||||
|
'no-alert': 2, // 禁止使用alert confirm prompt
|
||||||
|
'no-lone-blocks': 0, // 禁止不必要的嵌套块
|
||||||
|
'no-class-assign': 2, // 禁止给类赋值
|
||||||
|
'no-cond-assign': 2, // 禁止在条件表达式中使用赋值语句
|
||||||
|
'no-const-assign': 2, // 禁止修改const声明的变量
|
||||||
|
'no-delete-var': 2, // 不能对var声明的变量使用delete操作符
|
||||||
|
'no-dupe-keys': 2, // 在创建对象字面量时不允许键重复
|
||||||
|
'no-duplicate-case': 2, // switch中的case标签不能重复
|
||||||
|
'no-dupe-args': 2, // 函数参数不能重复
|
||||||
|
'no-empty': 2, // 块语句中的内容不能为空
|
||||||
|
'no-func-assign': 2, // 禁止重复的函数声明
|
||||||
|
'no-invalid-this': 0, // 禁止无效的this,只能用在构造器,类,对象字面量
|
||||||
|
'no-redeclare': 2, // 禁止重复声明变量
|
||||||
|
'no-spaced-func': 2, // 函数调用时 函数名与()之间不能有空格
|
||||||
|
'no-this-before-super': 0, // 在调用super()之前不能使用this或super
|
||||||
|
'no-undef': 2, // 不能有未定义的变量
|
||||||
|
'no-use-before-define': 2, // 未定义前不能使用
|
||||||
|
camelcase: 2, // 强制驼峰法命名
|
||||||
|
'vue/multi-word-component-names': 0,
|
||||||
|
'jsx-quotes': [2, 'prefer-double'], // 强制在JSX属性(jsx-quotes)中一致使用双引号
|
||||||
|
// 'react/sort-comp': 2, // 强制组件方法顺序
|
||||||
|
'no-extra-boolean-cast': 0, // 禁止不必要的bool转换
|
||||||
|
// 'react/no-array-index-key': 0, // 防止在数组中遍历中使用数组key做索引
|
||||||
|
'no-unreachable': 1, // 不能有无法执行的代码
|
||||||
|
'no-mixed-spaces-and-tabs': 0, // 禁止混用tab和空格
|
||||||
|
'prefer-arrow-callback': 0, // 比较喜欢箭头回调
|
||||||
|
'arrow-parens': 2, // 箭头函数用小括号括起来
|
||||||
|
'arrow-spacing': 0, // = >的前/后括号
|
||||||
|
'prefer-const': 0,
|
||||||
|
|
||||||
|
'prefer-destructuring': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
VariableDeclarator: {
|
||||||
|
array: false,
|
||||||
|
object: true
|
||||||
|
},
|
||||||
|
AssignmentExpression: {
|
||||||
|
array: false,
|
||||||
|
object: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enforceForRenamedProperties: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'use-isnan': 2, // 禁止比较时使用NaN,只能用isNaN()
|
||||||
|
'vue/no-multiple-template-root': 0,
|
||||||
|
'space-before-function-paren': 0,
|
||||||
|
'vue/no-v-model-argument': 0,
|
||||||
|
'promise/param-names': 0,
|
||||||
|
'no-case-declarations': 0,
|
||||||
|
'vue/valid-v-for': 0,
|
||||||
|
'prefer-promise-reject-errors': 0,
|
||||||
|
'vue/no-v-for-template-key': 0
|
||||||
|
}
|
||||||
|
}
|
||||||
8
web/.prettierrc.json
Normal file
8
web/.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"semi": false,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"trailingComma": "none"
|
||||||
|
}
|
||||||
3724
web/package-lock.json
generated
3724
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,10 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve && webpack-dev-server",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint",
|
||||||
|
"show-webpack-version": "webpack --version"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
@@ -19,18 +20,24 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.12.16",
|
||||||
"@babel/eslint-parser": "^7.12.16",
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
||||||
|
"@typescript-eslint/parser": "^8.41.0",
|
||||||
"@vue/cli-plugin-babel": "~5.0.0",
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^8.57.1",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.10.2",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^8.0.3",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"prettier": "^2.4.1",
|
"eslint-plugin-vue": "^8.7.1",
|
||||||
|
"prettier": "^2.8.8",
|
||||||
"sass": "^1.32.7",
|
"sass": "^1.32.7",
|
||||||
"sass-loader": "^12.0.0"
|
"sass-loader": "^12.0.0",
|
||||||
|
"vue-eslint-parser": "^10.2.0",
|
||||||
|
"webpack-cli": "^6.0.1",
|
||||||
|
"webpack-dev-server": "^5.2.2"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|||||||
@@ -4,23 +4,12 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
position: absolute;
|
||||||
-webkit-font-smoothing: antialiased;
|
top: 0;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
left: 0;
|
||||||
text-align: center;
|
bottom: 0;
|
||||||
color: #2c3e50;
|
right: 0;
|
||||||
}
|
min-width: 1440px;
|
||||||
|
min-height: 900px;
|
||||||
nav {
|
|
||||||
padding: 30px;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #2c3e50;
|
|
||||||
|
|
||||||
&.router-link-exact-active {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 120 KiB |
BIN
web/src/assets/images/loginFrom.png
Normal file
BIN
web/src/assets/images/loginFrom.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
@@ -1,28 +1,25 @@
|
|||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: '/',
|
||||||
name: "home",
|
redirect: '/login'
|
||||||
redirect: "/login",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: '/login',
|
||||||
name: "login",
|
name: 'login',
|
||||||
component: () =>
|
component: () => import(/* webpackChunkName: "login" */ '@/views/LoginView.vue')
|
||||||
import(/* webpackChunkName: "login" */ "@/views/LoginView.vue"),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/main",
|
path: '/main',
|
||||||
name: "main",
|
name: 'main',
|
||||||
component: () =>
|
component: () => import(/* webpackChunkName: "login" */ '@/views/MainView.vue')
|
||||||
import(/* webpackChunkName: "login" */ "@/views/MainView.vue"),
|
}
|
||||||
},
|
]
|
||||||
];
|
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(""),
|
history: createWebHistory(''),
|
||||||
routes,
|
routes
|
||||||
});
|
})
|
||||||
|
|
||||||
export default router;
|
export default router
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<a-config-provider
|
<a-config-provider
|
||||||
:theme="{
|
:theme="{
|
||||||
token: {
|
token: {
|
||||||
colorPrimary: '#065758',
|
colorPrimary: '#143d7d'
|
||||||
},
|
}
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="login">
|
<div class="login">
|
||||||
@@ -12,337 +12,143 @@
|
|||||||
<div class="title" style="">账号登录</div>
|
<div class="title" style="">账号登录</div>
|
||||||
<a-form ref="ruleForm" :model="form" :rules="rules">
|
<a-form ref="ruleForm" :model="form" :rules="rules">
|
||||||
<a-form-item label="" name="user">
|
<a-form-item label="" name="user">
|
||||||
<a-input
|
<a-input v-model:value="form.user" placeholder="请输入账号" autocomplete>
|
||||||
:bordered="false"
|
|
||||||
v-model:value="form.user"
|
|
||||||
placeholder="请输入账号"
|
|
||||||
autocomplete
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<span class="iconfont icon-a-xingzhuangjiehe1x"></span>
|
<user-outlined />
|
||||||
</template>
|
</template>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="" name="passwd">
|
<a-form-item label="" name="passwd">
|
||||||
<a-input-password
|
<a-input-password
|
||||||
:bordered="false"
|
|
||||||
v-model:value="form.passwd"
|
v-model:value="form.passwd"
|
||||||
placeholder="请输入密码"
|
placeholder="请输入密码"
|
||||||
autocomplete
|
autocomplete
|
||||||
@pressEnter="login"
|
@pressEnter="login"
|
||||||
style="background-color: #fff; margin-top: 6px"
|
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<span class="iconfont icon-a-xingzhuangjiehe1x1"></span>
|
<LockOutlined />
|
||||||
</template>
|
</template>
|
||||||
</a-input-password>
|
</a-input-password>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<a-button class="login-btn" @click="login" :loading="loading"
|
<a-button class="login-btn" @click="login" :loading="loading">登录 </a-button>
|
||||||
>登录
|
|
||||||
</a-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-config-provider>
|
</a-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getReq, postReq } from "@/request/api.js";
|
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
|
||||||
// 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 {
|
export default {
|
||||||
name: "loginView",
|
name: 'LoginView',
|
||||||
// components: { EyeTwoTone, EyeInvisibleOutlined },
|
components: {
|
||||||
props: {},
|
UserOutlined,
|
||||||
|
LockOutlined
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
copyRight: "",
|
form: {
|
||||||
loading: false,
|
user: 'admin',
|
||||||
companyName: "",
|
passwd: '123456'
|
||||||
publickey: "",
|
},
|
||||||
form: {},
|
|
||||||
rules: {
|
rules: {
|
||||||
user: [{ required: true, message: "请输入用户名", trigger: "blur" }],
|
user: [
|
||||||
passwd: [
|
{
|
||||||
{ required: true, message: "请输入登录密码", trigger: "blur" },
|
required: true,
|
||||||
|
message: '请输入账号'
|
||||||
|
}
|
||||||
],
|
],
|
||||||
code: [{ required: true, message: "请输入验证码", trigger: "blur" }],
|
passwd: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入密码'
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// rules: {
|
loading: false
|
||||||
// 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: {
|
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() {
|
async login() {
|
||||||
this.$refs.ruleForm
|
this.$refs.ruleForm.validate(async (valid) => {
|
||||||
.validate()
|
if (valid) {
|
||||||
.then((res) => {
|
this.loading = true
|
||||||
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 {
|
try {
|
||||||
const res = await postReq(paramsDate, "/user/login");
|
const res = await this.$http.post('/login', this.form)
|
||||||
|
this.loading = false
|
||||||
// 记住密码
|
if (res.code === 200) {
|
||||||
|
this.$message.success('登录成功')
|
||||||
if (res.code == 200) {
|
localStorage.setItem('token', res.token)
|
||||||
const { token, user } = res.data;
|
this.$router.push('/main')
|
||||||
this.$openNotification({
|
|
||||||
name: "",
|
|
||||||
type: "",
|
|
||||||
status: "success",
|
|
||||||
desc: "登录成功",
|
|
||||||
});
|
|
||||||
localStorage.setItem("token", token);
|
|
||||||
localStorage.setItem("showNotice", true);
|
|
||||||
|
|
||||||
// this.changeTheme();
|
|
||||||
this.getUserRoute(user);
|
|
||||||
} else {
|
} else {
|
||||||
this.loading = false;
|
this.$message.error(res.message || '登录失败')
|
||||||
throw new Error(res);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loading = false;
|
this.loading = false
|
||||||
this.form.code = "";
|
this.$message.error('请求失败,请稍后重试')
|
||||||
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 {
|
} else {
|
||||||
if (!itemMap[item.parentId]) {
|
// console.log("表单验证失败");
|
||||||
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.login {
|
.login {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-width: 1440px;
|
min-width: 1440px;
|
||||||
min-height: 900px;
|
min-height: 900px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-image: url("@/assets/images/loginBg.png");
|
background-image: url('@/assets/images/loginBg.png');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|
||||||
.main-title {
|
.main-title {
|
||||||
background: linear-gradient(
|
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(40, 235, 231, 1) 100%);
|
||||||
180deg,
|
|
||||||
rgba(255, 255, 255, 1) 0%,
|
|
||||||
rgba(40, 235, 231, 1) 100%
|
|
||||||
);
|
|
||||||
color: transparent;
|
color: transparent;
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
font-weight: 400;
|
font-weight: 600;
|
||||||
letter-spacing: 5px;
|
letter-spacing: 5px;
|
||||||
line-height: 53px;
|
line-height: 53px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-content {
|
.login-content {
|
||||||
width: 390px;
|
width: 540px;
|
||||||
|
height: 370px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
padding: 0 40px;
|
padding: 0 40px;
|
||||||
|
margin-top: 120px;
|
||||||
|
background-image: url('@/assets/images/loginFrom.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
.ant-form {
|
||||||
|
margin-top: 30px;
|
||||||
|
width: 330px;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 10px;
|
// margin-bottom: 10px;
|
||||||
|
margin-top: 60px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
:deep(.ant-input-prefix) {
|
:deep(.ant-input-prefix) {
|
||||||
color: #217575;
|
color: #fff;
|
||||||
}
|
}
|
||||||
:deep(.ant-form-item) {
|
:deep(.ant-form-item) {
|
||||||
margin-bottom: 20px !important;
|
margin-bottom: 20px !important;
|
||||||
@@ -373,22 +179,21 @@ export default {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.ant-checkbox-wrapper:hover {
|
.ant-checkbox-wrapper:hover {
|
||||||
color: #065758;
|
color: #143d7d;
|
||||||
}
|
}
|
||||||
span:hover {
|
span:hover {
|
||||||
color: #065758;
|
color: #143d7d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-btn {
|
.login-btn {
|
||||||
width: 335px;
|
width: 335px;
|
||||||
height: 45px;
|
height: 40px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #2a82e4;
|
background: #2a82e4;
|
||||||
|
border: none !important;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
.btn-text {
|
color: #fff;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.copyright {
|
.copyright {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -400,42 +205,18 @@ export default {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.ant-input) {
|
.ant-input-affix-wrapper {
|
||||||
|
background: none !important;
|
||||||
|
height: 40px;
|
||||||
|
:deep(.ant-input) {
|
||||||
|
background: none !important;
|
||||||
|
color: #fff;
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
// font-size: 12px !important;
|
color: var(--theme-text6) !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;
|
|
||||||
}
|
}
|
||||||
|
:deep(.anticon){
|
||||||
&:hover {
|
color: #fff ;
|
||||||
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>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home">
|
<div class="main">
|
||||||
<img alt="Vue logo" src="../assets/logo.png" />
|
<div class="header"></div>
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App" />
|
<div class="menu"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
// @ is an alias to /src
|
// @ is an alias to /src
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "HomeView",
|
name: "MainView",
|
||||||
components: {},
|
components: {},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,52 +1,53 @@
|
|||||||
const { defineConfig } = require("@vue/cli-service");
|
const { defineConfig } = require('@vue/cli-service')
|
||||||
const path = require("path");
|
const path = require('path')
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
transpileDependencies: true,
|
transpileDependencies: true,
|
||||||
publicPath: process.env.NODE_ENV === "production" ? "/your-project/" : "/",
|
publicPath: '/',
|
||||||
// 输出文件目录
|
// 输出文件目录
|
||||||
outputDir: "dist",
|
outputDir: 'dist',
|
||||||
|
|
||||||
// 静态资源目录
|
// 静态资源目录
|
||||||
assetsDir: "static",
|
assetsDir: 'static',
|
||||||
devServer: {
|
devServer: {
|
||||||
|
hot: true,
|
||||||
|
compress: true,
|
||||||
|
allowedHosts: 'all',
|
||||||
headers: {
|
headers: {
|
||||||
// 1. 允许开发环境跨域
|
// 1. 允许开发环境跨域
|
||||||
"Access-Control-Allow-Origin": "*",
|
'Access-Control-Allow-Origin': '*'
|
||||||
},
|
},
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
open: true,
|
open: false,
|
||||||
port: 8080,
|
port: 8080,
|
||||||
|
|
||||||
client: {
|
client: {
|
||||||
overlay: {
|
overlay: {
|
||||||
runtimeErrors: (error) => {
|
runtimeErrors: (error) => {
|
||||||
const ignoreErrors = [
|
const ignoreErrors = [
|
||||||
"ResizeObserver loop limit exceeded",
|
'ResizeObserver loop limit exceeded',
|
||||||
"ResizeObserver loop completed with undelivered notifications.",
|
'ResizeObserver loop completed with undelivered notifications.'
|
||||||
];
|
]
|
||||||
if (ignoreErrors.includes(error.message)) {
|
if (ignoreErrors.includes(error.message)) {
|
||||||
return false;
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
loaderOptions: {
|
loaderOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
additionalData: `@use "~@/style/color.scss";`,
|
additionalData: `@use "~@/style/color.scss";`
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
filename: `css/.[contenthash:8].css`,
|
filename: `css/.[contenthash:8].css`,
|
||||||
chunkFilename: `css/.[contenthash:8].chunk.css`,
|
chunkFilename: `css/.[contenthash:8].chunk.css`
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
// webpack相关配置
|
// webpack相关配置
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
// 自定义打包入口
|
// 自定义打包入口
|
||||||
entry: "./src/main.js",
|
|
||||||
|
|
||||||
// 扩展 webpack 配置
|
// 扩展 webpack 配置
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -54,13 +55,13 @@ module.exports = defineConfig({
|
|||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
"@": path.join(__dirname, "src"),
|
'@': path.join(__dirname, 'src')
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
|
// 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
|
||||||
lintOnSave: process.env.NODE_ENV !== "production",
|
lintOnSave: process.env.NODE_ENV !== 'production',
|
||||||
|
|
||||||
// 是否使用包含运行时编译器的 Vue 构建版本
|
// 是否使用包含运行时编译器的 Vue 构建版本
|
||||||
runtimeCompiler: false,
|
runtimeCompiler: false,
|
||||||
@@ -71,5 +72,5 @@ module.exports = defineConfig({
|
|||||||
// 第三方插件配置
|
// 第三方插件配置
|
||||||
pluginOptions: {
|
pluginOptions: {
|
||||||
// ...
|
// ...
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user