From 56d13900e2d74eeb9e22a9d86dc929640a676f6f Mon Sep 17 00:00:00 2001
From: web <candymxq888@outlook.com>
Date: 星期一, 17 三月 2025 17:21:43 +0800
Subject: [PATCH] fix:修改框架,初始化项目模板

---
 src/views/login.vue |  528 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 311 insertions(+), 217 deletions(-)

diff --git a/src/views/login.vue b/src/views/login.vue
index a590622..b2d1e8a 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -1,277 +1,371 @@
 <template>
-  <div class="login">
-    <div class="login-bcg1"></div>
-    <div class="contain">
-    <el-form  ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-      <h3 class="title">金川水电站生态流量监测系统</h3>
-      <el-form-item label="账 号" prop="userName">
-        <el-input
-          style="height: 45px;"
-          v-model="loginForm.userName"
-          type="text"
-          auto-complete="off"
-          placeholder="账号"
-        >
-          <!-- <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> -->
-        </el-input>
-      </el-form-item>
-      <el-form-item label="密 码" prop="password">
-        <el-input
-          style="height: 45px;"
-          v-model="loginForm.password"
-          :type="isPassword"
-          size="large"
-          auto-complete="off"
-          placeholder="密码"
-          @keyup.enter="handleLogin"
-        >
-        <template #suffix>
-            <div @click="showPassword"><svg-icon :icon-class="eyeView"/></div>
-        </template>
-        </el-input>
-      </el-form-item>
-      <el-checkbox class="check-box" v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
-      <el-form-item >
-        <el-button
-          :loading="loading"
-          size="large"
-          type="primary"
-          style="width:100%;"
-          @click.prevent="handleLogin"
-        >
-          <span v-if="!loading">登 录</span>
-          <span v-else>登 录 中...</span>
-        </el-button>
-      </el-form-item>
-    </el-form>
-    <img src="../assets/images/login/login_icon.png"/>
+    <div class="login">
+        <div class="login-bcg1"></div>
+        <div class="contain">
+            <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"
+                     @keydown.enter="handleLogin">
+                <h3 class="title">金川水电站生态流量监测系统</h3>
+                <el-form-item label="账号" prop="userName">
+                    <el-input
+                        style="height: 45px;"
+                        v-model="loginForm.userName"
+                        type="text"
+                        auto-complete="off"
+                        placeholder="账号"
+                    >
+                        <!-- <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> -->
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="密码" prop="password">
+                    <el-input
+                        style="height: 45px;"
+                        v-model="loginForm.password"
+                        :type="isPassword"
+                        size="large"
+                        auto-complete="off"
+                        placeholder="密码"
+                    >
+                        <template #suffix>
+                            <div @click="showPassword">
+                                <svg-icon :icon-class="eyeView"/>
+                            </div>
+                        </template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="验证码" prop="code">
+                    <div class="yzm-box">
+                        <el-input
+                            style="height: 45px;"
+                            v-model="loginForm.code"
+                            size="large"
+                            auto-complete="off"
+                            placeholder="验证码"
+                        >
+                        </el-input>
+                        <div class="yzm" @click="resetCode">
+                            <img v-if="codeUrl" :src="codeUrl" alt=""/>
+                            <div v-else class="code-none">无法加载</div>
+                        </div>
+                    </div>
+                </el-form-item>
+                <el-checkbox class="check-box" v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">
+                    记住密码
+                </el-checkbox>
+                <el-form-item>
+                    <el-button
+                        :loading="loading"
+                        size="large"
+                        type="primary"
+                        style="width:100%;"
+                        @click.prevent="handleLogin"
+                    >
+                        <span v-if="!loading">登 录</span>
+                        <span v-else>登 录 中...</span>
+                    </el-button>
+                </el-form-item>
+            </el-form>
+            <img class="left-img" src="../assets/images/login/login_icon.png"/>
+        </div>
+        <!--  底部  -->
+        <div class="footer">
+            <span>苏州伦晗电子有限公司.</span>
+        </div>
     </div>
-    <!--  底部  -->
-    <div class="footer">
-      <span>苏州伦晗电子有限公司.</span>
-    </div>
-  </div>
 </template>
 
 <script setup>
-// import { getCodeImg } from "@/api/login";
+import {onMounted} from 'vue';
 import Cookies from "js-cookie";
-import { encrypt, decrypt } from "@/utils/jsencrypt";
+import {encrypt, decrypt} from "@/utils/jsencrypt";
 import useUserStore from '@/store/modules/user';
 import usePermissionStore from '@/store/modules/permission';
