web
2025-03-17 56d13900e2d74eeb9e22a9d86dc929640a676f6f
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>