k94314517
2025-05-19 cdd6551b190b981b807a3b95e9635c559ccc769d
company/src/views/login.vue
@@ -1,35 +1,85 @@
<template>
  <div class="wrap">
    <div class="introduce">
      <h2>预选清单查询系统</h2>
    </div>
    <div class="login">
      <h1>系统登录&nbsp;/&nbsp;LOGIN IN</h1>
      <div class="info-input">
        <el-input v-model="username" placeholder="请输入用户名" prefix-icon="el-icon-user-solid" maxlength="50" v-trim/>
        <el-input v-model="password" placeholder="请输入密码" type="password" prefix-icon="eva-icon-password" maxlength="30" show-password/>
        <div class="captcha-input">
          <el-input v-model="captcha.value" placeholder="图片验证码" prefix-icon="eva-icon-shield" maxlength="4" @keypress.enter.native="login"/>
          <img v-if="!captcha.loading" :src="captcha.uri" @click="refreshCaptcha">
          <span v-else><i class="el-icon-loading"></i></span>
    <div class="wrap">
        <div class="introduce">
            <h2>{{systemTitle}}</h2>
        </div>
      </div>
      <el-button :loading="loading" @click="login">登&nbsp;&nbsp;录</el-button>
        <div class="login">
            <h1>系统登录&nbsp;/&nbsp;LOGIN IN</h1>
            <div class="login_type">
                <div :class="active === 1 ? 'login_type_item active' : 'login_type_item'" @click="handleClick(1)">账号登录</div>
                <div :class="active === 2 ? 'login_type_item active' : 'login_type_item'" @click="handleClick(2)">手机登录</div>
            </div>
            <div class="info-input">
                <template v-if="active === 1">
                    <el-input v-model="username" placeholder="请输入用户名" prefix-icon="el-icon-user-solid" maxlength="50" v-trim/>
                    <el-input v-model="password" placeholder="请输入密码" type="password" prefix-icon="eva-icon-password" maxlength="30" show-password/>
                    <div class="captcha-input">
                        <el-input v-model="captcha.value" placeholder="图片验证码" prefix-icon="eva-icon-shield" maxlength="4" @keypress.enter.native="login"/>
                        <img v-if="!captcha.loading" :src="captcha.uri" @click="refreshCaptcha">
                        <span v-else><i class="el-icon-loading"></i></span>
                    </div>
                </template>
                <template v-else>
                    <el-input v-model="phone" placeholder="请输入手机号" prefix-icon="el-icon-phone" maxlength="11" v-trim/>
                    <div class="captcha-input">
                        <el-input v-model="code" placeholder="请输入验证码" prefix-icon="eva-icon-shield" @keypress.enter.native="login" v-trim/>
                        <el-button type="primary" style="width: 120px; margin-left: 20px;" @click="send" v-if="num === 0">发送验证码</el-button>
                        <el-button type="primary" style="width: 120px; margin-left: 20px;" v-else>{{num}}</el-button>
                    </div>
                </template>
            </div>
          <div style="text-align: left;margin-bottom: 15px;font-size: 14px">
            <el-checkbox :true-label="1" :false-label="0"   v-model="readed"/>
              我已阅读和同意《<span @click="agreeType=0;title1='服务协议';visible1=true" style="color: dodgerblue;cursor: pointer">服务协议</span>》和
            《<span  @click="agreeType=1;title1='隐私协议';visible1=true" style="color: dodgerblue;cursor: pointer">隐私协议</span>》
          </div>
          <el-button :loading="loading" @click="login">登&nbsp;&nbsp;录</el-button>
        </div>
        <el-dialog
            class="center-title"
            :title="title1"
            width="70%"
            height="70%"
            text="用户协议"
            :visible.sync="visible1"
        >
          <div class="agree-list" v-if="agreeType==0" v-html="agreement0">
          </div>
          <div class="agree-list"  v-else v-html="agreement1">
          </div>
          <template  v-slot:footer>
            <el-button type="primary"   @click="readed=1;visible1=false">同意</el-button>
            <el-button @click="visible1=false">返回</el-button>
          </template>
        </el-dialog>
    </div>
  </div>
