2025-12-12 17:09:47 +08:00

403 lines
10 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.

<template>
<el-dialog :title="title" :visible.sync="dialogVisible" :width="responsiveWidth" :center="center" :top="responsiveTop"
@close="handleClose" custom-class="product-consult-dialog">
<div class="dialog-tit">
如需购买资源请移步PC端哦~
<div class="url_box">
<div class="url-container" @mouseenter="showTooltip = true" @mouseleave="showTooltip = false">
官网地址:
<span
class="url"
ref="urlElement"
@click="copyUrl"
:class="{ 'copied': isCopied }"
>
https://www.opencomputing.cn
<span class="copy-hint">点击复制</span>
</span>
<div v-if="showTooltip" class="tooltip" :class="{ 'tooltip-visible': showTooltip }">
点击复制链接
</div>
</div>
</div>
</div>
<el-form ref="ruleForm" :rules="rules" label-position="top" :model="formData" :disabled="loading">
<el-form-item label="需求描述">
<el-input :autosize="{ minRows: 6, maxRows: 6 }" type="textarea" size="mini" v-model="formData.content"
placeholder="请输入您的具体需求"></el-input>
</el-form-item>
<el-form-item label="客户类型">
<el-radio v-model="formData.custom_type" label="1">企业</el-radio>
<el-radio v-model="formData.custom_type" label="0">个人</el-radio>
</el-form-item>
<el-form-item prop="name" label="联系人姓名">
<el-input size="mini" v-model="formData.name" placeholder="请输入联系人姓名"></el-input>
</el-form-item>
<el-form-item prop="phone" label="联系人手机">
<el-input size="mini" v-model="formData.phone" placeholder="请输入联系人手机" type="number"></el-input>
</el-form-item>
<el-form-item v-show="formData.custom_type === '1'" label="公司名称">
<el-input size="mini" v-model="formData.company" placeholder="请输入公司名称"></el-input>
</el-form-item>
<el-form-item label="联系人邮箱">
<el-input size="mini" v-model="formData.email" placeholder="请输入联系人邮箱" type="email"></el-input>
</el-form-item>
</el-form>
<el-checkbox v-model="formData.checked" class="agreement-checkbox">
<p>勾选表示您同意<span v-if="platformName">{{ platformName }}</span>
及其授权的合作伙伴通过您填写的联系方式联系您且数据仅用于与您沟通
</p>
<p>
当您注销平台账号后您的数据会被销毁
</p>
</el-checkbox>
<span slot="footer" class="dialog-footer">
<el-button size="mini" type="primary" :loading="loading" @click="handleSubmit">
</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: 'ProductConsultDialog',
props: {
// 控制弹窗显示
visible: {
type: Boolean,
default: false
},
// 弹窗标题
title: {
type: String,
default: '产品咨询'
},
// 弹窗宽度(使用响应式默认值)
width: {
type: String,
default: '' // 留空使用响应式计算
},
// 弹窗位置
top: {
type: String,
default: '' // 留空使用响应式计算
},
// 是否居中
center: {
type: Boolean,
default: true
},
// 平台名称(用于协议文本)
platformName: {
type: String,
default: ''
},
// 客服二维码
qrCode: {
type: String,
default: ''
},
// 提交接口函数
submitApi: {
type: Function,
default: null
},
// 当前页面URL
currentUrl: {
type: String,
default: ''
},
// 默认表单数据
defaultFormData: {
type: Object,
default: () => ({
content: '',
custom_type: '1',
name: '',
phone: '',
company: '',
email: '',
checked: false
})
}
},
data() {
// 手机号验证规则
const validatePhone = (rule, value, callback) => {
if (!value) {
callback(new Error('请输入手机号'))
} else if (!/^1[3-9]\d{9}$/.test(value)) {
callback(new Error('请输入正确的手机号码'))
} else {
callback()
}
}
return {
loading: false,
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
phone: [
{ required: true, validator: validatePhone, trigger: 'blur' }
]
},
formData: { ...this.defaultFormData },
showTooltip: false, // 控制提示显示
isCopied: false, // 复制状态
copyTimer: null // 复制状态定时器
}
},
computed: {
// 控制弹窗显示的计算属性
dialogVisible: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
}
},
// 响应式宽度计算
responsiveWidth() {
if (this.width) return this.width
// 根据屏幕宽度动态计算
const screenWidth = window.innerWidth || document.documentElement.clientWidth
if (screenWidth <= 750) {
return '90%' // 移动端
} else if (screenWidth <= 1200) {
return '70%' // 平板
} else {
return '6rem' // 桌面端原50rem太大
}
},
// 响应式位置计算
responsiveTop() {
if (this.top) return this.top
const screenHeight = window.innerHeight || document.documentElement.clientHeight
if (screenHeight <= 667) {
return '10vh' // 小屏幕
} else {
return '15vh' // 正常屏幕
}
}
},
watch: {
// 监听visible变化
visible: {
immediate: true,
handler(newVal) {
if (newVal) {
// 显示时重置表单
this.resetForm()
}
}
},
// 监听defaultFormData变化
defaultFormData: {
deep: true,
handler(newVal) {
this.resetForm()
}
}
},
methods: {
// 复制URL到剪贴板
copyUrl() {
const urlToCopy = 'https://www.opencomputing.cn'
// 使用现代剪贴板API
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(urlToCopy)
.then(() => {
this.handleCopySuccess()
})
.catch(err => {
console.error('复制失败:', err)
this.fallbackCopy(urlToCopy)
})
} else {
// 使用旧的document.execCommand方法作为备选
this.fallbackCopy(urlToCopy)
}
},
// 备选复制方法
fallbackCopy(text) {
// 创建一个临时的textarea元素
const textArea = document.createElement('textarea')
textArea.value = text
textArea.style.position = 'fixed'
textArea.style.left = '-999999px'
textArea.style.top = '-999999px'
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
try {
const successful = document.execCommand('copy')
if (successful) {
this.handleCopySuccess()
} else {
this.$message.error('复制失败,请手动复制链接')
}
} catch (err) {
console.error('复制失败:', err)
this.$message.error('复制失败,请手动复制链接')
}
document.body.removeChild(textArea)
},
// 处理复制成功
handleCopySuccess() {
// 显示成功消息
this.$message.success('链接已复制到剪贴板')
// 设置复制状态
this.isCopied = true
// 清除之前的定时器
if (this.copyTimer) {
clearTimeout(this.copyTimer)
}
// 3秒后重置复制状态
this.copyTimer = setTimeout(() => {
this.isCopied = false
}, 3000)
// 隐藏提示框
this.showTooltip = false
},
// 重置表单
resetForm() {
this.formData = {
content: '',
custom_type: '1',
name: '',
phone: '',
company: '',
email: '',
checked: false,
...this.defaultFormData
}
// 清除表单验证
if (this.$refs.ruleForm) {
this.$refs.ruleForm.clearValidate()
}
},
// 关闭弹窗
handleClose() {
this.dialogVisible = false
this.$emit('close')
},
// 提交表单
handleSubmit() {
// 验证是否勾选协议
if (!this.formData.checked) {
this.$message.warning('请勾选同意协议后再提交!')
return
}
// 验证表单
this.$refs.ruleForm.validate(valid => {
if (valid) {
this.submitForm()
} else {
this.$message.error('请完善表单信息')
}
})
},
// 提交表单数据
async submitForm() {
this.loading = true
try {
const submitData = {
...this.formData,
url_link: this.currentUrl || window.location.href
}
// 如果有自定义提交函数,使用自定义函数
if (this.submitApi) {
const response = await this.submitApi(submitData)
this.handleResponse(response)
} else {
// 否则使用默认提交方式
const response = await this.defaultSubmitApi(submitData)
this.handleResponse(response)
}
} catch (error) {
console.error('提交咨询失败:', error)
this.$message.error('提交失败,请稍后再试!')
} finally {
this.loading = false
}
},
// 默认提交接口(如果没有传入自定义函数)
async defaultSubmitApi(data) {
// 这里可以添加默认的提交逻辑
// 例如return await this.$http.post('/api/consult', data)
},
// 处理响应结果
handleResponse(response) {
if (response && response.status) {
this.handleClose()
this.$emit('success', response)
} else {
this.$message.error(response?.msg || '提交失败,请稍后再试!')
this.$emit('error', response)
}
}
},
beforeDestroy() {
// 清除定时器
if (this.copyTimer) {
clearTimeout(this.copyTimer)
}
}
}
</script>
<style scoped lang="less">
@import url('../less/dialog/index.less');
</style>