-import { addActiveRoute } from '@/utils/index';
-import { setToken } from '@/utils/auth';
-import { useRouter, useRoute } from 'vue-router';
-import { login } from '@/api/login';
+import {addActiveRoute} from '@/utils/index';
+import {setToken} from '@/utils/auth';
+import {useRouter, useRoute} from 'vue-router';
+import {login, register, getIp} from '@/api/login';
+
 const userStore = useUserStore()
 const permissionStore = usePermissionStore()
 const route = useRoute();
 const router = useRouter();
-const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
 const isPassword = ref('password');
 const eyeView = ref('eye')
 
-const showPassword = () =>{
-    if(eyeView.value === 'eye'){
+const showPassword = () => {
+    if (eyeView.value === 'eye') {
         eyeView.value = 'eye-open'
         isPassword.value = 'text'
-    }else if(eyeView.value === 'eye-open'){
+    } else if (eyeView.value === 'eye-open') {
         eyeView.value = 'eye'
         isPassword.value = 'password'
     }
 }
-const loginForm = ref({
-  userName: "",
-  password: "",
-  rememberMe: false
+const loginForm = reactive({
+    userName: "",
+    password: "",
+    code: '',
+    uuid: '',
+    machineCode: '',
+    rememberMe: false
 });
+const codeUrl = ref('');
 const loginRules = {
-  userName: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
-  password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
+    userName: [{required: true, trigger: "blur", message: "请输入您的账号"}],
+    password: [{required: true, trigger: "blur", message: "请输入您的密码"}],
+    code: [{required: true, trigger: "blur", message: "请输入您的验证码"}],
 };
 const loading = ref(false);
 const redirect = ref(undefined);
 
 watch(route, (newRoute) => {
     redirect.value = newRoute.query && newRoute.query.redirect;
-}, { immediate: true });
+}, {immediate: true});
+
+/**
+ * 生成随机字符串uuid
+ * @param length 字符串的长度,默认11
+ * @returns {string}
+ */
+function generateRandomString(length = 11) {
+    let charset = 'abcdefghijklmnopqrstuvwxyz-_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+    let values = new Uint32Array(length);
+    window.crypto.getRandomValues(values);
+    let str = '';
+    for (let i = 0; i < length; i++) {
+        str += charset[values[i] % charset.length];
+    }
+    return str;
+}
+
+/**
+ * 获取验证码
+ */
+async function resetCode() {
+    loginForm.uuid = generateRandomString(11);
+    register(loginForm.uuid).then(res => {
+        codeUrl.value = res.data
+    })
+}
+
+/**
+ * 获取电脑标识
+ */
+async function getConputerId() {
+    const res = await getIp();
+    loginForm.machineCode = res.data;
+}
 
 //根据moduleCode获取相对应菜单
 const filterTreeMenus = (menus, userType) => {
-  let filteredMenu = [];
-  for (let item of menus) {
+    let filteredMenu = [];
+    for (let item of menus) {
         filteredMenu.push(item);
-      if (item.children && item.children.length > 0) {
-          let filteredChildren = filterTreeMenus(item.children, userType);
-          if (filteredChildren.length > 0) {
-              item.children = filteredChildren;
-          } else {
-              delete item.children;
-          }
-      }
-  }
-  return filteredMenu;
+        if (item.children && item.children.length > 0) {
+            let filteredChildren = filterTreeMenus(item.children, userType);
+            if (filteredChildren.length > 0) {
+                item.children = filteredChildren;
+            } else {
+                delete item.children;
+            }
+        }
+    }
+    return filteredMenu;
 }
 
 function handleLogin() {
-  proxy.$refs.loginRef.validate(valid => {
-    if (valid) {
-      loading.value = true;
+    proxy.$refs.loginRef.validate(valid => {
+        if (valid) {
+            loading.value = true;
 
-      //记住密码
-      if (loginForm.value.rememberMe) {
-        Cookies.set("userName", loginForm.value.userName, { expires: 30 });
-        Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 });
-        Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 });
-      } else {
-        //移除
-        Cookies.remove("userName");
-        Cookies.remove("password");
-        Cookies.remove("rememberMe");
-      }
-      const userInfo = {
-        userName:loginForm.value.userName.trim(),
-        password: loginForm.value.password
-      }
-      login(userInfo).then(async(res) => {
-        loading.value = false;
-        setToken(res.data.token)
-        
-        //普通管理员筛除菜单、权限、数据字典,普通用户筛除系统管理
-        if(res.data.userType == 2){
-            res.data.menus.forEach((item,index) =>{
-              if(item.id == '10001'){
-                item.children.forEach((itemChild,childIndex) =>{
-                  if(itemChild.id == '10101' || itemChild.id == '10102' || itemChild.id == '1822894922704416770'){
-                    item.children.splice(childIndex,1)
-                  }
-                })
-              }
+            //记住密码
+            if (loginForm.rememberMe) {
+                Cookies.set("userName", loginForm.userName, {expires: 30});
+                Cookies.set("password", encrypt(loginForm.password), {expires: 30});
+                Cookies.set("rememberMe", loginForm.rememberMe, {expires: 30});
+            } else {
+                //移除
+                Cookies.remove("userName");
+                Cookies.remove("password");
+                Cookies.remove("rememberMe");
+            }
+            const userInfo = {
+                userName: loginForm.userName.trim(),
+                password: loginForm.password,
+                code: loginForm.code,
+                uuid: loginForm.uuid,
+                machineCode: loginForm.machineCode,
+            }
+            login(userInfo).then(async (res) => {
+                loading.value = false;
+                setToken(res.data.token)
+
+                //普通管理员筛除菜单、权限、数据字典,普通用户筛除系统管理
+                if (res.data.userType == 2) {
+                    res.data.menus.forEach((item, index) => {
+                        if (item.id == '10001') {
+                            item.children.forEach((itemChild, childIndex) => {
+                                if (itemChild.id == '10101' || itemChild.id == '10102' || itemChild.id == '1822894922704416770') {
+                                    item.children.splice(childIndex, 1)
+                                }
+                            })
+                        }
+                    })
+                } else if (res.data.userType == 3) {
+                    res.data.menus.forEach((item, index) => {
+                        if (item.id == '10001') {
+                            res.data.menus.splice(index, 1)
+                        }
+                    })
+                }
+                console.log(123123, res.data.menus)
+                let filteredMenus = filterTreeMenus(res.data.menus, 1)
+                console.log('filterTreeMenus菜单权限过滤', filteredMenus)
+
+                permissionStore.setSidebarRouters(filteredMenus);
+                console.log('setSidebarRouters配置菜单路由项数据', permissionStore.sidebarRouters)
+
+                addActiveRoute(permissionStore, router)
+
+                localStorage.setItem('listPermission', JSON.stringify(res.data.listPermission))
+                localStorage.setItem('id', JSON.stringify(res.data.id))
+                localStorage.setItem('userType', JSON.stringify(res.data.userType))
+
+                router.push("/screen");//overview
+            }).catch(error => {
+                loading.value = false;
+                proxy.$modal.msgError('登录失败!')
             })
-          }else if(res.data.userType == 3){
-            res.data.menus.forEach((item,index) =>{
-              if(item.id == '10001'){
-                res.data.menus.splice(index,1)
-              }
-            })
-          }
-          console.log(123123,res.data.menus)
-        let filteredMenus = filterTreeMenus(res.data.menus, 1)
-        console.log('filterTreeMenus菜单权限过滤',filteredMenus)
-
-        permissionStore.setSidebarRouters(filteredMenus);
-        console.log('setSidebarRouters配置菜单路由项数据', permissionStore.sidebarRouters)
-
-        addActiveRoute(permissionStore, router)
-        
-        localStorage.setItem('listPermission',JSON.stringify(res.data.listPermission))
-        localStorage.setItem('id',JSON.stringify(res.data.id))
-        localStorage.setItem('userType',JSON.stringify(res.data.userType))
-        
-        router.push("/user");//overview
-      }).catch(error => {
-        loading.value = false;
-        proxy.$modal.msgError('登录失败!')
-      })
-    }
-  });
+        }
+    });
 }
