403 lines
10 KiB
Vue
403 lines
10 KiB
Vue
<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>
|