index.vue 5.43 KB
<template>
  <div class="login-section">
    <van-config-provider :theme-vars="themeVars">
      <van-form ref="form" @submit="onSubmit">
        <van-cell-group inset style="border: 1px solid #EAEAEA;">
          <van-field v-if="use_widget" v-model="phone" name="phone" label="手机号" placeholder="手机号" readonly clickable
            :rules="[{ validator, message: '请输入正确手机号' }]"
            @touchstart.stop="showKeyboard" />
          <van-field v-else v-model="phone" name="phone" label="手机号" placeholder="手机号"
            :rules="[{ validator, message: '请输入正确手机号' }]" />
          <van-field v-model="code" center clearable name="code" type="digit" label="短信验证码" placeholder="请输入短信验证码"
            :formatter="formatter" :rules="[{ required: true, message: '请填写验证码' }]">
            <template #button>
              <van-button @click="sendCode" v-if="countDown.current.value.total === limit" size="small" type="primary"
                :disabled="disabled">
                <span>发送验证码</span>
              </van-button>
              <van-button v-else size="small" type="primary" :disabled="disabled">
                <span>{{ countDown.current.value.seconds }} 秒重新发送</span>
              </van-button>
            </template>
          </van-field>
        </van-cell-group>
      </van-form>
    </van-config-provider>
  </div>

  <van-number-keyboard v-model="phone" :show="keyboard_show" :maxlength="11" @blur="onBlur" />

  <!-- 图片滑块验证 -->
  <image-slider-verify :isShow="sliderShow" @done="handleConfirm" @on-close="handleClose">
  </image-slider-verify>
</template>

<script setup>
import ImageSliderVerify from '@/components/ImageSliderVerify/index.vue'

import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useCountDown } from '@vant/use';
import { wxInfo } from '@/utils/tools';
import { styleColor } from '@/constant.js';

import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();

const emit = defineEmits(['on-submit'])

const form = ref(null);

const submit = () => {
  let valid = form.value.validate();
  valid
    .then(() => {
      form.value.submit();
    })
    .catch(error => {
      console.error(error);
      Toast({
        message: '请检查后再次提交',
        icon: 'cross',
      });
    })
}

defineExpose({
  submit
})

const themeVars = {
  buttonPrimaryBackground: styleColor.baseColor,
  buttonPrimaryBorderColor: styleColor.baseColor,
  buttonPrimaryColor: styleColor.baseFontColor,
  CellVerticalPadding: '14px'
};

const onSubmit = () => { 
  emit('on-submit', {
    phone: phone.value,
    code: code.value,
  })
}

// 判断是否显示控件
let use_widget = ref(true);
/**
 * 手机号码校验
 * 函数返回 true 表示校验通过,false 表示不通过
 * @param {*} val 
 */
const validator = (val) => {
  let flag = false;
  // 简单判断手机号位数
  if (/1\d{10}/.test(val) && phone.value.length === 11) {
    disabled.value = false;
    flag = true;
  } else {
    disabled.value = true;
    flag = false;
  }
  return flag
};


const phone = ref('');
const code = ref('');
// TAG: 开发环境测试数据
if (import.meta.env.DEV) {
  phone.value = import.meta.env.VITE_ID
  code.value = import.meta.env.VITE_PIN
}

onMounted(() => {
  /**
   * 判断微信环境看是否弹出控件框
   * 桌面微信直接输入
   * 其他环境弹出输入框
   */
  if (wxInfo().isiOS || wxInfo().isAndroid) {
    use_widget.value = true;
  } else {
    use_widget.value = false;
  }
  // 判断微信授权状态,进入页面时未授权需要授权跳转
  if (!Cookies.get('PHPSESSID')) {
    $router.replace({
      path: '/auth',
      query: {
        href: location.hash,
        userType: 'b'
      }
    });
  }
})

// 手机号输入控件控制
const keyboard_show = ref(false);
const showKeyboard = () => { // 弹出数字弹框
  keyboard_show.value = true;
};
const onBlur = () => { // 数字键盘失焦回调
  keyboard_show.value = false;
  if (phone.value.length === 11) {
    disabled.value = false;
  }
};

// 设置发送短信倒计时
// TAG: vant 自带倒计时函数
const limit = ref(60000); // 配置倒计时秒数
const countDown = useCountDown({
  // 倒计时 24 小时
  time: limit.value,
  onFinish: () => {
    countDown.reset();
  }
});

const sendCode = () => { // 发送验证码
  countDown.start();
  axios.post('/srv/?a=bind_phone&t=get_code', {
    phone: phone.value
  })
    .then(res => {
      if (res.data.code === 1) {
        Toast.success('发送成功');
      } else {
        console.warn(res.data);
        if (!res.data.show) return false;
        Toast({
          message: res.data.msg,
          icon: 'close',
        });
      }
    })
    .catch(err => {
      console.error(err);
    })
};

const disabled = ref(true);
// 过滤输入的数字 只能四位
const formatter = (value) => value.substring(0, 4);

// 滑块验证成功后回调
const sliderShow = ref(false);
const handleConfirm = (val) => {
  sliderShow.value = false
  console.warn('验证成功');
}
const handleClose = () => {
  sliderShow.value = false
}
const imageVerify = () => {
  sliderShow.value = true;
}
</script>

<style lang="less" scoped>
</style>