124 lines
4.3 KiB
Vue
124 lines
4.3 KiB
Vue
<script setup lang="ts">
|
||
import { ref, watch, onUnmounted } from 'vue'
|
||
import { X } from 'lucide-vue-next'
|
||
|
||
interface Props {
|
||
isOpen: boolean
|
||
}
|
||
|
||
const props = defineProps<Props>()
|
||
const emit = defineEmits<{ (e: 'close'): void }>()
|
||
|
||
const containerRef = ref<HTMLDivElement | null>(null)
|
||
const modalRef = ref<HTMLDivElement | null>(null)
|
||
|
||
watch(() => props.isOpen, (open) => {
|
||
if (!containerRef.value) return
|
||
|
||
if (open) {
|
||
document.body.style.overflow = 'hidden'
|
||
document.body.style.touchAction = 'none'
|
||
|
||
containerRef.value.innerHTML = `
|
||
<div class="loading-indicator" style="text-align: center; padding: 2rem;">
|
||
<div style="border: 4px solid #3b82f6; border-top: 4px solid transparent; border-radius: 50%; width: 48px; height: 48px; animation: spin 1s linear infinite; margin: 0 auto 1rem;"></div>
|
||
<p style="color: #6b7280;">表单加载中...</p>
|
||
</div>
|
||
<style>
|
||
@keyframes spin {
|
||
0% { transform: rotate(0deg); }
|
||
100% { transform: rotate(360deg); }
|
||
}
|
||
</style>
|
||
`
|
||
|
||
const iframe = document.createElement('iframe')
|
||
iframe.id = 'goldendata_form_xFYow5'
|
||
iframe.src = 'https://baoming.gongxue100.com/f/xFYow5?background=white&banner=show&embedded=true&inner_redirect=false'
|
||
iframe.width = '100%'
|
||
iframe.height = '918'
|
||
iframe.frameBorder = '0'
|
||
iframe.style.border = 'none'
|
||
|
||
iframe.onload = () => {
|
||
const loader = containerRef.value?.querySelector('.loading-indicator') as HTMLElement | null
|
||
if (loader) loader.style.display = 'none'
|
||
}
|
||
|
||
iframe.onerror = () => {
|
||
const loader = containerRef.value?.querySelector('.loading-indicator') as HTMLElement | null
|
||
if (loader) {
|
||
loader.innerHTML = `
|
||
<div style="text-align: center; padding: 2rem;">
|
||
<div style="width: 48px; height: 48px; background: #fee2e2; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 1rem;">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2">
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
</div>
|
||
<p style="color: #6b7280; margin-bottom: 1rem;">表单加载失败</p>
|
||
<button onclick="window.location.reload()" style="background: #3b82f6; color: white; border: none; padding: 0.5rem 1rem; border-radius: 0.5rem; cursor: pointer;">重新加载</button>
|
||
</div>
|
||
`
|
||
}
|
||
}
|
||
|
||
containerRef.value.appendChild(iframe)
|
||
} else {
|
||
document.body.style.overflow = ''
|
||
document.body.style.touchAction = ''
|
||
if (containerRef.value) {
|
||
containerRef.value.innerHTML = ''
|
||
}
|
||
}
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
document.body.style.overflow = ''
|
||
document.body.style.touchAction = ''
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div v-if="isOpen" class="fixed inset-0 z-[9999] flex items-center justify-center p-4">
|
||
<div
|
||
class="absolute inset-0 bg-black/60 backdrop-blur-sm"
|
||
@click="emit('close')"
|
||
/>
|
||
|
||
<div
|
||
ref="modalRef"
|
||
class="relative bg-white rounded-3xl shadow-2xl w-full max-w-4xl max-h-[90vh] overflow-hidden animate-slide-up flex flex-col"
|
||
>
|
||
<button
|
||
@click="emit('close')"
|
||
class="absolute top-4 right-4 p-2 rounded-full hover:bg-gray-100 transition-colors z-10"
|
||
>
|
||
<X :size="24" class="text-gray-500" />
|
||
</button>
|
||
|
||
<div class="flex-1 overflow-y-auto">
|
||
<div class="p-6 md:p-8">
|
||
<div class="flex items-center gap-3 mb-6">
|
||
<div class="p-2 bg-orange-100 text-orange-600 rounded-xl">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/>
|
||
<circle cx="12" cy="10" r="3"/>
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-bold text-xl text-gray-900">报名上课</h3>
|
||
<p class="text-xs text-gray-500">填写信息,获取专属学习规划</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
ref="containerRef"
|
||
class="w-full min-h-[800px]"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|