|
|
@@ -0,0 +1,276 @@
|
|
|
+<script lang="ts" setup>
|
|
|
+import { onUnmounted, reactive, ref } from 'vue'
|
|
|
+import { useUserStore } from '@/store'
|
|
|
+
|
|
|
+definePage({
|
|
|
+ style: {
|
|
|
+ navigationBarTitleText: '绑定银行卡',
|
|
|
+ },
|
|
|
+})
|
|
|
+
|
|
|
+const userStore = useUserStore()
|
|
|
+
|
|
|
+const model = reactive({
|
|
|
+ name: '',
|
|
|
+ bankName: '',
|
|
|
+ bankNumber: '',
|
|
|
+ phone: '',
|
|
|
+ code: '', // 添加验证码字段
|
|
|
+ result: '',
|
|
|
+ description: '',
|
|
|
+})
|
|
|
+
|
|
|
+// 倒计时相关变量
|
|
|
+const countdown = ref(0)
|
|
|
+const countdownText = ref('获取验证码')
|
|
|
+const isCounting = ref(false)
|
|
|
+let countdownTimer: ReturnType<typeof setInterval> | null = null
|
|
|
+
|
|
|
+// 获取验证码函数
|
|
|
+function getCode() {
|
|
|
+ if (isCounting.value) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 验证手机号格式
|
|
|
+ if (!/^1[3-9]\d{9}$/.test(model.phone)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入正确的手机号',
|
|
|
+ icon: 'none',
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 开始倒计时
|
|
|
+ isCounting.value = true
|
|
|
+ countdown.value = 60
|
|
|
+ countdownText.value = `${countdown.value}s后重新获取`
|
|
|
+
|
|
|
+ // 模拟发送验证码请求
|
|
|
+ uni.showToast({
|
|
|
+ title: '验证码已发送',
|
|
|
+ icon: 'success',
|
|
|
+ })
|
|
|
+
|
|
|
+ // 设置倒计时定时器
|
|
|
+ countdownTimer = setInterval(() => {
|
|
|
+ countdown.value--
|
|
|
+ if (countdown.value > 0) {
|
|
|
+ countdownText.value = `${countdown.value}s后重新获取`
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // 倒计时结束
|
|
|
+ clearInterval(countdownTimer!)
|
|
|
+ countdownTimer = null
|
|
|
+ isCounting.value = false
|
|
|
+ countdownText.value = '获取验证码'
|
|
|
+ }
|
|
|
+ }, 1000)
|
|
|
+}
|
|
|
+
|
|
|
+// 组件卸载时清除定时器
|
|
|
+onUnmounted(() => {
|
|
|
+ if (countdownTimer) {
|
|
|
+ clearInterval(countdownTimer)
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const rules = reactive({
|
|
|
+ name: {
|
|
|
+ type: 'string',
|
|
|
+ required: true,
|
|
|
+ message: '请填写姓名',
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ },
|
|
|
+ phone: {
|
|
|
+ type: 'string',
|
|
|
+ required: true,
|
|
|
+ message: '请填写电话',
|
|
|
+ pattern: /^1[3-9]\d{9}$/,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ },
|
|
|
+})
|
|
|
+
|
|
|
+// 使用 ref 创建响应式引用
|
|
|
+const uFormRef = ref(null)
|
|
|
+
|
|
|
+function submitForm() {
|
|
|
+ uFormRef.value.validate().then((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '校验通过',
|
|
|
+ icon: 'success',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ uni.showToast({
|
|
|
+ title: '校验失败',
|
|
|
+ icon: 'error',
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ // 处理验证错误
|
|
|
+ uni.showToast({
|
|
|
+ title: '校验失败',
|
|
|
+ icon: 'error',
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <view class="form-container">
|
|
|
+ <view class="form-wrapper">
|
|
|
+ <u-form
|
|
|
+ ref="uFormRef"
|
|
|
+ label-position="left"
|
|
|
+ :model="model"
|
|
|
+ :rules="rules"
|
|
|
+ >
|
|
|
+ <u-form-item
|
|
|
+ ref="item1"
|
|
|
+ label="姓名"
|
|
|
+ prop="name"
|
|
|
+ :border-bottom="true"
|
|
|
+ >
|
|
|
+ <u-input
|
|
|
+ v-model="model.name"
|
|
|
+ border="none"
|
|
|
+ placeholder="请输入姓名"
|
|
|
+ />
|
|
|
+ </u-form-item>
|
|
|
+ <u-form-item
|
|
|
+ ref="item2"
|
|
|
+ label="开户行"
|
|
|
+ prop="bankName"
|
|
|
+ :border-bottom="true"
|
|
|
+ >
|
|
|
+ <u-input
|
|
|
+ v-model="model.bankName"
|
|
|
+ border="none"
|
|
|
+ placeholder="请输入开户行"
|
|
|
+ />
|
|
|
+ </u-form-item>
|
|
|
+ <u-form-item
|
|
|
+ ref="item3"
|
|
|
+ label="卡号"
|
|
|
+ prop="bankNumber"
|
|
|
+ :border-bottom="true"
|
|
|
+ >
|
|
|
+ <u-input
|
|
|
+ v-model="model.bankNumber"
|
|
|
+ border="none"
|
|
|
+ placeholder="请输入卡号"
|
|
|
+ />
|
|
|
+ </u-form-item>
|
|
|
+ <u-form-item
|
|
|
+ ref="item4"
|
|
|
+ label="电话"
|
|
|
+ prop="phone"
|
|
|
+ :border-bottom="true"
|
|
|
+ >
|
|
|
+ <u-input
|
|
|
+ v-model="model.phone"
|
|
|
+ border="none"
|
|
|
+ placeholder="请输入手机号"
|
|
|
+ />
|
|
|
+ </u-form-item>
|
|
|
+ <u-form-item
|
|
|
+ ref="item5"
|
|
|
+ label="验证码"
|
|
|
+ :border-bottom="true"
|
|
|
+ >
|
|
|
+ <view class="form-item-code">
|
|
|
+ <u-input
|
|
|
+ v-model="model.code"
|
|
|
+ border="none"
|
|
|
+ placeholder="请输入验证码"
|
|
|
+ />
|
|
|
+ <view
|
|
|
+ class="form-item-result u-text-success"
|
|
|
+ :class="{ disabled: isCounting }"
|
|
|
+ :style="{ cursor: isCounting ? 'not-allowed' : 'pointer' }"
|
|
|
+ @click="getCode"
|
|
|
+ >
|
|
|
+ {{ countdownText }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-form-item>
|
|
|
+ </u-form>
|
|
|
+
|
|
|
+ <view class="form-btn" @click="submitForm">
|
|
|
+ 确认绑定
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+::v-deep .u-form-item__body__left {
|
|
|
+ width: 150rpx !important;
|
|
|
+ font-weight: 400 !important;
|
|
|
+ font-size: 26rpx !important;
|
|
|
+ color: #333333 !important;
|
|
|
+}
|
|
|
+::v-deep .u-input__content__field-wrapper__field {
|
|
|
+ text-align: right !important;
|
|
|
+}
|
|
|
+::v-deep .u-form-item__body__left__content__label {
|
|
|
+ color: #333333 !important;
|
|
|
+ font-size: 26rpx !important;
|
|
|
+ font-weight: 400 !important;
|
|
|
+}
|
|
|
+::v-deep .u-line {
|
|
|
+ border-color: #eeeeee !important;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .u-form-item__body__right__content__slot {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+.form-container {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ min-height: 100vh;
|
|
|
+ padding: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-wrapper {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ padding: 0 32rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-item-result {
|
|
|
+ height: 44rpx;
|
|
|
+ line-height: 44rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ text-align: center;
|
|
|
+ &.u-text-success {
|
|
|
+ color: #64a6ff;
|
|
|
+ }
|
|
|
+ &.disabled {
|
|
|
+ opacity: 0.5;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.form-item-code {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ gap: 60rpx;
|
|
|
+}
|
|
|
+.form-btn {
|
|
|
+ width: 600rpx;
|
|
|
+ height: 80rpx;
|
|
|
+ line-height: 80rpx;
|
|
|
+ background: linear-gradient(90deg, #ee6b67 0%, #ff7d78 100%);
|
|
|
+ border-radius: 10rpx;
|
|
|
+ position: fixed;
|
|
|
+ bottom: 52rpx;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+</style>
|