fucai-claim/src/pages/home/index.vue

361 lines
13 KiB
Vue
Raw Normal View History

<template>
<div class="min-h-screen bg-[#FCEEF3] overflow-hidden">
<!-- 顶部头图 -->
<div class="w-full overflow-hidden relative">
<img src="/头图.png" alt="活动宣传" class="w-full h-auto" />
<!-- 顶部Logo和标题 -->
<div class="absolute top-0 left-0 py-4 h-full w-full flex flex-col items-start justify-center px-4">
<div class="flex items-start mb-4">
<img src="/logo.png" alt="中国福利彩票" class="h-8 pl-2" />
</div>
<img src="/ziti.png" alt="宁福您彩 新婚送福" class="h-15" />
</div>
</div>
<!-- 表单区域 -->
<div class="p-4 -mt-10 z-10 relative">
<div class="max-w-md mx-auto bg-white rounded-xl shadow-sm p-6">
<!-- 标题 -->
<div class="flex items-center justify-center text-xl text-[#E8424D] mb-6">
<img src="/爱心点缀1.png" alt="" class="h-5">
<span class="px-2">领取专属喜礼</span>
<img src="/爱心点缀2.png" alt="" class="h-5">
</div>
<div>
<div v-if="![2, 3].includes(activityInfo.status)">
<!-- 手机号输入 -->
<div class="mb-5 flex items-center gap-3 border border-gray-200 rounded-lg px-4">
<input v-model="formData.phone" type="tel" placeholder="请输入手机号码" maxlength="11"
class="outline-none focus:border-[#E8424D] transition-colors flex-1 h-11" />
<button @click="sendVerificationCode" :disabled="countdown > 0 || formData.phone.length !== 11"
class="h-11 rounded-lg text-sm text-[#E8424D] transition-all disabled:text-[#8a8a8a]">
{{ countdown > 0 ? `${countdown}秒后重发` : formData.verifyCode ? '重新获取' : '获取验证码' }}
</button>
</div>
<!-- 验证码输入 -->
<div class="mb-5 flex items-center gap-3 border border-gray-200 rounded-lg px-4">
<input :disabled="formData.verifyCode" v-model="formData.smsCode" type="text" placeholder="请输入验证码"
maxlength="6" class="outline-none focus:border-[#E8424D] transition-colors flex-1 h-11" />
<button v-if="!formData.verifyCode" @click="verifyCode" :disabled="formData.smsCode.length !== 6"
class="h-8 px-4 bg-[#E8424D] text-white rounded-lg text-sm transition-all hover:opacity-90 active:scale-98 disabled:bg-[#8a8a8a]">
验证
</button>
</div>
</div>
<div v-if="formData.verifyCode && !formData.qrCode">
<!-- 结婚证信息 -->
<div class="mb-6">
<h3 class="text-base text-gray-800 mb-3 font-medium">结婚证信息:</h3>
<div v-if="!formData.marriageNo"
class="border border-gray-200 rounded-lg p-5 flex items-center justify-center">
<div class="relative inline-block" @click="handleScanClick">
<img src="/扫描.png" alt="" class="h-20">
<div
class="h-16 w-26 absolute border border-[#f0f0f0] rounded-md top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex justify-center">
<span class="text-[#E2E4E9] text-xs pt-1">结婚证</span>
</div>
<input type="file" ref="ocrUploadId" class="hidden" accept="image/*" @change="handleImageChange" />
</div>
</div>
<div v-if="formData.marriageNo"
class="w-full flex flex-col items-start border border-gray-200 rounded-lg p-5 bg-[#FAFAFA]">
<div>
<span class="inline-block w-25 text-right">结婚证字号</span>
<span class="pl-2">{{ formData.marriageNo }}</span>
</div>
<div class="mt-2">
<span class="inline-block w-25 text-right">男方姓名</span>
<span class="pl-2">{{ formData.husbandName }}</span>
</div>
<div class="mt-2">
<span class="inline-block w-25 text-right">女方姓名</span>
<span class="pl-2">{{ formData.wifeName }}</span>
</div>
</div>
</div>
<!-- 提交按钮 -->
<button @click="submitForm" :disabled="!formData.marriageNo"
class="w-full h-12 bg-gradient-to-r from-[#E8424D] to-[#FF7A7A] text-white rounded-full text-lg font-bold transition-all hover:opacity-90 active:scale-98 disabled:from-[#8a8a8a] disabled:to-[#8a8a8a]">
提交领取喜礼
</button>
</div>
<div v-if="formData.qrCode">
<div>
<h3 class="text-base text-gray-800 mb-3 font-medium">请使用微信扫描下方二维码:</h3>
</div>
<div class="mt-4 flex justify-center items-center">
<qrcode-vue :value="formData.qrCode" :size="200" level="H" render-as="canvas" />
</div>
</div>
</div>
<div v-if="activityInfo.status === 2">
<!-- 活动结束状态 -->
<div class="mt-6 p-4 border border-[#E8424D] bg-[#FFF5F5] rounded-lg text-center">
<div class="text-[#E8424D] text-lg font-semibold mb-2">活动已结束</div>
<div class="text-gray-600 text-sm">{{ activityInfo.activityName }}活动已结束感谢您的参与敬请期待下一次活动</div>
<div class="mt-4 text-xs text-gray-500">活动时间{{ activityInfo.activityStartTime }} - {{
activityInfo.activityEndTime }}</div>
</div>
</div>
<div v-else-if="activityInfo.status === 3">
<!-- 活动失败状态 -->
<div class="mt-6 p-4 border border-[#FF7A7A] bg-[#FFF5F5] rounded-lg text-center">
<div class="text-[#FF7A7A] text-lg font-semibold mb-2">活动获取失败</div>
<div class="text-gray-600 text-sm">活动获取失败请稍后重试</div>
<div class="mt-4 text-xs text-gray-500">活动时间--</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import message from '../../components/message';
import apiService from '../../services/apiService'
import { ref, onMounted } from 'vue'
import dayjs from 'dayjs'
import QrcodeVue from 'qrcode.vue'
import { showLoading, hideLoading } from '../../components/loading'
const ocrUploadId = ref<HTMLInputElement>();
// 表单数据
const formData = ref({
phone: '',
smsCode: '',
verifyCode: false, // 验证状态
marriageNo: '', // 结婚证号
husbandName: '', // 男方姓名
wifeName: '', // 女方姓名
registerDate: '', // 登记日期
qrCode: '', // 二维码
})
const activityInfo = ref<any>({}); // 活动信息
onMounted(() => {
// 检查活动是否已结束
showLoading();
apiService.getCurrentActivity().then((response: any) => {
if (response.data) {
activityInfo.value = {
...response.data,
activityStartTime: dayjs(response.data.activityStartTime).format('YYYY年MM月DD日'),
activityEndTime: dayjs(response.data.activityEndTime).format('YYYY年MM月DD日'),
};
if (new Date(response.data.activityEndTime) < new Date()) {
message.error('活动已结束');
activityInfo.value.status = 2;
} else {
const user = JSON.parse(localStorage.getItem('userAs') || '{}');
if (user.phone && user.smsCode) {
formData.value.phone = user.phone;
formData.value.smsCode = user.smsCode;
verifyCode();
}
}
}
}).catch((error) => {
message.error('获取活动信息失败,请稍后重试')
activityInfo.value.status = 3;
}).finally(() => {
hideLoading();
})
})
// 倒计时
const countdown = ref(0)
let countdownTimer: number | null = null
// 发送验证码
const sendVerificationCode = () => {
const { phone } = formData.value
// 简单手机号验证
if (!/^1[3-9]\d{9}$/.test(phone)) {
message.error('请输入正确的手机号码')
return
}
showLoading();
// 调用发送短信验证码接口
apiService.sendSms({
mobile: phone,
type: 3,
}).then(() => {
formData.value.verifyCode = false;
formData.value.smsCode = '';
formData.value.qrCode = '';
// 开始倒计时
countdown.value = 60
if (countdownTimer) {
clearInterval(countdownTimer)
}
countdownTimer = window.setInterval(() => {
if (countdown.value > 0) {
countdown.value--
} else {
if (countdownTimer) {
clearInterval(countdownTimer)
}
}
}, 1000)
}).catch((error) => {
console.error('发送验证码失败:', error)
message.error('验证码发送失败,请稍后重试')
}).finally(() => {
hideLoading();
})
}
// 验证验证码
const verifyCode = () => {
const { smsCode } = formData.value
if (smsCode.length !== 6 || !/^\d{6}$/.test(smsCode)) {
message.error('请输入6位数字验证码')
return
}
showLoading();
// 调用验证短信验证码接口
apiService.verifySms({
mobile: formData.value.phone,
smsCode: smsCode,
type: 3,
}).then((res) => {
localStorage.setItem('userAs', JSON.stringify({
phone: formData.value.phone,
smsCode: formData.value.smsCode,
}));
formData.value.verifyCode = true;
// 验证成功后重置倒计时
countdown.value = 0;
// 验证成功如果有二维码,保存到表单
if (res.data.code) {
formData.value = {
...formData.value,
qrCode: res.data.code,
}
} else {
formData.value = {
...formData.value,
marriageNo: "",
husbandName: "",
wifeName: "",
registerDate: "",
qrCode: ""
}
}
}).catch((error) => {
localStorage.removeItem('userAs');
message.error('验证码验证失败,请重试');
formData.value = {
...formData.value,
marriageNo: "",
husbandName: "",
wifeName: "",
registerDate: "",
qrCode: ""
}
}).finally(() => {
hideLoading();
})
}
// 处理扫描点击事件
const handleScanClick = () => {
ocrUploadId.value?.click()
}
const handleImageChange = () => {
const file = ocrUploadId.value?.files?.[0]
if (!file) {
message.error('请选择图片文件')
return
}
// 调用上传OCR图片接口
const formFormData = new FormData()
formFormData.append('file', file)
showLoading();
apiService.uploadOcrImage(formFormData).then((response: any) => {
apiService.parseOcrInfo({
mobile: formData.value.phone,
smsCode: formData.value.smsCode,
uploadId: response.data.uploadId,
}).then((res: any) => {
if (res?.data?.parsed?.marriageNo) {
formData.value.marriageNo = res?.data?.parsed?.marriageNo;
formData.value.husbandName = res?.data?.parsed?.husbandName;
formData.value.wifeName = res?.data?.parsed?.wifeName;
formData.value.registerDate = res?.data?.parsed?.registerDate;
} else {
message.error('解析OCR信息失败请稍后重试');
ocrUploadId.value && (ocrUploadId.value.value = '');
}
}).catch((error) => {
message.error('解析OCR信息失败请稍后重试')
ocrUploadId.value && (ocrUploadId.value.value = '');
}).finally(() => {
hideLoading();
})
}).catch((error) => {
message.error('图片上传失败,请稍后重试')
ocrUploadId.value && (ocrUploadId.value.value = '');
hideLoading();
})
}
// 提交表单
const submitForm = () => {
if (!formData.value.phone || !formData.value.smsCode) {
message.error('请完善所有信息')
return
}
showLoading();
apiService.receiveCheck({
marriageNo: formData.value.marriageNo,
receiveName: formData.value.husbandName,
receiveMobile: formData.value.phone,
smsCode: formData.value.smsCode,
}).then((res: any) => {
formData.value.qrCode = res.data.code;
}).catch((error) => {
message.error(error?.msg || '提交失败,请稍后重试')
}).finally(() => {
hideLoading();
})
}
// 组件卸载时清理定时器
import { onUnmounted } from 'vue'
onUnmounted(() => {
if (countdownTimer) {
clearInterval(countdownTimer)
}
})
</script>