xlqx/app/components/ContactFloatingButton.vue
2025-11-04 15:25:51 +08:00

217 lines
6.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- components/ContactFloatingButton.vue -->
<template>
<div class="fixed right-2 lg:right-6 top-1/2 transform -translate-y-1/2 z-50 flex items-center">
<!-- PC端弹窗 - 使用 CSS 媒体查询只在 lg 及以上显示 -->
<div class="hidden lg:block">
<UPopover
arrow
mode="click"
:popper="{ placement: 'left-start' }"
:content="{
align: 'center',
side: 'left',
sideOffset: 6
}"
>
<UButton
class="bg-primary hover:bg-primary-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
color="neutral"
label="商家加盟"
variant="subtle"/>
<template #content>
<div class="w-75 lg:w-100 h-120 lg:h-160 p-4 bg-white rounded-lg shadow-xl overflow-y-auto hidden lg:block">
<img src="https://api.ccttiot.com/image-1762158125769.png" alt="">
<h3 class="text-lg font-semibold my-4 text-gray-800">商家加盟申请</h3>
<UForm
ref="formRef"
:state="formState"
class="space-y-4 w-full"
@submit="onSubmit"
>
<UFormGroup label="姓名" name="name" required>
<UInput
v-model="formState.name"
placeholder="请输入您的姓名"
size="md"
class="w-full mb-5"
/>
</UFormGroup>
<UFormGroup label="手机号" name="mobile" required>
<UInput
v-model="formState.mobile"
type="tel"
placeholder="请输入您的手机号"
size="md"
class="w-full mb-5"
/>
</UFormGroup>
<UFormGroup label="城市" name="city" required>
<UInput
v-model="formState.city"
placeholder="请输入您的意向合作城市"
size="md"
class="w-full mb-5"
/>
</UFormGroup>
<UFormGroup label="是否有设备" name="hasDevice">
<div class="flex gap-4 mb-5">
<label class="flex items-center gap-2 cursor-pointer">
<input
type="radio"
v-model="formState.hasDevice"
:value="1"
class="w-4 h-4 text-primary"
/>
<span class="text-sm">有设备</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input
type="radio"
v-model="formState.hasDevice"
:value="0"
class="w-4 h-4 text-primary"
/>
<span class="text-sm">无设备</span>
</label>
</div>
</UFormGroup>
<UFormGroup label="留言内容" name="content" required>
<UTextarea
v-model="formState.content"
placeholder="请输入您想要了解的信息"
:rows="3"
size="md"
class="w-full mb-5"
/>
</UFormGroup>
<div class="flex gap-2 ">
<UButton
type="submit"
:loading="isSubmitting"
:disabled="isSubmitting"
class="flex-1 bg-primary hover:bg-primary-600 justify-center items-center rounded-full"
size="xl"
>
{{ isSubmitting ? '提交中...' : '马上加盟 立即挣钱' }}
</UButton>
</div>
</UForm>
<img class="mt-2" src="https://api.ccttiot.com/image-1762158608753.png" alt="">
<img src="https://api.ccttiot.com/image-1762159041739.png" alt="">
<img src="https://api.ccttiot.com/image-1762159105486.png" alt="">
<img src="https://api.ccttiot.com/image-1762158699504.png" alt="">
</div>
</template>
</UPopover>
</div>
<!-- 移动端:跳转链接 - 使用 CSS 媒体查询,只在 lg 以下显示 -->
<NuxtLink
to="/merchantFranchise"
class="block lg:hidden"
>
<UButton
class="bg-primary hover:bg-primary-600 text-white px-4 py-2 rounded-l-lg shadow-lg transition-all duration-300 "
color="neutral"
label="商家加盟"
variant="subtle"/>
</NuxtLink>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { submitMchApply, type MchApplyParams } from '~/config/api'
const toast = useToast()
const formRef = ref()
const isSubmitting = ref(false)
const formState = reactive<MchApplyParams>({
name: '',
mobile: '',
content: '',
hasDevice: 0,
city: ''
})
const showToast = (title: string, type: 'success' | 'error' = 'success') => {
toast.add({
title,
color: type === 'success' ? 'success' : 'error',
icon: type === 'success' ? 'i-heroicons-check-circle' : 'i-heroicons-exclamation-circle',
})
}
const resetForm = () => {
formState.name = ''
formState.mobile = ''
formState.content = ''
formState.hasDevice = 0
formState.city = ''
formRef.value?.clear()
}
const validateForm = (): boolean => {
if (!formState.name.trim()) {
showToast('请输入姓名', 'error')
return false
}
if (!formState.mobile.trim()) {
showToast('请输入手机号', 'error')
return false
}
// 简单的手机号验证
const mobileRegex = /^1[3-9]\d{9}$/
if (!mobileRegex.test(formState.mobile)) {
showToast('请输入正确的手机号', 'error')
return false
}
if (!formState.city.trim()) {
showToast('请输入所在城市', 'error')
return false
}
if (!formState.content.trim()) {
showToast('请输入留言内容', 'error')
return false
}
return true
}
const onSubmit = async () => {
if (!validateForm()) {
return
}
isSubmitting.value = true
try {
const response = await submitMchApply(formState)
if (response.code === 200) {
showToast('申请提交成功!我们会尽快与您联系。', 'success')
resetForm()
} else {
showToast(response.msg || '提交失败,请稍后重试', 'error')
}
} catch (error) {
console.error('提交申请失败:', error)
showToast('提交失败,请检查网络连接后重试', 'error')
} finally {
isSubmitting.value = false
}
}
</script>