123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- <template>
- <div>
- <v-form @submit.prevent ref="phoneForm">
- <v-text-field v-model="loginData.phone" :disabled="props.phoneDisabled" :placeholder="$t('login.mobileNumberPlaceholder')" color="primary" variant="outlined" density="compact" :rules="phoneRules" validate-on="input">
- <template v-slot:prepend-inner>
- <span class="d-flex">
- <v-icon icon="mdi-cellphone" size="20"></v-icon>
- <span class="d-flex" id="menu-activator">
- <span class="phone-number">{{ currentArea }}</span>
- <v-icon size="20">mdi-chevron-down</v-icon>
- </span>
- <v-menu activator="#menu-activator">
- <v-list>
- <v-list-item v-for="(item, index) in items" :key="index" :value="index" @click="handleChangeCurrentArea(item)">
- <v-list-item-title>{{ item.label }}</v-list-item-title>
- </v-list-item>
- </v-list>
- </v-menu>
- </span>
- </template>
- </v-text-field>
- <v-text-field
- v-model="loginData.code"
- :placeholder="$t('login.enterCode')"
- color="primary"
- variant="outlined"
- density="compact"
- prepend-inner-icon="mdi-security"
- :rules="[v=> !!v || $t('login.enterCode')]"
- @keyup.enter="handleEnter"
- >
- <template #append-inner>
- <span v-if="showCode" class="login-code" @click="handleCode">{{ $t('login.getSmsCode') }}</span>
- <span v-else class="disable">{{ $t('login.retrieveAgain') }}{{ count }}s</span>
- </template>
- </v-text-field>
- </v-form>
- </div>
- </template>
- <script setup>
- defineOptions({ name: 'verification-code' })
- import { ref, reactive, defineExpose, defineEmits } from 'vue'
- import { setCodeTime } from '@/utils/code'
- import { sendSmsCode } from '@/api/common/index'
- import { useI18n } from '@/hooks/web/useI18n'
- import Snackbar from '@/plugins/snackbar'
- const emits = defineEmits(['handleEnter'])
- const { t } = useI18n()
- const props = defineProps({ phoneDisabled: Boolean })
- const phoneRules = ref([
- value => {
- if (value) return true
- return t('login.mobileNumberPlaceholder')
- },
- value => {
- if (value?.length <= 11 && /^1[3456789]\d{9}$/.test(value)) return true
- return t('login.correctPhoneNumber')
- }
- ])
- // 手机号区域
- const currentArea = ref('0086')
- const items = [
- { label: '中国大陆-0086', value: '0086' }
- ]
- const handleChangeCurrentArea = (e) => {
- currentArea.value = e.value
- }
- // 获取验证码
- const showCode = ref(true)
- const count = ref(0)
- const timer = ref(null)
- const handleCode = () => {
- if (!loginData.phone) {
- Snackbar.warning(t('login.mobileNumberPlaceholder'))
- return
- }
- count.value = 60
- setTime()
- getSmsCode()
- }
- const getSmsCode = async () => {
- const query = {
- phone: loginData.phone,
- scene: 30
- }
- // try {
- await sendSmsCode(query)
- Snackbar.success(t('login.sendCode'))
- // } catch (error) {
- // Snackbar.error(error.msg)
- // }
- }
- const setTime = () => {
- showCode.value = false
- timer.value = setInterval(() => {
- let number = count.value
- if (number > 0 && number <= 60) {
- count.value--
- setCodeTime(number - 1)
- } else {
- showCode.value = true
- clearInterval(timer.value)
- timer.value = null
- }
- }, 1000)
- }
- const autoTimer = () => {
- count.value = 0
- if(!count.value) return
- setTime()
- }
- autoTimer()
- const loginUserPhone = localStorage.getItem('loginUserPhone') || '13229740091'
- const loginData = reactive({
- phone: loginUserPhone, // 13229740091 小梅 // 15775026250 瑞森
- code: '123456'
- })
- const phoneForm = ref()
- const handleEnter = () => {
- emits('handleEnter')
- }
- defineExpose({
- loginData,
- phoneForm
- })
- </script>
- <style lang="scss" scoped>
- .login-code {
- width: 97px;
- color: var(--v-primary-base);
- text-align: end;
- font-size: 12px;
- cursor: pointer;
- }
- .disable {
- width: 72px;
- color: grey;
- font-size: 12px;
- }
- .phone-number {
- width: 34px;
- font-size: 12px;
- }
- </style>
|