587 lines
14 KiB
Vue
587 lines
14 KiB
Vue
<template>
|
||
<el-dialog
|
||
:visible.sync="dialogVisible"
|
||
:fullscreen="true"
|
||
custom-class="mobile-consult-fullscreen-dialog"
|
||
:append-to-body="true"
|
||
:close-on-click-modal="false"
|
||
:close-on-press-escape="!submitSuccess"
|
||
:show-close="false"
|
||
@close="handleClose"
|
||
>
|
||
<div v-if="submitSuccess" class="submit-success-page">
|
||
<div class="success-icon">
|
||
<i class="el-icon-check"></i>
|
||
</div>
|
||
<h2 class="success-title">已完成</h2>
|
||
<p class="success-desc">您的咨询信息已提交,我们会尽快与您联系。</p>
|
||
</div>
|
||
|
||
<div v-else class="mobile-consult-wrap">
|
||
<h2 class="mobile-consult-title">{{ title }}</h2>
|
||
<p class="mobile-consult-subtitle">期待与您开启AI创新未来</p>
|
||
|
||
<el-form
|
||
ref="consultForm"
|
||
:model="formData"
|
||
:rules="rules"
|
||
label-position="top"
|
||
class="mobile-consult-form"
|
||
>
|
||
<el-form-item label="1. 请填写您的姓名" prop="name">
|
||
<el-input
|
||
v-model.trim="formData.name"
|
||
maxlength="20"
|
||
placeholder="请输入您的姓名"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="2. 请填写您的联系方式" prop="phone">
|
||
<el-input
|
||
v-model.trim="formData.phone"
|
||
maxlength="11"
|
||
placeholder="请输入您的联系电话"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="3. 请填写您的邮箱" prop="email">
|
||
<el-input
|
||
v-model.trim="formData.email"
|
||
maxlength="60"
|
||
placeholder="请输入您的邮箱"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="4. 请填写您的公司名称" prop="company">
|
||
<el-input
|
||
v-model.trim="formData.company"
|
||
maxlength="80"
|
||
placeholder="请输入您的公司名称"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="5. 请选择您的企业类型(单选)" prop="enterprise_type">
|
||
<el-radio-group v-model="formData.enterprise_type" class="option-grid">
|
||
<el-radio
|
||
v-for="item in enterpriseOptions"
|
||
:key="item.id"
|
||
:label="item.id"
|
||
class="option-item"
|
||
>
|
||
{{ item.name }}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="6. 请选择您所在的省份(单选)" prop="region">
|
||
<el-select
|
||
v-model="formData.region"
|
||
filterable
|
||
placeholder="输入省份名称或拼音首字母搜索..."
|
||
class="full-select"
|
||
>
|
||
<el-option
|
||
v-for="item in provinceOptions"
|
||
:key="item.id"
|
||
:label="item.name"
|
||
:value="item.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="7. 您想咨询的方向(可多选)">
|
||
<el-checkbox-group v-model="formData.consult_direction_list" class="direction-list">
|
||
<el-checkbox
|
||
v-for="item in consultDirectionOptions"
|
||
:key="item.id"
|
||
:label="item.id"
|
||
class="direction-item"
|
||
>
|
||
<span class="direction-main">{{ item.title }}</span>
|
||
<span class="direction-sub">{{ item.desc }}</span>
|
||
</el-checkbox>
|
||
</el-checkbox-group>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="8. 如果您有其他问题需要咨询,请留言">
|
||
<el-input
|
||
v-model.trim="formData.content"
|
||
type="textarea"
|
||
:autosize="{ minRows: 3, maxRows: 5 }"
|
||
maxlength="500"
|
||
show-word-limit
|
||
placeholder="请输入您想咨询的内容..."
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<div class="qrcode-area">
|
||
<p>长按二维码添加微信,获取专属服务</p>
|
||
<img src="@/assets/image/newkefu.png" alt="官方客服二维码">
|
||
</div>
|
||
|
||
<el-checkbox v-model="formData.checked" class="privacy-checkbox">
|
||
<span>
|
||
您填写的信息仅用于本次业务对接沟通,公司将严格落实信息安全保护机制,不泄露、不滥用您的任何个人资料。
|
||
</span>
|
||
</el-checkbox>
|
||
|
||
<el-button
|
||
type="primary"
|
||
class="submit-btn"
|
||
:loading="loading"
|
||
@click="handleSubmit"
|
||
>
|
||
提交咨询
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script>
|
||
import { reqConsultForm, reqProductConsult } from '@/api/H5'
|
||
|
||
export default {
|
||
name: 'MobileFullScreenConsultDialog',
|
||
props: {
|
||
visible: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
title: {
|
||
type: String,
|
||
default: '开元云科技合作咨询'
|
||
},
|
||
qrCode: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
currentUrl: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
submitApi: {
|
||
type: Function,
|
||
default: null
|
||
}
|
||
},
|
||
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,
|
||
formData: this.getInitialFormData(),
|
||
enterpriseOptions: [],
|
||
provinceOptions: [],
|
||
consultDirectionOptions: [],
|
||
submitSuccess: false,
|
||
rules: {
|
||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||
phone: [{ required: true, validator: validatePhone, trigger: 'blur' }],
|
||
email: [
|
||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
|
||
],
|
||
company: [{ required: true, message: '请输入公司名称', trigger: 'blur' }],
|
||
enterprise_type: [{ required: true, message: '请选择企业类型', trigger: 'change' }],
|
||
region: [{ required: true, message: '请选择所在省份', trigger: 'change' }]
|
||
},
|
||
originalOverflow: ''
|
||
}
|
||
},
|
||
computed: {
|
||
dialogVisible: {
|
||
get() {
|
||
return this.visible
|
||
},
|
||
set(value) {
|
||
this.$emit('update:visible', value)
|
||
}
|
||
}
|
||
},
|
||
watch: {
|
||
visible: {
|
||
immediate: true,
|
||
handler(newVal) {
|
||
if (newVal) {
|
||
this.resetForm()
|
||
this.fetchConsultOptions()
|
||
this.disableBodyScroll()
|
||
} else {
|
||
this.enableBodyScroll()
|
||
}
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
getInitialFormData() {
|
||
return {
|
||
custom_type: '1',
|
||
name: '',
|
||
phone: '',
|
||
email: '',
|
||
company: '',
|
||
enterprise_type: '',
|
||
region: '',
|
||
consult_direction_list: [],
|
||
content: '',
|
||
checked: false
|
||
}
|
||
},
|
||
resetForm() {
|
||
this.formData = this.getInitialFormData()
|
||
this.submitSuccess = false
|
||
this.$nextTick(() => {
|
||
if (this.$refs.consultForm) this.$refs.consultForm.clearValidate()
|
||
})
|
||
},
|
||
disableBodyScroll() {
|
||
this.originalOverflow = document.body.style.overflow
|
||
document.body.style.overflow = 'hidden'
|
||
},
|
||
enableBodyScroll() {
|
||
document.body.style.overflow = this.originalOverflow || ''
|
||
},
|
||
handleClose() {
|
||
this.dialogVisible = false
|
||
this.$emit('close')
|
||
},
|
||
normalizeDictOptions(list, type) {
|
||
return list
|
||
.filter(item => item && item.dict_type === type)
|
||
.sort((a, b) => Number(a.sort_order || 0) - Number(b.sort_order || 0))
|
||
.map(item => ({
|
||
id: item.dict_key,
|
||
name: item.dict_value
|
||
}))
|
||
},
|
||
normalizeDirectionOptions(list) {
|
||
return list
|
||
.filter(item => item && item.dict_type === 'direction')
|
||
.sort((a, b) => Number(a.sort_order || 0) - Number(b.sort_order || 0))
|
||
.map(item => {
|
||
const value = item.dict_value || ''
|
||
const match = value.match(/^(.+?)((.+?))$/)
|
||
return {
|
||
id: String(item.dict_key),
|
||
name: value,
|
||
title: match ? match[1] : value,
|
||
desc: match ? match[2] : ''
|
||
}
|
||
})
|
||
},
|
||
extractConsultOptionList(res) {
|
||
if (res && Array.isArray(res.data)) return res.data
|
||
if (res && res.data && Array.isArray(res.data.data)) return res.data.data
|
||
return []
|
||
},
|
||
async fetchConsultOptions() {
|
||
try {
|
||
const res = await reqConsultForm()
|
||
const list = this.extractConsultOptionList(res)
|
||
if (!list.length) return
|
||
|
||
const enterpriseOptions = this.normalizeDictOptions(list, 'enterprise_type')
|
||
const provinceOptions = this.normalizeDictOptions(list, 'region')
|
||
const consultDirectionOptions = this.normalizeDirectionOptions(list)
|
||
|
||
if (enterpriseOptions.length) this.enterpriseOptions = enterpriseOptions
|
||
if (provinceOptions.length) this.provinceOptions = provinceOptions
|
||
if (consultDirectionOptions.length) this.consultDirectionOptions = consultDirectionOptions
|
||
} catch (error) {
|
||
// 保留本地兜底选项,避免接口异常时无法填写表单。
|
||
}
|
||
},
|
||
buildSubmitPayload() {
|
||
return {
|
||
custom_type: this.formData.custom_type,
|
||
name: this.formData.name,
|
||
phone: this.formData.phone,
|
||
email: this.formData.email,
|
||
company: this.formData.company,
|
||
enterprise_type: this.formData.enterprise_type,
|
||
region: this.formData.region,
|
||
consult_direction: this.formData.consult_direction_list.join(','),
|
||
content: this.formData.content,
|
||
source: '公众号',
|
||
url_link: this.currentUrl || window.location.href
|
||
}
|
||
},
|
||
async handleSubmit() {
|
||
if (!this.formData.checked) {
|
||
this.$message.warning('请先勾选信息安全与隐私保护说明')
|
||
return
|
||
}
|
||
this.$refs.consultForm.validate(async valid => {
|
||
if (!valid) return
|
||
this.loading = true
|
||
try {
|
||
const payload = this.buildSubmitPayload()
|
||
const response = this.submitApi ? await this.submitApi(payload) : await reqProductConsult(payload)
|
||
if (response && (response.status === true || response.status === 'true')) {
|
||
this.$emit('success', response)
|
||
this.submitSuccess = true
|
||
} else {
|
||
this.$message.error((response && response.msg) || '提交失败,请稍后再试')
|
||
}
|
||
} catch (error) {
|
||
this.$message.error('提交失败,请稍后再试')
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
})
|
||
}
|
||
},
|
||
beforeDestroy() {
|
||
this.enableBodyScroll()
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
::v-deep .mobile-consult-fullscreen-dialog {
|
||
margin: 0 !important;
|
||
width: 100% !important;
|
||
max-width: 100% !important;
|
||
height: 100vh;
|
||
border-radius: 0;
|
||
|
||
.el-dialog__header {
|
||
padding: 14px 14px 8px;
|
||
border-bottom: 0;
|
||
}
|
||
|
||
.el-dialog__title {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #111827;
|
||
}
|
||
|
||
.el-dialog__body {
|
||
height: calc(100vh - 60px);
|
||
padding: 12px 14px 18px;
|
||
overflow-y: auto;
|
||
}
|
||
}
|
||
|
||
.mobile-consult-wrap {
|
||
padding-bottom: 8px;
|
||
}
|
||
|
||
.submit-success-page {
|
||
min-height: calc(100vh - 110px);
|
||
padding: 80px 24px 24px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.success-icon {
|
||
width: 88px;
|
||
height: 88px;
|
||
border-radius: 50%;
|
||
background: #22c55e;
|
||
color: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 14px 28px rgba(34, 197, 94, 0.22);
|
||
|
||
i {
|
||
font-size: 46px;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
.success-title {
|
||
margin: 24px 0 10px;
|
||
color: #111827;
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.mobile-consult-title {
|
||
margin: 0;
|
||
font-size: 24px;
|
||
line-height: 1.25;
|
||
color: #111827;
|
||
}
|
||
|
||
.mobile-consult-subtitle {
|
||
margin: 6px 0 16px;
|
||
font-size: 12px;
|
||
color: #9ca3af;
|
||
}
|
||
|
||
.mobile-consult-form {
|
||
::v-deep .el-form-item {
|
||
margin-bottom: 18px;
|
||
}
|
||
|
||
::v-deep .el-form-item__content,
|
||
::v-deep .el-input,
|
||
::v-deep .el-select,
|
||
::v-deep .el-textarea {
|
||
width: 100%;
|
||
}
|
||
|
||
::v-deep .el-form-item__label {
|
||
padding-bottom: 6px;
|
||
font-size: 13px;
|
||
line-height: 1.3;
|
||
color: #1f2937;
|
||
font-weight: 600;
|
||
}
|
||
|
||
::v-deep .el-form-item__error {
|
||
position: static;
|
||
padding-top: 6px;
|
||
line-height: 1.25;
|
||
font-size: 12px;
|
||
}
|
||
|
||
::v-deep .el-input__inner {
|
||
height: 40px;
|
||
border-radius: 10px;
|
||
border: 1px solid #e5e7eb;
|
||
}
|
||
|
||
::v-deep .el-form-item.is-error .el-input__inner,
|
||
::v-deep .el-form-item.is-error .el-textarea__inner {
|
||
border-color: #f56c6c;
|
||
}
|
||
|
||
::v-deep .el-textarea__inner {
|
||
border-radius: 10px;
|
||
border: 1px solid #e5e7eb;
|
||
}
|
||
}
|
||
|
||
.option-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||
gap: 8px;
|
||
width: 100%;
|
||
}
|
||
|
||
.option-item {
|
||
margin-right: 0 !important;
|
||
padding: 9px 8px;
|
||
border: 1px solid #e5e7eb;
|
||
border-radius: 10px;
|
||
white-space: nowrap;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
|
||
::v-deep .el-radio__label {
|
||
padding-left: 6px;
|
||
font-size: 12px;
|
||
color: #374151;
|
||
}
|
||
}
|
||
|
||
.full-select {
|
||
width: 100%;
|
||
}
|
||
|
||
.direction-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8px;
|
||
width: 100%;
|
||
}
|
||
|
||
.direction-item {
|
||
margin-right: 0 !important;
|
||
border: 1px solid #e5e7eb;
|
||
border-radius: 10px;
|
||
padding: 10px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
|
||
::v-deep .el-checkbox__label {
|
||
display: inline-flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
padding-left: 8px;
|
||
}
|
||
}
|
||
|
||
.direction-main {
|
||
font-size: 14px;
|
||
color: #111827;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.direction-sub {
|
||
font-size: 12px;
|
||
color: #9ca3af;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.qrcode-area {
|
||
margin: 16px 0;
|
||
text-align: center;
|
||
padding: 18px 0;
|
||
background: #f7f8fa;
|
||
border-radius: 12px;
|
||
|
||
p {
|
||
margin: 0 0 10px;
|
||
font-size: 12px;
|
||
color: #6b7280;
|
||
}
|
||
|
||
img {
|
||
width: 98px;
|
||
height: 98px;
|
||
border-radius: 8px;
|
||
border: 1px dashed #3b82f6;
|
||
}
|
||
}
|
||
|
||
.privacy-checkbox {
|
||
margin: 0 0 14px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
|
||
::v-deep .el-checkbox__input {
|
||
margin-top: 3px;
|
||
}
|
||
|
||
::v-deep .el-checkbox__label {
|
||
padding-left: 8px;
|
||
color: #6b7280;
|
||
font-size: 12px;
|
||
line-height: 1.6;
|
||
white-space: normal;
|
||
}
|
||
}
|
||
|
||
.submit-btn {
|
||
width: 100%;
|
||
height: 44px;
|
||
border: none;
|
||
border-radius: 999px;
|
||
background: #111827;
|
||
color: #fff;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
</style>
|