376 lines
10 KiB
Vue
376 lines
10 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 标题 -->
|
||
<div class="top-tit">
|
||
开元云
|
||
</div>
|
||
|
||
<!-- 搜索框(完善功能) -->
|
||
<div class="search">
|
||
<div class="search-box">
|
||
<div class="input">
|
||
<input
|
||
type="text"
|
||
placeholder="请输入产品名称"
|
||
v-model="keyWord"
|
||
@keyup.enter="search"
|
||
/>
|
||
</div>
|
||
<div class="search-btn" @click="search">
|
||
搜索
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 供应商 -->
|
||
<div class="supplier-container" v-if="!isSearchMode">
|
||
<div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)">
|
||
<div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }">
|
||
{{ value.secTitle }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 云产品 -->
|
||
<div class="box">
|
||
<!-- 无数据提示 -->
|
||
<div v-if="showNoData" class="no-data">
|
||
暂无相关产品数据
|
||
</div>
|
||
|
||
<!-- 搜索模式:显示所有产品 -->
|
||
<template v-else-if="isSearchMode && searchResults.length > 0">
|
||
<div v-for="product in searchResults" :key="product.id" class="box-item">
|
||
<!-- 标题 -->
|
||
<div class="item-tit">
|
||
{{ product.name }}
|
||
</div>
|
||
|
||
<!-- 产品描述(如果有) -->
|
||
<div class="item-detail" v-if="product.description">
|
||
{{ product.description }}
|
||
</div>
|
||
|
||
<!-- 供应商标签 -->
|
||
<div class="item-desc" v-if="product.label">
|
||
{{ product.label }}
|
||
</div>
|
||
|
||
<!-- 立即咨询 -->
|
||
<div class="item-btn">
|
||
<div class="btn" @click="openConsultDialog(product, null)">
|
||
立即咨询
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 正常模式:只显示当前选中的供应商的产品 -->
|
||
<template v-else-if="!isSearchMode && activeSupplierIndex >= 0">
|
||
<template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu">
|
||
<div v-for="product in thrMenu.value" :key="product.id" class="box-item">
|
||
<!-- 标题 -->
|
||
<div class="item-tit">
|
||
{{ product.name }}
|
||
</div>
|
||
|
||
<!-- 产品描述(如果有) -->
|
||
<div class="item-detail" v-if="product.description">
|
||
{{ product.description }}
|
||
</div>
|
||
|
||
<!-- 供应商标签 -->
|
||
<div class="item-desc" v-if="showProductDesc(product)">
|
||
{{ getProductDesc(product) }}
|
||
</div>
|
||
|
||
<!-- 立即咨询 -->
|
||
<div class="item-btn">
|
||
<div class="btn" @click="openConsultDialog(product, thrMenu)">
|
||
立即咨询
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</template>
|
||
</div>
|
||
|
||
<!-- 产品咨询弹窗 -->
|
||
<ProductConsultDialog :visible.sync="showConsultDialog" :platform-name="platformName" :qr-code="qrCode"
|
||
:default-form-data="consultFormData" :submit-api="submitConsultApi" @success="handleConsultSuccess"
|
||
@close="handleDialogClose" />
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { reqNavList } from '@/api/H5/index'
|
||
import ProductConsultDialog from '../components/H5_dialog/index.vue'
|
||
import { reqProductConsult } from '@/api/H5/index'
|
||
|
||
export default {
|
||
components: {
|
||
ProductConsultDialog
|
||
},
|
||
|
||
data() {
|
||
return {
|
||
cloudData: {},
|
||
activeSupplierIndex: 0, // 默认选中第一个供应商
|
||
keyWord: '',
|
||
// 搜索相关
|
||
isSearchMode: false,
|
||
searchResults: [],
|
||
// 咨询弹窗相关
|
||
showConsultDialog: false,
|
||
platformName: '开元云',
|
||
qrCode: '',
|
||
consultFormData: {
|
||
content: '',
|
||
custom_type: '1',
|
||
name: '',
|
||
phone: '',
|
||
company: '',
|
||
email: '',
|
||
checked: false
|
||
},
|
||
currentProduct: null,
|
||
currentCategory: null,
|
||
searchTimer: null // 防抖定时器
|
||
}
|
||
},
|
||
created() {
|
||
this.getCloudData()
|
||
},
|
||
computed: {
|
||
// 当前选中的供应商标题
|
||
currentSupplierTitle() {
|
||
if (this.cloudData.secMenu && this.cloudData.secMenu[this.activeSupplierIndex]) {
|
||
return this.cloudData.secMenu[this.activeSupplierIndex].secTitle
|
||
}
|
||
return ''
|
||
},
|
||
// 显示无数据提示
|
||
showNoData() {
|
||
if (this.isSearchMode) {
|
||
return this.searchResults.length === 0
|
||
} else {
|
||
return !this.cloudData.secMenu || this.cloudData.secMenu.length === 0
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
// 防抖处理:避免频繁请求
|
||
debounce(func, delay = 500) {
|
||
return (...args) => {
|
||
if (this.searchTimer) clearTimeout(this.searchTimer)
|
||
this.searchTimer = setTimeout(() => {
|
||
func.apply(this, args)
|
||
}, delay)
|
||
}
|
||
},
|
||
|
||
// 判断是否显示供应商标签
|
||
showProductDesc(product) {
|
||
// 如果是百度云且有label字段
|
||
if (this.currentSupplierTitle === '百度云' && product.label) {
|
||
return true
|
||
}
|
||
|
||
// 如果是阿里云,总是显示(因为阿里云数据中没有label字段)
|
||
if (this.currentSupplierTitle === '阿里云') {
|
||
return true
|
||
}
|
||
|
||
// 其他情况
|
||
return false
|
||
},
|
||
|
||
// 获取供应商标签内容
|
||
getProductDesc(product) {
|
||
// 获取当前供应商标题
|
||
const supplierTitle = this.currentSupplierTitle
|
||
|
||
// 处理百度云
|
||
if (supplierTitle === '百度云') {
|
||
// 如果product有ssecTitle字段(虽然你的数据中没有),使用它
|
||
if (product.ssecTitle && product.ssecTitle.trim() !== '') {
|
||
return product.ssecTitle
|
||
}
|
||
// 否则使用label字段
|
||
return product.label || '百度云'
|
||
}
|
||
|
||
// 处理阿里云 - 阿里云数据中没有ssecTitle和label字段,所以直接显示供应商名称
|
||
if (supplierTitle === '阿里云') {
|
||
// 如果阿里云的数据结构中有ssecTitle字段,使用它
|
||
if (product.ssecTitle && product.ssecTitle.trim() !== '') {
|
||
return product.ssecTitle
|
||
}
|
||
// 如果阿里云的数据结构中有label字段,使用它
|
||
if (product.label && product.label.trim() !== '') {
|
||
return product.label
|
||
}
|
||
// 否则显示"阿里云"
|
||
return '阿里云'
|
||
}
|
||
|
||
// 默认返回供应商标题
|
||
return supplierTitle
|
||
},
|
||
|
||
// 获取云数据(支持接收keyword参数)
|
||
async getCloudData(keyword = '') {
|
||
if (keyword) {
|
||
this.keyWord = keyword
|
||
}
|
||
|
||
try {
|
||
const res = await reqNavList({
|
||
url_link: window.location.href,
|
||
keyword: this.keyWord.trim() // 去除首尾空格,避免空字符请求
|
||
})
|
||
|
||
if (res.status == true) {
|
||
// 判断是搜索模式还是正常模式
|
||
if (this.keyWord.trim() && Array.isArray(res.data)) {
|
||
// 搜索模式:返回的是数组
|
||
this.isSearchMode = true
|
||
this.searchResults = res.data
|
||
console.log('搜索模式数据:', this.searchResults)
|
||
} else {
|
||
// 正常模式:返回的是嵌套结构
|
||
this.isSearchMode = false
|
||
this.searchResults = []
|
||
this.cloudData = res.data.product_service[0] || {}
|
||
console.log('正常模式数据:', this.cloudData)
|
||
|
||
// 确保有数据时重置选中第一个供应商
|
||
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
|
||
this.activeSupplierIndex = 0
|
||
} else {
|
||
this.activeSupplierIndex = -1
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('获取数据失败:', error)
|
||
}
|
||
},
|
||
|
||
// 搜索方法(绑定防抖)
|
||
search: function() {
|
||
// 调用防抖后的获取数据方法
|
||
this.debounce(this.getCloudData)(this.keyWord)
|
||
},
|
||
|
||
// 选择供应商(不允许取消选中)
|
||
selectSupplier(index) {
|
||
this.activeSupplierIndex = index
|
||
},
|
||
|
||
// 打开咨询弹窗
|
||
openConsultDialog(product, category) {
|
||
this.currentProduct = product
|
||
this.currentCategory = category
|
||
|
||
// 设置咨询表单的预填内容
|
||
let content = `我想咨询关于【${product.name}】的产品信息`
|
||
if (product.description) {
|
||
content += ` - ${product.description}`
|
||
}
|
||
|
||
this.consultFormData = {
|
||
...this.consultFormData,
|
||
content: content
|
||
}
|
||
|
||
this.showConsultDialog = true
|
||
},
|
||
|
||
// 提交咨询API
|
||
async submitConsultApi(data) {
|
||
// 如果有额外的产品信息,可以添加到提交数据中
|
||
const submitData = {
|
||
...data,
|
||
product_name: this.currentProduct?.name || '',
|
||
product_description: this.currentProduct?.description || '',
|
||
product_label: this.currentProduct?.label || '',
|
||
product_category: this.currentCategory?.thrTitle || '',
|
||
supplier_name: this.isSearchMode ? '搜索产品' : (this.cloudData.secMenu[this.activeSupplierIndex]?.secTitle || ''),
|
||
page_type: this.isSearchMode ? 'search_result' : 'product_list'
|
||
}
|
||
|
||
return await reqProductConsult(submitData)
|
||
},
|
||
|
||
// 咨询成功回调
|
||
handleConsultSuccess(response) {
|
||
console.log('咨询提交成功:', response)
|
||
this.$message.success('咨询提交成功,我们将尽快联系您!')
|
||
},
|
||
|
||
// 弹窗关闭回调
|
||
handleDialogClose() {
|
||
this.currentProduct = null
|
||
this.currentCategory = null
|
||
// 重置表单数据
|
||
this.consultFormData = {
|
||
content: '',
|
||
custom_type: '1',
|
||
name: '',
|
||
phone: '',
|
||
company: '',
|
||
email: '',
|
||
checked: false
|
||
}
|
||
},
|
||
|
||
// 清空搜索
|
||
clearSearch() {
|
||
this.keyWord = ''
|
||
this.isSearchMode = false
|
||
this.searchResults = []
|
||
this.getCloudData()
|
||
}
|
||
},
|
||
// 销毁时清除定时器
|
||
beforeDestroy() {
|
||
if (this.searchTimer) clearTimeout(this.searchTimer)
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
html,
|
||
body {
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
}
|
||
</style>
|
||
<style lang="less" scoped>
|
||
@import url('../less/cloud/cloud.less');
|
||
|
||
// 新增无数据样式
|
||
.no-data {
|
||
text-align: center;
|
||
padding: 40px 0;
|
||
color: #999;
|
||
font-size: 14px;
|
||
}
|
||
|
||
// 搜索模式提示
|
||
.search-mode-tip {
|
||
text-align: center;
|
||
padding: 10px 0;
|
||
color: #666;
|
||
font-size: 14px;
|
||
|
||
.clear-btn {
|
||
color: #409EFF;
|
||
text-decoration: underline;
|
||
cursor: pointer;
|
||
margin-left: 10px;
|
||
}
|
||
}
|
||
</style>
|