code.vue 5.2 KB
<template>
  <view class="page-code">
    <view class="page-code__logo">
      <image :src="formatImagePath('truck-load', 'svg')" mode="aspectFit"></image>
    </view>
    <view class="page-code__title">
      <view>请输入验证码</view>
      <view class="subtitle">验证码已发送至{{ form.mobile }}</view>
    </view>
    <view class="page-code__content">
      <u-cell title="验证码">
        <template #value>
          <input v-model="form.verificationCode" placeholder="请输入验证码" type="number" />
        </template>
        <template #right-icon>
          <u-code ref="code" @change="onCodeChange" keep-running start-text="获取验证码" change-text="Xs" />
          <text @tap="getCode" :text="codeTips" class="u-page__code-text">{{ codeTips }}</text>
        </template>
      </u-cell>
    </view>
    <view class="page-code__button">
      <u-button shape="circle" type="primary" hover-class="active" open-type="getUserInfo" lang="zh_CN" :disabled="!isValidated" :loading="submitting" @getuserinfo="onGetUserInfo">授权登录</u-button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      form: {
        mobile: '',
        verificationCode: '',
      },
      code: '',
      codeTips: '',
      sendding: true,
      submitting: false,
    };
  },
  computed: {
    isValidated() {
      return !!this.form.verificationCode;
    }
  },
  onLoad() {
    this.form.mobile = this.$params.mobile;
    // #ifdef MP-WEIXIN
    this.generateWeChatAuthCode();
    this.$refs.code.start();
    uni.showToast({ icon: 'none', title: '请注意查收验证码短信' });
    // #endif
    // #ifdef MP-DINGTALK
    setTimeout(() => {
      this.$refs.code.start();
      uni.showToast({ icon: 'none', title: '请注意查收验证码短信' });
    }, 300);
    // #endif
  },
  onShow() {
    uni.hideHomeButton();
  },
  methods: {
    // 获取微信登录code
    generateWeChatAuthCode() {
      uni.login({
        provider: 'weixin',
        success: response => {
          const { code } = response;
          if (code) {
            this.code = code;
          }
        }
      });
    },
    onCodeChange(text) {
      this.codeTips = text;
    },
    getCode() {
      if (this.$refs.code.canGetCode) {
        if (!this.form.mobile) {
          return uni.showToast({ icon: 'none', title: '请输入手机号' });
        }
        if (!this.sendding) {
          this.sendding = true;
          uni.$u.api.login.send({ mobile: this.form.mobile }).then(() => {
            uni.showToast({ title: '验证码已发送', icon: 'none' });
            this.$refs.code.start();
          }).finally(() => {
            this.sendding = false;
          });
        }
      } else {
        uni.showToast({ title: '倒计时结束后再发送', icon: 'none' });
      }
    },
    // 确认提交
    async onSubmit(params) {
      const data = {
        code: this.code,
        ...this.form,
        ...params,
      };
      if (!this.submitting) {
        this.submitting = true;
        uni.$u.api.login.bind(data).then((response) => {
          const result = response.result || {};
          this.$store.commit('SET_AUTHED', result.hasBind);
          this.$store.commit('SET_USER_INFO', result);
          uni.showToast({ title: '登录成功', icon: 'none' });
          uni.$emit('refresh-permission');
          setTimeout(() => {
            uni.switchTab({ url: '/pages/index' });
          }, 1500);
        }).catch(() => {
          this.generateWeChatAuthCode();
        }).finally(() => {
          this.submitting = false;
        });
      }
    },
    // 获取授权信息
    async onGetUserInfo(e) {
      const { detail = {} } = e;
      const { iv, encryptedData } = detail;
      if (iv && encryptedData) {
        this.onSubmit({ iv, encryptedData });
      } else {
        uni.showModal({
          title: '提示',
          content: '授权失败,请重试',
          showCancel: false,
          // #ifdef MP-DINGTALK
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          // #endif
        });
      }
    },
  }
};
</script>

<style lang="scss">
.page-code {
  padding: $padding-md;
  font-size: $font-md;
  min-height: 100vh;
  background-color: #fff;
  box-sizing: border-box;
  &__logo {
    text-align: center;
    height: 240upx;
    image {
      height: 100%;
      width: 100%;
    }
  }
  &__title {
    margin-top: $padding-md;
    font-size: $font-lg * 1.2;
    padding: $padding-md;
    line-height: 2;
    .subtitle {
      color: $color-text-caption;
      font-size: $font-md;
    }
  }
  &__content {
    color: $color-minor;
    padding: $padding-md 0;
    .u-cell__body__content {
      flex: initial !important;
    }
    .u-cell__title {
      min-width: $padding-md * 5 !important;
    }
    .u-cell input {
      flex: auto;
    }
  }
  &__button {
    padding-top: $padding-md * 6;
    button {
      border: 0;
      color: #fff;
      background-color: $color-primary;
      padding: $padding-md;
      line-height: 1.5;
      text-align: cener;
      font-size: $font-md * 1.2;
      border-radius: $radius-lg * 2;
      &::after {
        border: 0;
      }
      &.active {
        background-color: darken($color-primary, 3%);
      }
    }
  }
}
</style>