</template>
</template>
<script>
import { mapMutations } from 'vuex'
import { getCaptcha, loginByPassword } from '@/api/system/common'
import { getCaptcha, loginByPassword, loginByPhone } from '@/api/system/common'
import { sendSms } from '@/api/business/smsEmail'
import { getAgreement } from '@/api/system/dict'
export default {
  name: 'Login',
  data () {
    return {
      title1:'服务协议',
      systemTitle: process.env.VUE_APP_SYSTEM_TITLE,
      loading: false,
      username: '',
      password: '',
      phone: '',
      visible1:false,
      code: '',
      readed: 0,
      agreeType:'',
      active: 1,
      num: 0,
      timer: null,
      agreement0: '这是服务协议',
      agreement1: '这是隐私协议',
      // 验证码
      captcha: {
        loading: false,
@@ -41,31 +91,103 @@
  },
  methods: {
    ...mapMutations(['setUserInfo']),
    handleClick (e) {
      this.active = e
      this.username = ''
      this.password = ''
      this.phone = ''
      this.code = ''
    },
    getAgree () {
      getAgreement({}).then(res => {
        if (res && res.length >= 2) {
          this.agreement0 = res[0]
          this.agreement1 = res[1]
        }
      })
    },
    send () {
      if (!this.phone) {
        this.$message.warning('请先输入手机号')
        return
      }
      var reg = /^1[3456789]\d{9}$/
      if (!reg.test(this.phone)) {
        this.$message.warning('手机号不合法')
        return
      }
      sendSms({
        phone: this.phone
      }).then(res => {
        this.num = 60
        this.setTimer()
      })
    },
    setTimer () {
      this.timer = setInterval(() => {
        if (this.num === 0) {
          this.num = 0
          clearInterval(this.timer)
          this.timer = null
          return
        }
        this.num -= 1
      }, 1000)
    },
    // 登录
    login () {
      if (this.loading) {
        return
      }
      if (!this.__check()) {
      if (this.readed !== 1) {
        this.$message.error('请先阅读和同意《服务协议》和《隐私协议》')
        return
      }
      this.loading = true
      loginByPassword({
        username: this.username.trim(),
        password: this.password,
        code: this.captcha.value.trim(),
        uuid: this.captcha.uuid
      })
        .then(() => {
          window.location.href = process.env.VUE_APP_CONTEXT_PATH
      if (this.active === 1) {
        if (!this.__check()) {
          return
        }
        this.loading = true
        loginByPassword({
          username: this.username.trim(),
          password: this.password,
          code: this.captcha.value.trim(),
          uuid: this.captcha.uuid
        })
        .catch(e => {
          this.refreshCaptcha()
          this.$tip.apiFailed(e)
          .then(() => {
            window.location.href = process.env.VUE_APP_CONTEXT_PATH
          })
          .catch(e => {
            this.refreshCaptcha()
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.loading = false
          })
      } else {
        if (!this.phone) {
          this.$tip.error('请输入手机号')
          return
        }
        if (!this.code) {
          this.$tip.error('请输入验证码')
          return
        }
        this.loading = true
        loginByPhone({
          phone: this.phone,
          code: this.code.trim()
        })
        .finally(() => {
          this.loading = false
        })
          .then(() => {
            window.location.href = process.env.VUE_APP_CONTEXT_PATH
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
          .finally(() => {
            this.loading = false
          })
      }
    },
    // 刷新验证码
    refreshCaptcha () {
@@ -103,108 +225,149 @@
  },
  created () {
    this.refreshCaptcha()
    this.getAgree()
    document.title = this.systemTitle
  }
}
</script>
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
$input-gap: 30px;
.wrap {
  display: flex;
  width: 100%;
  height: 100vh;
  background-image: url("../assets/images/login.jpg");
  background-repeat: no-repeat;
  background-size: auto 180%;
  background-clip: content-box;
  background-position: center;
  // 左边介绍
  .introduce {
    padding-left: 10%;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    color: #fff;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    flex-direction: column;
    justify-content: center;
    h2 {
      font-size:34px;
      font-style: italic;
      font-weight: 900;
      margin-top: 50px;
    @import "@/assets/style/variables.scss";
    .agree-list{
      height: 550px;
      //max-height: 50%;
      overflow: auto;
    }
    h3 {
      font-size: 49px;
      font-weight: 300;
      margin: 25px 0;
    }
  }
  // 右边登录
  .login {
    height: 100%;
    width: 38%;
    max-width: 560px;
    min-width: 460px;
    flex-shrink: 0;
    text-align: center;
    background: #fff;
    padding: 0 80px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    box-sizing: border-box;
    h1 {
      font-size: 28px;
      font-weight: 500;
    }
    .info-input {
      margin-top: $input-gap;
      margin-bottom: 60px;
      /deep/ .el-input {
        margin-top: 30px;
        .el-input__inner {
          height: 50px;
          background: #F9F9F9;
          border: 1px solid transparent;
          &:focus {
            border: 1px solid $primary-color;
          }
        }
      }
    }
    // 验证码输入
    .captcha-input {
      display: flex;
      margin-top: $input-gap;
      height: 50px;
      .el-input {
        width: 100%;
        margin-top: 0;
      }
      span, img {
        width: 45%;
        height: 100%;
        flex-shrink: 0;
        margin-left: 16px;
      }
      span {
    $input-gap: 30px;
    .wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        background: #f7f7f7;
        border-radius: 8px;
      }
        width: 100%;
        height: 100vh;
        background-image: url("../assets/images/login.jpg");
        background-repeat: no-repeat;
        background-size: auto 180%;
        background-clip: content-box;
        background-position: center;
        // 左边介绍
        .introduce {
            padding-left: 10%;
            width: 100%;
            height: 100%;
            box-sizing: border-box;
            color: #fff;
            background: rgba(0, 0, 0, 0.4);
            display: flex;
            flex-direction: column;
            justify-content: center;
            h2 {
                font-size:34px;
                font-style: italic;
                font-weight: 900;
                margin-top: 50px;
            }
            h3 {
                font-size: 49px;
                font-weight: 300;
                margin: 25px 0;
            }
        }
        // 右边登录
        .login {
            height: 100%;
            width: 38%;
            max-width: 560px;
            min-width: 460px;
            flex-shrink: 0;
            text-align: center;
            background: #fff;
            padding: 0 80px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            box-sizing: border-box;
            h1 {
                font-size: 28px;
                font-weight: 500;
            }
            .login_type {
                width: 100%;
                height: 50px;
                display: flex;
                align-items: center;
                margin: 20px 0;
                .active {
                    box-sizing: border-box;
                    color: rgba(64, 106, 255, 0.996) !important;
                    border-bottom: 1px solid rgba(64, 106, 255, 0.996) !important;
                }
                .login_type_item {
                    flex: 1;
                    height: 100%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    color: black;
                    font-size: 14px;
                    cursor: pointer;
                }
            }
            .info-input {
                margin-bottom: 15px;
                /deep/ .el-input {
                    margin-top: 30px;
                    &:first-child {
                        margin-top: 0 !important;
                    }
                    .el-input__inner {
                        height: 50px;
                        background: #F9F9F9;
                        border: 1px solid transparent;
                        &:focus {
                            border: 1px solid $primary-color;
                        }
                    }
                }
            }
            // 验证码输入
            .captcha-input {
                display: flex;
                margin-top: $input-gap;
                height: 50px;
                .el-input {
                    width: 100%;
                    margin-top: 0;
                }
                span, img {
                    width: 45%;
                    height: 100%;
                    flex-shrink: 0;
                    margin-left: 16px;
                }
                span {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    background: #f7f7f7;
                    border-radius: 8px;
                }
            }
            .el-button {
                height: 50px;
                width: 100%;
                color: #fff;
                font-size: 16px;
                background: linear-gradient(130deg, $primary-color + 20 0%, $primary-color - 20 100%);
            }
        }
    }
    .el-button {
      height: 50px;
   ::v-deep .center-title .el-dialog__title {
      text-align: center;
      width: 100%;
      color: #fff;
      font-size: 16px;
      background: linear-gradient(130deg, $primary-color + 20 0%, $primary-color - 20 100%);
      font-size: 18px;
      font-weight: bold;
    }
  }
}
    ::v-deep  .el-dialog__header{
      text-align: center;
    }
</style>