180 lines
3.8 KiB
Plaintext
180 lines
3.8 KiB
Plaintext
<template>
|
|
<view class="page-container">
|
|
<view class="form-group">
|
|
<view class="input-item">
|
|
<text class="label">手机号</text>
|
|
<input class="input" type="number" placeholder="请输入新手机号" v-model="phone" maxlength="11" />
|
|
</view>
|
|
<view class="input-item">
|
|
<text class="label">验证码</text>
|
|
<input class="input" type="number" placeholder="请输入验证码" v-model="code" maxlength="6" />
|
|
<text class="code-btn" @click="sendCode">{{ counting ? `${count}s` : '获取验证码' }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<button class="submit-btn" @click="handleSubmit">确认绑定</button>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref } from 'vue'
|
|
import supa from '@/components/supadb/aksupainstance.uts'
|
|
|
|
const phone = ref('')
|
|
const code = ref('')
|
|
const counting = ref(false)
|
|
const count = ref(60)
|
|
|
|
const sendCode = async () => {
|
|
if (counting.value) return
|
|
if (!phone.value || phone.value.length !== 11) {
|
|
uni.showToast({
|
|
title: '请输入正确的手机号',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
uni.showLoading({ title: '发送中...' })
|
|
|
|
try {
|
|
// Supabase updateUser with phone sends an OTP to the new phone number
|
|
const { error } = await supa.auth.updateUser({
|
|
phone: phone.value
|
|
})
|
|
|
|
uni.hideLoading()
|
|
|
|
if (error != null) {
|
|
uni.showToast({
|
|
title: '发送失败: ' + error.message,
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
counting.value = true
|
|
count.value = 60
|
|
|
|
const timer = setInterval(() => {
|
|
count.value--
|
|
if (count.value <= 0) {
|
|
clearInterval(timer)
|
|
counting.value = false
|
|
}
|
|
}, 1000)
|
|
|
|
uni.showToast({
|
|
title: '验证码已发送',
|
|
icon: 'none'
|
|
})
|
|
} catch(e) {
|
|
uni.hideLoading()
|
|
console.error(e)
|
|
uni.showToast({ title: '发送异常', icon: 'none' })
|
|
}
|
|
}
|
|
|
|
const handleSubmit = async () => {
|
|
if (!phone.value || !code.value) {
|
|
uni.showToast({
|
|
title: '请填写完整信息',
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
uni.showLoading({ title: '绑定中...' })
|
|
|
|
try {
|
|
// 验证 OTP
|
|
const { error } = await supa.auth.verifyOtp({
|
|
phone: phone.value,
|
|
token: code.value,
|
|
type: 'phone_change'
|
|
})
|
|
|
|
uni.hideLoading()
|
|
|
|
if (error != null) {
|
|
uni.showToast({
|
|
title: '绑定失败: ' + error.message,
|
|
icon: 'none'
|
|
})
|
|
return
|
|
}
|
|
|
|
uni.showToast({
|
|
title: '绑定成功',
|
|
icon: 'success'
|
|
})
|
|
|
|
// 更新本地存储的用户信息
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
if (userInfo) {
|
|
// @ts-ignore
|
|
let u = userInfo as any
|
|
u['phone'] = phone.value
|
|
uni.setStorageSync('userInfo', u)
|
|
}
|
|
|
|
setTimeout(() => {
|
|
uni.navigateBack()
|
|
}, 1500)
|
|
} catch(e) {
|
|
uni.hideLoading()
|
|
console.error(e)
|
|
uni.showToast({ title: '系统错误', icon: 'none' })
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.page-container {
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.form-group {
|
|
background-color: #fff;
|
|
border-radius: 8px;
|
|
padding: 0 15px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.input-item {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 50px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.input-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.label {
|
|
width: 70px;
|
|
font-size: 14px;
|
|
color: #333;
|
|
}
|
|
|
|
.input {
|
|
flex: 1;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.code-btn {
|
|
color: #007aff;
|
|
font-size: 14px;
|
|
padding: 5px 10px;
|
|
}
|
|
|
|
.submit-btn {
|
|
background-color: #007aff;
|
|
color: #fff;
|
|
border-radius: 25px;
|
|
font-size: 16px;
|
|
}
|
|
</style> |