+
 function getCookie() {
-  const userName = Cookies.get("userName");
-  const password = Cookies.get("password");
-  const rememberMe = Cookies.get("rememberMe");
-  loginForm.value = {
-    userName: userName === undefined ? loginForm.value.userName : userName,
-    password: password === undefined ? loginForm.value.password : decrypt(password),
-    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
-  };
+    const userName = Cookies.get("userName");
+    const password = Cookies.get("password");
+    const rememberMe = Cookies.get("rememberMe");
+    loginForm.userName = userName === undefined ? loginForm.userName : userName;
+    loginForm.password = password === undefined ? loginForm.password : password;
+    loginForm.rememberMe = rememberMe === undefined ? loginForm.rememberMe : rememberMe;
 }
-getCookie();
+
+onMounted(() => {
+    getCookie();
+    resetCode();
+    getConputerId()
+})
 </script>
 
 <style lang='scss' scoped>
 
-.login{
-  position: relative;
+.login {
+    position: relative;
     // justify-content: center;
     // align-items: center;
     width: 100%;
     height: 100%;
     background-image: url("../assets/images/login/login_bcg.png");
     background-size: 100% 100%;
-    .login-bcg1{
-      position: absolute;
-      height: 100%;
-      width:100%;
-      background-image: url("../assets/images/login/login_bcg1.png");
-      background-size: 100% 100%;
-    }
-    .contain{
-      position: absolute;
-      background-color: rgba(239, 245, 254, 0.75);
-      border-radius: 26px;
-      width: 76%;
-      height: 85%;
-      top: 0;  
-      right: 0;  
-      bottom: 0;  
-      left: 0;  
-      margin: auto;
-    }
-    img{
-      position: absolute;
-      width:44%;
-      height: 62%;
-      top: 16%;
-      left:-4%;
-    }
-    .login-form {
-      position: absolute;
-      width: 38%;
-      height:75%;
-      right:5%;
-      top:10%;
-      border-radius: 10px;
-      background: #ffffff;
-      padding: 25px;
-      box-shadow: 0 0 10px 4px #c4d4f7;
 
-      .title {
-        font-size: 40px;
-        margin: 10px 30px 100px;
-        text-align: center;
-        color: #000000;
+    .login-bcg1 {
+        position: absolute;
+        height: 100%;
+        width: 100%;
+        background-image: url("../assets/images/login/login_bcg1.png");
+        background-size: 100% 100%;
     }
-      .el-form-item{
-        margin: 40px auto 20px;
-        width: 85%;
-        :deep(.el-form-item__label){
-          line-height: 45px;
-          font-size: large;
-          font-weight: 500;
-        }    
-        .el-button{
-          height: 50px;
+
+    .contain {
+        position: absolute;
+        background-color: rgba(239, 245, 254, 0.75);
+        border-radius: 26px;
+        width: 76%;
+        height: 85%;
+        top: 0;
+        right: 0;
+        bottom: 0;
+        left: 0;
+        margin: auto;
+    }
+
+    .left-img {
+        position: absolute;
+        width: 44%;
+        height: 62%;
+        top: 16%;
+        left: -4%;
+    }
+
+    .login-form {
+        position: absolute;
+        width: 42%;
+        height: 80%;
+        right: 5%;
+        top: 10%;
+        border-radius: 10px;
+        background: #ffffff;
+        padding: 25px;
+        box-shadow: 0 0 10px 4px #c4d4f7;
+
+        .title {
+            font-size: 40px;
+            margin: 10px 20px 70px;
+            text-align: center;
+            color: #000000;
         }
-      }
-      .check-box{
-        width: 85%;
-        left: 50%;
-        transform:translate(-50%) ;
-      }
+        .el-form-item {
+            margin: 30px auto;
+            width: 85%;
+
+            .yzm-box{
+                width: 100%;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                :deep(.el-input){
+                    width: 60%;
+                }
+                .yzm{
+                    width: 35%;
+                    display: flex;
+                    align-items: center;
+                    img{
+                        width: 100%;
+                    }
+                }
+            }
+
+            :deep(.el-form-item__label) {
+                line-height: 45px;
+                font-size: large;
+                font-weight: 500;
+                width: 80px;
+            }
+
+            .el-button {
+                height: 50px;
+            }
+        }
+
+        .check-box {
+            width: 85%;
+            left: 50%;
+            transform: translate(-50%);
+        }
     }
 }
+
 .footer {
-  height: 40px;
-  line-height: 40px;
-  position: fixed;
-  bottom: 0;
-  width: 100%;
-  text-align: center;
-  color: #fff;
-  font-family: Arial;
-  font-size: 12px;
-  letter-spacing: 1px;
+    height: 40px;
+    line-height: 40px;
+    position: fixed;
+    bottom: 0;
+    width: 100%;
+    text-align: center;
+    color: #fff;
+    font-family: Arial;
+    font-size: 12px;
+    letter-spacing: 1px;
 }
 
 </style>

--
Gitblit v1.9.3