qiyunfeng-create
3 天以前 5f00696dfb25bc90034448ceb634ed1ef256681a
src/layout/components/login.vue
New file
@@ -0,0 +1,845 @@
<template>
  <el-dialog
    align-center
    append-to-body
    v-model="dialogFormVisible"
    @close="closeDialog"
    @open="openDialog"
    class="fansdialog"
  >
    <div style="display: flex; justify-content: space-around">
      <el-image :src="dialogLeftImg" class="leftImg" />
      <div class="logIn">
        <div class="signUpTitle" v-if="flag == 'logIn'">
          <ul>
            <li
              @click="signUpWay = 'authSignUp'"
              :style="{
                color: signUpWay == 'authSignUp' ? '#144941' : '#545C63',
              }"
            >
              手机号登录
            </li>
            <li>|</li>
            <li
              @click="wechatLoginOpen"
              :style="{ color: signUpWay == 'wechat' ? '#144941' : '#545C63' }"
            >
              微信登录
            </li>
          </ul>
        </div>
        <div v-else style="text-align: center; color: #144941">注册</div>
        <div
          class="singUpPhone"
          v-if="signUpWay === 'phone' || 'authSignUp'"
          :style="{ height: signUpWay == 'findPassword' ? '450px' : '400px' }"
        >
          <el-form
            :model="passFormData"
            v-if="signUpWay === 'phone' || 'authSignUp'"
            ref="passFormRef"
            @keyup.enter="signInSystem(passFormRef)"
          >
            <el-form-item
              v-if="signUpWay !== 'findPassword'"
              :rules="[
                { min: 11, max: 11, message: '请输入11位电话号码' },
                {
                  validator: (_, value, callback) => {
                    if (
                      !/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(
                        value
                      )
                    ) {
                      callback('请输入11位电话号码');
                    } else {
                      callback();
                    }
                  },
                },
              ]"
              prop="telNumber"
            >
              <el-input
                v-model="passFormData.telNumber"
                placeholder="请输入手机号"
                size="large"
              >
                <template #prepend>
                  <el-select
                    v-model="select"
                    placeholder="Select"
                    style="width: 110px"
                    class="selectPhone"
                  >
                    <el-option label="中国+86" value="86" />
                  </el-select>
                </template>
              </el-input>
            </el-form-item>
            <el-form-item>
              <el-button class="yanzhengBtn" @click="sliderImgDialogVisable = true"
                >验证</el-button
              >
            </el-form-item>
            <el-form-item
              v-if="signUpWay === 'authSignUp'"
              class="codeWay"
              :rules="[
                { required: true, message: '请输入验证码' },
                { min: 4, max: 6, message: '请输入有效验证码' },
              ]"
              prop="telCode"
            >
              <el-input
                v-model="passFormData.telCode"
                placeholder="请输入验证码"
                size="large"
              />
              <el-button
                type="primary"
                class="codeBtn"
                :disabled="countDown != 0"
                @click="getCode(passFormRef)"
                >{{
                  countDown == 0 ? "获取验证码" : "验证码(" + countDown + "s)"
                }}</el-button
              >
            </el-form-item>
            <el-form-item
              v-if="flag === 'signUp'"
              :rules="[
                { required: true, message: '请输入密码' },
                { min: 8, max: 16, message: '密码在8到16位之间' },
                {
                  validator: (rule, value, callback) => {
                    if (!/\d/.test(value) || /^\d+$/.test(value)) {
                      callback('密码不能为纯数字或字母');
                    } else {
                      callback();
                    }
                  },
                },
              ]"
              prop="password"
              class="passwordInput"
            >
              <el-input
                type="password"
                show-password
                v-model="passFormData.password"
                placeholder="请输入密码"
                size="large"
                style="width: 304px"
              >
              </el-input>
            </el-form-item>
            <el-form-item
              v-if="flag === 'signUp'"
              :rules="[
                { required: true, message: '请输入确认密码' },
                { validator: validateLogInPassword },
              ]"
              prop="confirmPassword"
              class="passwordInput"
            >
              <el-input
                type="password"
                show-password
                v-model="passFormData.confirmPassword"
                placeholder="确认密码"
                size="large"
                style="width: 304px"
              />
            </el-form-item>
          </el-form>
          <el-button class="loginBtn" @click="loginBtn">登录</el-button>
        </div>
      </div>
    </div>
    <el-dialog
      v-model="sliderImgDialogVisable"
      align-center
      destroy-on-close="true"
      width="420"
      class="sliderImgDialog"
    >
      <verify :MG="MG" @loginImgVerify="loginImgVerify"></verify>
    </el-dialog>
  </el-dialog>
</template>
<script setup>
import { ref, inject, watchEffect, reactive, nextTick } from "vue";
import dialogLeftImg from "@/assets/images/header/dialogLeftImg.png";
import verify from "@/components/sliderImg/component/verify.vue";
import "@/components/sliderImg/sliderImg.js";
import "@/components/sliderImg/sliderImg.css";
import { ElMessage } from "element-plus";
import { useUserStore } from "@/store";
import { useRouter } from "vue-router";
const router = useRouter();
const userStore = useUserStore();
const MG = inject("MG");
const config = inject("config");
const dialogFormVisible = ref(false);
const sliderImgDialogVisable = ref(false);
const flag = ref("logIn"); // 登录或注册
const signUpWay = ref("authSignUp"); // 登录方式
const select = ref("中国+86");
const countDown = ref(0); // 倒计时时间
let timer = null; // 倒计时实例
const passFormRef = ref();
const passFormData = ref({
  telNumber: "",
  password: "",
  telCode: "",
  password: "",
  confirmPassword: "",
});
const closeDialog = () => {
  countDown.value = 0;
  clearInterval(timer);
  if (passFormRef.value) {
    passFormRef.value.resetFields();
  }
  dialogFormVisible.value = false;
};
// 弹窗打开事件
const openDialog = () => {};
const loginImgVerify = (code) => {
  sliderImgDialogVisable.value = false;
  MG.identity
    .getPhoneCode({
      phoneNumber: passFormData.value.telNumber,
      imageCaptcha: code,
      appRefCode: config.appRefCode,
    })
    .then((res) => {
      if (res == "验证码发送成功") {
        getSecond(60);
        ElMessage.success(res);
      } else {
        ElMessage.error(res);
      }
    });
};
watchEffect(() => {
  if (dialogFormVisible.value) {
  }
});
//登录
const loginBtn = () => {
  let query = {
    phoneNumber: passFormData.value.telNumber,
    phoneCaptcha: passFormData.value.telCode,
    appRefCode: config.appRefCode,
    platform: "string",
  };
  MG.identity.loginByMobilePhone(query).then((res) => {
    console.log("res", res);
    userStore.setToken(res.data.accessToken);
    getUserInfo();
  });
};
const getUserInfo = () => {
  MG.identity.getCurrentAppUser().then((res) => {
    console.log("res", res);
    if (res) {
      let userInfo = res.infoList.find((item) => item.type == "userInfo");
      let userTypeObj = res.infoList.find((item) => item.type == "userType");
      const userData = {
        userName: userInfo && userInfo.data ? JSON.parse(userInfo.data).name : "",
        school: userInfo && userInfo.data ? JSON.parse(userInfo.data).school : "",
        city: userInfo && userInfo.data ? JSON.parse(userInfo.data).city : "",
        cityCode: userInfo && userInfo.data ? JSON.parse(userInfo.data).cityCode : "",
        address: userInfo && userInfo.data ? JSON.parse(userInfo.data).address : "",
        userType:
          userTypeObj && userTypeObj.data ? JSON.parse(userTypeObj.data).userType : "",
      };
      localStorage.setItem("xiehe-isUserInfo", userData?.userType == "" ? "-1" : "1");
      let teacherRole = res.roleLinks.find((item) => item.role.refCode == "teacher");
      let teacherInfos = res.infoList.find((item) => item.type == "teacherInfo");
      let wechatInfo = res.infoList.find((item) => item.type == "WeChat");
      let studentInfo = res.infoList.find((item) => item.type == "Default");
      let phoneInfo = res.secretList.find((item) => item.type == "MobilePhone");
      // let nameAndPassword = res.secretList.find((item) => item.type == 'LoginNameAndPassword')
      let emailInfo = res.secretList.find((item) => item.type == "EMail");
      if (teacherRole && teacherInfos) {
        userStore.setUserInfo({
          ...userData,
          ...teacherInfos,
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo ? emailInfo.credential : JSON.parse(teacherInfos.data).email,
          icon: wechatInfo?.icon,
          role: "Teacher",
          roleId: teacherRole.role.id,
          userId: res.userId,
        });
      } else if (wechatInfo) {
        userStore.setUserInfo({
          ...userData,
          ...wechatInfo,
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo?.credential,
          role: "Student",
          userId: res.userId,
        });
      } else if (studentInfo) {
        userStore.setUserInfo({
          ...userData,
          ...studentInfo,
          icon: wechatInfo?.icon,
          phoneNumber: phoneInfo?.credential,
          Email: emailInfo?.credential,
          role: "Student",
          userId: res.userId,
        });
      } else if (phoneInfo) {
        userStore.setUserInfo({
          ...userData,
          ...phoneInfo,
          name: phoneInfo?.credential,
          icon: phoneInfo?.icon,
          phoneNumber: phoneInfo?.credential,
          role: "Student",
          userId: res.userId,
        });
      }
    }
    router.go(0);
  });
};
// 倒计时
const getSecond = (time) => {
  if (!timer) {
    countDown.value = time;
    timer = setInterval(() => {
      countDown.value--;
      if (countDown.value == 0) {
        clearInterval(timer);
        timer = null;
      }
    }, 1000);
  }
};
// 登录和重置密码按钮按钮
const signInSystem = async (formEl) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      // if (signUpWay.value === 'phone') {
      //   // 账号密码登录
      //   passwordSignUp()
      // } else if (signUpWay.value == 'authSignUp') {
      //   // 验证码登录
      //   codeSignUp()
      // } else {
      //   // 重置密码
      //   changePassword()
      // }
    }
  });
};
const logIn = () => {
  dialogFormVisible.value = true;
  flag.value = "logIn";
};
// 打开注册弹窗
const signUp = () => {
  dialogFormVisible.value = true;
  flag.value = "signUp";
};
const wechatLoginOpen = () => {
  signUpWay.value = "wechat";
};
defineExpose({
  logIn,
  signUp,
});
</script>
<style lang="less" scoped>
// 用户信息填写界面
.changeUser {
  .prompt-title {
    width: 80%;
    line-height: 24px;
    color: #000;
    span {
      display: inline-block;
    }
  }
}
.fansdialog {
  width: 806px;
  .leftImg {
    box-sizing: border-box;
    width: 403px;
  }
  .el-dialog__header {
    padding: 0;
  }
  .el-dialog__body {
    width: 806px;
    height: 575px;
    display: flex;
    padding: 0 !important;
  }
  .leftImg {
    .el-image__inner {
      width: 403px;
    }
  }
  .el-dialog__header {
    padding: 0;
  }
  .el-dialog__body {
    width: 806px;
    display: flex;
    padding: 0 !important;
  }
}
.agreementDialog {
  width: 760px;
  height: 600px;
  p span {
    line-height: 24px;
  }
  .el-dialog__header {
    font-size: 18px;
    color: #333;
  }
  .el-dialog__body {
    overflow: auto;
    height: 500px;
    width: 760px;
  }
  .el-dialog__footer {
    display: flex;
    justify-content: center;
  }
}
.wechatTipsDialog {
  .el-dialog__header {
    font-size: 18px;
  }
  .el-dialog__body {
    display: flex;
    align-items: center;
    p {
      margin-left: 10px;
      line-height: 24px;
    }
  }
}
.sliderImgDialog {
  .el-dialog__body {
    min-height: 320px;
  }
}
</style>
<style lang="less">
/** 登录注册弹窗 */
.logIn {
  width: 403px;
  height: 100%;
  padding-top: 48px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  .signUpTitle {
    width: 100%;
    ul {
      display: flex;
      justify-content: center;
      width: 100%;
      li {
        height: 20px;
        display: flex;
        align-items: center;
        .el-image {
          margin-right: 5px;
          width: 20px;
        }
      }
      li:nth-child(2n + 1) {
        cursor: pointer;
        margin: 0 10px;
      }
      li:first-child {
        margin-left: 0;
        .el-image {
          width: 10px;
        }
      }
    }
  }
  /** 微信登录 */
  .signUpContent {
    display: flex;
    height: 400px;
    flex-wrap: wrap;
    flex-direction: column;
    justify-content: space-around;
    align-content: center;
    .el-image {
      width: 176px;
    }
    h2 {
      font-size: 20px;
      color: #000;
      font-weight: 700;
      text-align: center;
    }
    p {
      text-align: center;
      line-height: 26px;
    }
    .wechatCode {
      h2 {
        margin-bottom: 24px;
      }
    }
  }
  /** 密码登录 */
  .singUpPhone {
    height: 400px;
    display: flex;
    flex-direction: column;
    align-items: center;
    h2 {
      padding-top: 35px;
      font-size: 20px;
      color: #000;
      font-weight: 700;
      text-align: center;
    }
    .back {
      display: flex;
      align-items: center;
      cursor: pointer;
      margin: 10px 0px 0px 20px;
      align-self: flex-start;
      font-size: 12px;
      color: #333;
    }
    .el-form {
      margin-top: 26px;
    }
    .signInBtn {
      width: 304px;
      height: 41px;
      margin-bottom: 33px;
      border-radius: 3px;
      // opacity: 0.55;
      color: #fff;
      font-size: 14px;
    }
    .codeBtn {
      width: 101px;
      height: 41px;
      background-color: #019e58;
      // opacity: 0.55;
    }
    .yanzhengBtn {
      width: 100%;
      height: 41px;
      background-color: #019e58;
      color: #fff;
    }
    .loginBtn {
      width: 76%;
      height: 41px;
      background: linear-gradient(90deg, #019e58 0%, #144941 100%);
      color: #fff;
      margin-top: 50px;
    }
    .el-image {
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    .authSignUp {
      width: 305px;
      flex: 1;
      display: flex;
      justify-content: end;
      align-items: end;
      padding-bottom: 20px;
      span {
        cursor: pointer;
        color: #333;
        font-size: 12px;
      }
    }
    .codeWay {
      .el-input {
        width: 195px;
      }
      .el-button {
        width: 100px;
        padding: 0;
        margin: 0 0 0 10px;
      }
      .authCodeBox {
        width: 100px;
        height: 50px;
        margin-left: 10px;
        cursor: pointer;
        position: relative;
        span {
          position: absolute;
          top: 35px;
          height: 10px;
          margin-bottom: 20px;
          font-size: 10px;
          color: #1f971f;
        }
      }
    }
  }
  .claus {
    margin-bottom: 10px;
    color: #000;
    font-size: 12px;
    width: 100%;
    text-align: center;
    line-height: 26px;
  }
}
.policy {
  cursor: pointer;
  color: #ff6c00;
}
/** 注册表单 */
.signUp {
  width: 403px;
  justify-content: space-around;
  color: #333;
  font-size: 12px;
  span:first-child,
  span:last-child {
    cursor: pointer;
  }
  .logInTitle {
    width: 96%;
    font-size: 16px;
    margin: 20px 0 0 20px;
    font-weight: bold;
  }
  h4 {
    font-size: 16px;
    color: #ff6c00;
  }
  .logInBox {
    margin-top: 20px;
    padding: 0 40px;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    .el-form-item {
      .el-button {
        width: 100px;
        height: 41px;
        border-radius: 3px;
        color: #fff;
        font-size: 14px;
      }
    }
    .agreement {
      height: 40px;
      display: flex;
      align-items: center;
      margin: 30px 0 0 0;
      line-height: 32px;
      height: 32px;
      font-size: 12px;
      color: #000;
      .el-checkbox {
        margin-right: 10px;
      }
      .el-link {
        font-size: 12px;
      }
      p {
        height: 100%;
        display: flex;
        align-items: center;
      }
    }
    .hint {
      font-size: 11px;
      color: #545c63;
    }
    .codeWay {
      .el-input {
        width: 195px;
      }
      .el-button {
        width: 100px;
        padding: 0;
        margin: 0 0 0 10px;
      }
      .authCodeBox {
        width: 100px;
        height: 50px;
        margin-left: 10px;
        cursor: pointer;
        position: relative;
        span {
          position: absolute;
          top: 35px;
          left: 0;
          width: 100px;
          font-size: 10px;
          color: #1f971f;
        }
      }
    }
  }
  .logInBtn {
    width: 304px;
    height: 41px;
    margin-top: 10px;
    margin-bottom: 20px;
    border-radius: 3px;
    color: #fff;
    font-size: 14px;
  }
  /** 选择用户类型 */
  .changeUser {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    .el-form-item {
      &:last-child {
        margin-bottom: 0;
      }
      .el-button {
        height: 40px;
        margin-left: 10px;
      }
    }
    h2 {
      font-size: 20px;
      margin-top: 70px;
      color: #000;
      font-weight: bold;
    }
    .el-radio-group {
      display: flex;
      flex-direction: column;
      .el-radio-button {
        width: 166px;
      }
      /deep/ .el-radio-button__inner {
        width: 166px;
        height: 41px;
        line-height: 24px;
        border-radius: 4px;
        border: 0;
        border: 1px solid #dcdfe6;
      }
      .el-radio-button:nth-child(n + 1) {
        margin-bottom: 27px;
      }
    }
  }
}
.selectPhone {
  background: #fff;
}
// .el-select {
//   width: 100px;
//   height: 30px;
//   color: red;
//   border: none !important;
//   /deep/ .select-trigger {
//     height: 100%;
//     .el-input--suffix {
//       height: 100%;
//       background-color: #fff;
//     }
//   }
// }
</style>