This commit is contained in:
hrx 2025-12-24 09:52:03 +08:00
parent 1803df3994
commit 9d4bf4ea67
120 changed files with 779 additions and 447 deletions

View File

@ -41,51 +41,6 @@ import FloatingBox from './components/FloatingBox/FloatingBox.vue'; // 导入悬
import '@/assets/elementStyle.css' import '@/assets/elementStyle.css'
import Hammer from 'hammerjs'; import Hammer from 'hammerjs';
import {mapState} from "vuex"; import {mapState} from "vuex";
import {white} from "mockjs/src/mock/random/color_dict";
// ctrl + +/- ctrl +
// document.addEventListener(
// "keydown",
// function (event) {
// if (
// (event.ctrlKey === true || event.metaKey === true) &&
// (event.which === 61 ||
// event.which === 107 ||
// event.which === 173 ||
// event.which === 109 ||
// event.which === 187 ||
// event.which === 189)
// ) {
// event.preventDefault();
// }
// },
// false
// );
// Chrome IE 360
// window.addEventListener(
// "mousewheel",
// function (event) {
// if (event.ctrlKey === true || event.metaKey) {
// event.preventDefault();
//
// },
// {
// passive: false,
// }
// );
//
// // firefox
// window.addEventListener(
// "DOMMouseScroll",
// function (event) {
// if (event.ctrlKey === true || event.metaKey) {
// event.preventDefault();
// }
// },
// {
// passive: false,
// }
// );
export default { export default {
name: "App", name: "App",
components: { components: {
@ -100,16 +55,6 @@ export default {
customerName: '' customerName: ''
} }
}, },
created() {
// if (sessionStorage.getItem('userId')) {
// if (sessionStorage.getItem('org_type')=='2'||sessionStorage.getItem('org_type')=='3') {
// this.isshow=true
// }else{
// this.isshow=false
// }
// }
},
mounted() { mounted() {
this.audioElement = new Audio('https://www.kaiyuancloud.cn/dev/idfile?path=/batch_upload/phone-ring.mp3'); this.audioElement = new Audio('https://www.kaiyuancloud.cn/dev/idfile?path=/batch_upload/phone-ring.mp3');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -4,7 +4,8 @@
<div class="top-tit"> <div class="top-tit">
开元云 开元云
</div> </div>
<!-- 搜索 -->
<!-- 搜索 -->
<div class="search"> <div class="search">
<div class="search-box"> <div class="search-box">
<div class="input"> <div class="input">
@ -20,18 +21,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 供应商 -->
<div v-if="cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container"> <!-- 搜索提示 -->
<div <div v-if="isSearching && searchValue" class="search-tip">
v-for="(value, index) in cloudData.secMenu" 搜索关键词: "{{ searchValue }}"
:key="index" <span class="clear-search" @click="clearSearch">× 清空搜索</span>
class="supplier" </div>
@click="selectSupplier(index)"
> <!-- 供应商 - 只在非搜索模式显示 -->
<div <div v-if="!isSearching && cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container">
class="supplier-title" <div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)">
:class="{ 'active': activeSupplierIndex === index }" <div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }">
>
{{ value.secTitle }} {{ value.secTitle }}
</div> </div>
</div> </div>
@ -39,34 +39,45 @@
<!-- 产品 --> <!-- 产品 -->
<div class="box"> <div class="box">
<!-- 只显示当前选中的供应商的产品 --> <!-- 搜索模式显示搜索结果 -->
<template v-if="cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0"> <template v-if="isSearching && 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">
{{ product.description }}
</div>
<div class="item-desc">
智算
</div>
<div class="item-btn">
<div class="btn" @click="goToDetail(product.id)">
查看详情
</div>
</div>
</div>
</template>
<!-- 搜索模式无结果 -->
<div v-else-if="isSearching && searchResults.length === 0" class="no-data">
未找到与"{{ searchValue }}"相关的产品
</div>
<!-- 正常模式只显示当前选中的供应商的产品 -->
<template v-else-if="!isSearching && cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0">
<template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu"> <template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu">
<!-- 循环每个分类下的产品 --> <div v-for="product in thrMenu.value" :key="product.id" class="box-item">
<div
v-for="product in thrMenu.value"
:key="product.id"
class="box-item"
v-show="shouldShowProduct(product)"
>
<!-- 标题 -->
<div class="item-tit"> <div class="item-tit">
{{ product.name }} {{ product.name }}
</div> </div>
<!-- 详情 -->
<div class="item-detail"> <div class="item-detail">
{{ product.description }} {{ product.description }}
</div> </div>
<!-- 描述 -->
<div class="item-desc"> <div class="item-desc">
智算 智算
</div> </div>
<!-- 立即咨询和查看详情 -->
<div class="item-btn"> <div class="item-btn">
<!-- <div class="btn" @click="openConsultDialog(product, thrMenu)">
立即咨询
</div> -->
<!-- 查看详情 带着id跳转/h5HomePage/details -->
<div class="btn" @click="goToDetail(product.id)"> <div class="btn" @click="goToDetail(product.id)">
查看详情 查看详情
</div> </div>
@ -74,84 +85,91 @@
</div> </div>
</template> </template>
</template> </template>
</div>
<!-- 正常模式无数据 -->
<div v-else-if="!isSearching && (!cloudData.secMenu || cloudData.secMenu.length === 0)" class="no-data">
暂无产品数据
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { reqNavList } from '@/api/H5/index' import { reqNavList } from '@/api/H5/index'
import ProductConsultDialog from '../components/H5_dialog/index.vue'
export default { export default {
data() { data() {
return { return {
cloudData: {}, cloudData: {},
activeSupplierIndex: 0, // activeSupplierIndex: 0,
searchValue: '', // searchValue: '',
isSearching: false, // isSearching: false,
searchResults: []
//
showConsultDialog: false,
platformName: '开元云',
qrCode: '',
consultFormData: {
content: '',
custom_type: '1',
name: '',
phone: '',
company: '',
email: '',
checked: false
},
currentProduct: null,
currentCategory: null
} }
}, },
created() { created() {
this.getCloudData() this.getCloudData()
}, },
methods: { methods: {
async getCloudData() { async getCloudData(keyword) {
const res = await reqNavList({ url_link: window.location.href }) try {
if (res.status == true) { const params = {
this.cloudData = res.data.product_service[1] url_link: window.location.href,
// ...(keyword && { keyword: keyword.trim() })
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
} }
const res = await reqNavList(params)
if (res.status == true) {
if (keyword) {
//
this.isSearching = true
this.searchResults = Array.isArray(res.data) ? res.data : []
} else {
//
this.isSearching = false
this.searchResults = []
this.cloudData = res.data.product_service[1] || {}
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
}
}
}
} catch (error) {
console.error('获取数据失败:', error)
this.isSearching = false
this.searchResults = []
} }
}, },
// //
handleSearch() { handleSearch() {
this.isSearching = !!this.searchValue.trim() const keyword = this.searchValue.trim()
// API if (keyword) {
console.log('搜索关键词:', this.searchValue) this.getCloudData(keyword)
} else {
//
this.clearSearch()
}
}, },
// //
shouldShowProduct(product) { clearSearch() {
if (!this.isSearching) { this.isSearching = false
return true this.searchValue = ''
} this.searchResults = []
// this.getCloudData() //
const keyword = this.searchValue.toLowerCase().trim()
return (
(product.name && product.name.toLowerCase().includes(keyword)) ||
(product.description && product.description.toLowerCase().includes(keyword))
)
}, },
// //
selectSupplier(index) { selectSupplier(index) {
this.activeSupplierIndex = index if (!this.isSearching) {
this.activeSupplierIndex = index
}
}, },
// //
goToDetail(productId) { goToDetail(productId) {
// 使productId
if (productId === '2113') { if (productId === '2113') {
this.$router.push({ this.$router.push({
path: '/h5HomePage/details', path: '/h5HomePage/details',
@ -159,7 +177,7 @@ export default {
id: productId id: productId
} }
}) })
}else{ } else {
this.$router.push({ this.$router.push({
path: '/h5HomePage/netDetail', path: '/h5HomePage/netDetail',
query: { query: {
@ -173,12 +191,49 @@ export default {
</script> </script>
<style> <style>
html, html, body {
body {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
} }
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
@import url('../less/all/index.less'); @import url('../less/all/index.less');
/* 搜索提示样式 */
.search-tip {
padding: 10px 20px;
background-color: #f5f7fa;
color: #666;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e4e7ed;
}
.clear-search {
color: #409EFF;
cursor: pointer;
font-size: 12px;
padding: 2px 8px;
border-radius: 3px;
transition: all 0.3s;
}
.clear-search:hover {
background-color: #ecf5ff;
color: #409EFF;
}
/* 无数据样式 */
.no-data {
text-align: center;
padding: 40px 20px;
color: #909399;
font-size: 14px;
background-color: #f5f7fa;
border-radius: 4px;
margin: 20px;
}
</style> </style>

View File

@ -4,25 +4,26 @@
<div class="top-tit"> <div class="top-tit">
开元云 开元云
</div> </div>
<!-- 搜索 -->
<!-- 搜索框完善功能 -->
<div class="search"> <div class="search">
<div class="search-box"> <div class="search-box">
<div class="input"> <div class="input">
<input <input
type="text" type="text"
placeholder="请输入产品名称" placeholder="请输入产品名称"
v-model="searchValue" v-model="keyWord"
@keyup.enter="handleSearch" @keyup.enter="search"
/> />
</div> </div>
<div class="search-btn" @click="handleSearch"> <div class="search-btn" @click="search">
搜索 搜索
</div> </div>
</div> </div>
</div> </div>
<!-- 供应商 --> <!-- 供应商 -->
<div class="supplier-container"> <div class="supplier-container" v-if="!isSearchMode">
<div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)"> <div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)">
<div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }"> <div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }">
{{ value.secTitle }} {{ value.secTitle }}
@ -32,10 +33,42 @@
<!-- 云产品 --> <!-- 云产品 -->
<div class="box"> <div class="box">
<!-- 只显示当前选中的供应商的产品 --> <!-- 无数据提示 -->
<template v-if="cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0"> <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"> <template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu">
<div v-for="product in thrMenu.value" :key="product.id" class="box-item" v-show="shouldShowProduct(product)"> <div v-for="product in thrMenu.value" :key="product.id" class="box-item">
<!-- 标题 --> <!-- 标题 -->
<div class="item-tit"> <div class="item-tit">
{{ product.name }} {{ product.name }}
@ -83,9 +116,10 @@ export default {
return { return {
cloudData: {}, cloudData: {},
activeSupplierIndex: 0, // activeSupplierIndex: 0, //
searchValue: '', // keyWord: '',
isSearching: false, // //
isSearchMode: false,
searchResults: [],
// //
showConsultDialog: false, showConsultDialog: false,
platformName: '开元云', platformName: '开元云',
@ -100,7 +134,8 @@ export default {
checked: false checked: false
}, },
currentProduct: null, currentProduct: null,
currentCategory: null currentCategory: null,
searchTimer: null //
} }
}, },
created() { created() {
@ -113,28 +148,25 @@ export default {
return this.cloudData.secMenu[this.activeSupplierIndex].secTitle return this.cloudData.secMenu[this.activeSupplierIndex].secTitle
} }
return '' return ''
},
//
showNoData() {
if (this.isSearchMode) {
return this.searchResults.length === 0
} else {
return !this.cloudData.secMenu || this.cloudData.secMenu.length === 0
}
} }
}, },
methods: { methods: {
// //
handleSearch() { debounce(func, delay = 500) {
this.isSearching = !!this.searchValue.trim() return (...args) => {
console.log('搜索关键词:', this.searchValue) if (this.searchTimer) clearTimeout(this.searchTimer)
}, this.searchTimer = setTimeout(() => {
func.apply(this, args)
// }, delay)
shouldShowProduct(product) {
if (!this.isSearching) {
return true
} }
//
const keyword = this.searchValue.toLowerCase().trim()
return (
(product.name && product.name.toLowerCase().includes(keyword)) ||
(product.description && product.description.toLowerCase().includes(keyword)) ||
(product.label && product.label.toLowerCase().includes(keyword)) ||
(product.ssecTitle && product.ssecTitle.toLowerCase().includes(keyword))
)
}, },
// //
@ -186,39 +218,49 @@ export default {
return supplierTitle return supplierTitle
}, },
// // keyword
async getCloudData() { async getCloudData(keyword = '') {
const res = await reqNavList({ url_link: window.location.href }) if (keyword) {
if (res.status == true) { this.keyWord = keyword
this.cloudData = res.data.product_service[0]
console.log('云产品数据:', this.cloudData)
//
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
//
this.cloudData.secMenu.forEach((supplier, index) => {
console.log(`供应商 ${index} (${supplier.secTitle}):`)
if (supplier.thrMenu && supplier.thrMenu.length > 0) {
supplier.thrMenu.forEach((category, catIndex) => {
console.log(` 分类 ${catIndex} (${category.thrTitle}):`)
if (category.value && category.value.length > 0) {
//
const firstProduct = category.value[0]
console.log(` 第一个产品:`, {
name: firstProduct.name,
description: firstProduct.description,
label: firstProduct.label,
ssecTitle: firstProduct.ssecTitle,
source: firstProduct.source
})
}
})
}
})
}
} }
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)
}, },
// //
@ -232,9 +274,14 @@ export default {
this.currentCategory = category this.currentCategory = category
// //
let content = `我想咨询关于【${product.name}】的产品信息`
if (product.description) {
content += ` - ${product.description}`
}
this.consultFormData = { this.consultFormData = {
...this.consultFormData, ...this.consultFormData,
content: `我想咨询关于【${product.name}】的产品信息` content: content
} }
this.showConsultDialog = true this.showConsultDialog = true
@ -249,8 +296,8 @@ export default {
product_description: this.currentProduct?.description || '', product_description: this.currentProduct?.description || '',
product_label: this.currentProduct?.label || '', product_label: this.currentProduct?.label || '',
product_category: this.currentCategory?.thrTitle || '', product_category: this.currentCategory?.thrTitle || '',
supplier_name: this.cloudData.secMenu[this.activeSupplierIndex]?.secTitle || '', supplier_name: this.isSearchMode ? '搜索产品' : (this.cloudData.secMenu[this.activeSupplierIndex]?.secTitle || ''),
page_type: 'product_list' page_type: this.isSearchMode ? 'search_result' : 'product_list'
} }
return await reqProductConsult(submitData) return await reqProductConsult(submitData)
@ -259,7 +306,6 @@ export default {
// //
handleConsultSuccess(response) { handleConsultSuccess(response) {
console.log('咨询提交成功:', response) console.log('咨询提交成功:', response)
//
this.$message.success('咨询提交成功,我们将尽快联系您!') this.$message.success('咨询提交成功,我们将尽快联系您!')
}, },
@ -277,7 +323,19 @@ export default {
email: '', email: '',
checked: false checked: false
} }
},
//
clearSearch() {
this.keyWord = ''
this.isSearchMode = false
this.searchResults = []
this.getCloudData()
} }
},
//
beforeDestroy() {
if (this.searchTimer) clearTimeout(this.searchTimer)
} }
} }
</script> </script>
@ -291,4 +349,27 @@ body {
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
@import url('../less/cloud/cloud.less'); @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> </style>

View File

@ -54,7 +54,7 @@
</div> </div>
<!-- 备案信息 --> <!-- 备案信息 -->
<div class="footer-bottom"> <!-- <div class="footer-bottom">
<div class="icp-info"> <div class="icp-info">
<div class="icp-item"> <div class="icp-item">
<span class="icp-text">ICP备案号</span> <span class="icp-text">ICP备案号</span>
@ -79,7 +79,7 @@
</router-link> </router-link>
</div> </div>
</div> </div>
</div> </div> -->
</div> </div>
</div> </div>
</div> </div>

View File

@ -265,7 +265,7 @@ export default {
border-radius: .3rem; border-radius: .3rem;
padding: .2rem .2rem; padding: .2rem .2rem;
background-color: #fff; background-color: #fff;
padding-bottom: 2rem;
// //
.box-title { .box-title {
font-size: 0.24rem; font-size: 0.24rem;
@ -297,6 +297,9 @@ export default {
// //
.price { .price {
width: calc(100% - 0.4rem);
position: absolute;
bottom: .2rem;
font-size: .16rem; font-size: .16rem;
color: #F62424; color: #F62424;
margin-top: .2rem; margin-top: .2rem;

View File

@ -61,6 +61,8 @@
padding: 0.15rem 0.2rem; padding: 0.15rem 0.2rem;
margin: 0.34rem 0; margin: 0.34rem 0;
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative;
padding-bottom: 0.6rem;
} }
.box .box-item:hover { .box .box-item:hover {
transform: translateY(-0.05rem); transform: translateY(-0.05rem);
@ -91,17 +93,21 @@
.box .box-item .item-btn { .box .box-item .item-btn {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; padding-top: 0.2rem;
} }
.box .box-item .item-btn .btn { .box .box-item .item-btn .btn {
background: linear-gradient(90deg, #1f70ff, #3a8cff); background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
border-radius: 0.04rem;
padding: 0.08rem 0;
width: calc(100% - 0.4rem);
text-align: center;
color: #fff; color: #fff;
padding: 0.08rem 0.2rem; font-size: 0.182rem;
border-radius: 0.15rem;
font-size: 0.24rem;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
border: none; border: none;
position: absolute;
bottom: 0.2rem;
} }
.box .box-item .item-btn .btn:hover { .box .box-item .item-btn .btn:hover {
background: linear-gradient(90deg, #0d5aff, #2a7aff); background: linear-gradient(90deg, #0d5aff, #2a7aff);

View File

@ -68,7 +68,8 @@
padding: .15rem .2rem; padding: .15rem .2rem;
margin: .34rem 0; margin: .34rem 0;
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative;
padding-bottom: .6rem;
&:hover { &:hover {
transform: translateY(-0.05rem); transform: translateY(-0.05rem);
box-shadow: 0 .08rem .2rem rgba(0, 0, 0, 0.1); box-shadow: 0 .08rem .2rem rgba(0, 0, 0, 0.1);
@ -102,17 +103,23 @@
.item-btn { .item-btn {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; // justify-content: flex-end;
padding-top: .2rem;
.btn { .btn {
background: linear-gradient(90deg, #1f70ff, #3a8cff); background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
border-radius: 0.04rem;
// padding: 0.08rem ;
padding: .08rem 0;
width: calc(100% - 0.4rem);
text-align: center;
color: #fff; color: #fff;
padding: .08rem .2rem; font-size: 0.182rem;
border-radius: .15rem;
font-size: 0.24rem;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
border: none; border: none;
position: absolute;
bottom: 0.2rem;
&:hover { &:hover {
background: linear-gradient(90deg, #0d5aff, #2a7aff); background: linear-gradient(90deg, #0d5aff, #2a7aff);
@ -178,9 +185,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(90deg, background: linear-gradient(90deg,
rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0) 100%); rgba(255, 255, 255, 0) 100%);
transition: left 0.5s ease; transition: left 0.5s ease;
} }
@ -259,6 +266,7 @@
opacity: 0; opacity: 0;
transform: translateY(.1rem); transform: translateY(.1rem);
} }
100% { 100% {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);

View File

@ -53,6 +53,7 @@
padding: 0 0.3rem; padding: 0 0.3rem;
} }
.box .box-item { .box .box-item {
position: relative;
display: flex; display: flex;
width: 48%; width: 48%;
flex-direction: column; flex-direction: column;
@ -62,6 +63,7 @@
padding: 0.15rem 0.2rem; padding: 0.15rem 0.2rem;
margin: 0.34rem 0; margin: 0.34rem 0;
transition: all 0.3s ease; transition: all 0.3s ease;
padding-bottom: 0.6rem;
} }
.box .box-item:hover { .box .box-item:hover {
transform: translateY(-0.05rem); transform: translateY(-0.05rem);
@ -99,18 +101,21 @@
.box .box-item .item-btn { .box .box-item .item-btn {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; padding-top: 0.2rem;
} }
.box .box-item .item-btn .btn { .box .box-item .item-btn .btn {
background: linear-gradient(90deg, #1f70ff, #3a8cff); background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
border-radius: 0.04rem;
padding: 0.08rem 0;
width: calc(100% - 0.4rem);
text-align: center;
color: #fff; color: #fff;
padding: 0.08rem 0.2rem; font-size: 0.182rem;
border-radius: 0.15rem;
font-size: 0.24rem;
/* 修改为下方代码的字体大小 */
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
border: none; border: none;
position: absolute;
bottom: 0.2rem;
} }
.box .box-item .item-btn .btn:hover { .box .box-item .item-btn .btn:hover {
background: linear-gradient(90deg, #0d5aff, #2a7aff); background: linear-gradient(90deg, #0d5aff, #2a7aff);

View File

@ -60,6 +60,7 @@
padding: 0 .3rem; padding: 0 .3rem;
.box-item { .box-item {
position: relative;
display: flex; display: flex;
width: 48%; width: 48%;
flex-direction: column; flex-direction: column;
@ -69,6 +70,7 @@
padding: .15rem .2rem; padding: .15rem .2rem;
margin: .34rem 0; margin: .34rem 0;
transition: all 0.3s ease; transition: all 0.3s ease;
padding-bottom: .6rem;
&:hover { &:hover {
transform: translateY(-0.05rem); transform: translateY(-0.05rem);
@ -112,18 +114,24 @@
.item-btn { .item-btn {
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: flex-end; // justify-content: flex-end;
padding-top: .2rem;
.btn { .btn {
background: linear-gradient(90deg, #1f70ff, #3a8cff); background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
border-radius: 0.04rem;
// padding: 0.08rem ;
padding: .08rem 0;
width: calc(100% - 0.4rem);
text-align: center;
color: #fff; color: #fff;
padding: .08rem .2rem; font-size: 0.182rem;
border-radius: .15rem;
font-size: 0.24rem;
/* 修改为下方代码的字体大小 */
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
border: none; border: none;
position: absolute;
bottom: 0.2rem;
&:hover { &:hover {
background: linear-gradient(90deg, #0d5aff, #2a7aff); background: linear-gradient(90deg, #0d5aff, #2a7aff);
@ -134,6 +142,7 @@
} }
} }
} }
.search { .search {
width: 100%; width: 100%;
margin: .3rem 0; margin: .3rem 0;
@ -188,9 +197,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(90deg, background: linear-gradient(90deg,
rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0) 100%); rgba(255, 255, 255, 0) 100%);
transition: left 0.5s ease; transition: left 0.5s ease;
} }
@ -269,6 +278,7 @@
opacity: 0; opacity: 0;
transform: translateY(.1rem); transform: translateY(.1rem);
} }
100% { 100% {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);

View File

@ -5,6 +5,10 @@
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
.logo-item {
display: flex;
align-items: center;
}
.top-box { .top-box {
width: 100%; width: 100%;
height: 50vh; height: 50vh;
@ -79,16 +83,16 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%); background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%);
border: 1px solid rgba(39, 90, 255, 0.1); border: 0.01rem solid rgba(39, 90, 255, 0.1);
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative; position: relative;
padding-bottom: 1.2rem; padding-bottom: 1.8rem;
} }
.base-box .content .item-box:hover, .base-box .content .item-box:hover,
.journey-box .content .item-box:hover, .journey-box .content .item-box:hover,
.latitude-box .content .item-box:hover { .latitude-box .content .item-box:hover {
box-shadow: 0 0.04rem 0.16rem rgba(39, 90, 255, 0.12); box-shadow: 0 0.04rem 0.16rem rgba(39, 90, 255, 0.12);
transform: translateY(-2px); transform: translateY(-0.02rem);
border-color: rgba(39, 90, 255, 0.2); border-color: rgba(39, 90, 255, 0.2);
background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%); background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%);
} }
@ -145,10 +149,13 @@
.base-box .content .item-box .item-price, .base-box .content .item-box .item-price,
.journey-box .content .item-box .item-price, .journey-box .content .item-box .item-price,
.latitude-box .content .item-box .item-price { .latitude-box .content .item-box .item-price {
width: calc(100% - 0.4rem);
padding-top: 0.2rem;
border-top: 0.02rem dashed #d4d6e1;
font-size: 0.13rem; font-size: 0.13rem;
font-weight: bold; font-weight: bold;
color: #d4d6e1; color: #d4d6e1;
margin: 0.15rem 0; margin: 0.2rem 0;
position: absolute; position: absolute;
bottom: 0.6rem; bottom: 0.6rem;
} }
@ -194,7 +201,7 @@
margin-top: auto; margin-top: auto;
width: 100%; width: 100%;
position: relative; position: relative;
bottom: -0.9rem; bottom: -1.6rem;
} }
.base-box .content .item-box .item-button .item-button-text, .base-box .content .item-box .item-button .item-button-text,
.journey-box .content .item-box .item-button .item-button-text, .journey-box .content .item-box .item-button .item-button-text,
@ -228,8 +235,9 @@
.partner .partner-scroll .logo-scroll-container { .partner .partner-scroll .logo-scroll-container {
display: flex; display: flex;
height: 100%; height: 100%;
animation: scroll 15s linear infinite; animation: scroll linear infinite;
white-space: nowrap; white-space: nowrap;
width: max-content;
} }
.partner .partner-scroll .logo-item { .partner .partner-scroll .logo-item {
flex: 0 0 auto; flex: 0 0 auto;
@ -248,12 +256,14 @@
height: 100%; height: 100%;
object-fit: contain; object-fit: contain;
} }
/* 关键:无缝循环滚动动画 */
@keyframes scroll { @keyframes scroll {
0% { 0% {
transform: translateX(0); transform: translateX(0);
} }
100% { 100% {
transform: translateX(-50%); /* 因为图片重复了三份所以移动33.33%实现无缝循环 */
transform: translateX(-33.33%);
} }
} }
.footer { .footer {
@ -273,7 +283,7 @@
padding: 0.6rem 0.2rem 0.4rem; padding: 0.6rem 0.2rem 0.4rem;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-top: 1px solid #e8edf5; border-top: 0.01rem solid #e8edf5;
} }
.footer:before { .footer:before {
content: ''; content: '';
@ -308,9 +318,9 @@
padding: 0.3rem 0.2rem; padding: 0.3rem 0.2rem;
background: #fff; background: #fff;
border-radius: 0.16rem; border-radius: 0.16rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); box-shadow: 0 0.02rem 0.08rem rgba(0, 0, 0, 0.05);
margin-top: 0.4rem; margin-top: 0.4rem;
border: 1px solid #eef2f9; border: 0.01rem solid #eef2f9;
width: 100%; width: 100%;
} }
@media (min-width: 768px) { @media (min-width: 768px) {
@ -358,7 +368,7 @@
gap: 0.16rem; gap: 0.16rem;
} }
} }
.footer-center .contact-item .phone-link { .footer-center .contact-item .phone-link {
color: #333; color: #333;
text-decoration: none; text-decoration: none;
transition: all 0.3s; transition: all 0.3s;
@ -366,7 +376,7 @@
font-size: 0.208rem; font-size: 0.208rem;
/* 增大30%: 0.16rem * 1.3 = 0.208rem */ /* 增大30%: 0.16rem * 1.3 = 0.208rem */
} }
.footer-center .contact-item .phone-link:hover { .footer-center .contact-item .phone-link:hover {
color: #275AFF; color: #275AFF;
text-decoration: underline; text-decoration: underline;
} }
@ -410,8 +420,8 @@
background: #fff; background: #fff;
border-radius: 0.16rem; border-radius: 0.16rem;
padding: 0.24rem; padding: 0.24rem;
box-shadow: 0 2px 12px rgba(39, 90, 255, 0.08); box-shadow: 0 0.02rem 0.12rem rgba(39, 90, 255, 0.08);
border: 1px solid #eef2f9; border: 0.01rem solid #eef2f9;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.code-img .qr-box:hover { .code-img .qr-box:hover {

View File

@ -6,6 +6,11 @@
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
.logo-item {
display: flex;
align-items: center;
}
.top-box { .top-box {
width: 100%; width: 100%;
height: 50vh; height: 50vh;
@ -85,13 +90,14 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%); background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%);
border: 1px solid rgba(39, 90, 255, 0.1); border: .01rem solid rgba(39, 90, 255, 0.1);
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative; position: relative;
padding-bottom: 1.2rem; padding-bottom: 1.8rem;
&:hover { &:hover {
box-shadow: 0 .04rem .16rem rgba(39, 90, 255, 0.12); box-shadow: 0 .04rem .16rem rgba(39, 90, 255, 0.12);
transform: translateY(-2px); transform: translateY(-0.02rem);
border-color: rgba(39, 90, 255, 0.2); border-color: rgba(39, 90, 255, 0.2);
background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%); background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%);
} }
@ -141,12 +147,17 @@
} }
.item-price { .item-price {
width: calc(100% - 0.4rem);
padding-top: 0.2rem;
// 上虚线
border-top: .02rem dashed #d4d6e1;
font-size: 0.13rem; font-size: 0.13rem;
font-weight: bold; font-weight: bold;
color: #d4d6e1; color: #d4d6e1;
margin: 0.15rem 0; margin: 0.2rem 0;
position: absolute; position: absolute;
bottom: .6rem; bottom: .6rem;
.price { .price {
font-size: .38rem; font-size: .38rem;
color: #f52220; color: #f52220;
@ -184,10 +195,12 @@
margin-top: auto; margin-top: auto;
width: 100%; width: 100%;
position: relative; position: relative;
bottom: -0.9rem; bottom: -1.6rem;
.item-button-text { .item-button-text {
color: #fff; color: #fff;
font-size: 0.182rem; /* 增大30%: 0.14rem * 1.3 = 0.182rem */ font-size: 0.182rem;
/* 增大30%: 0.14rem * 1.3 = 0.182rem */
} }
} }
} }
@ -220,8 +233,9 @@
.logo-scroll-container { .logo-scroll-container {
display: flex; display: flex;
height: 100%; height: 100%;
animation: scroll 15s linear infinite; animation: scroll linear infinite;
white-space: nowrap; white-space: nowrap;
width: max-content;
} }
.logo-item { .logo-item {
@ -245,13 +259,15 @@
} }
} }
/* 关键:无缝循环滚动动画 */
@keyframes scroll { @keyframes scroll {
0% { 0% {
transform: translateX(0); transform: translateX(0);
} }
100% { 100% {
transform: translateX(-50%); /* 因为图片重复了三份所以移动33.33%实现无缝循环 */
transform: translateX(-33.33%);
} }
} }
@ -276,7 +292,7 @@
// margin-top: 1rem; // margin-top: 1rem;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-top: 1px solid #e8edf5; border-top: .01rem solid #e8edf5;
} }
.footer:before { .footer:before {
@ -322,9 +338,9 @@
padding: 0.3rem 0.2rem; padding: 0.3rem 0.2rem;
background: #fff; background: #fff;
border-radius: 0.16rem; border-radius: 0.16rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); box-shadow: 0 .02rem .08rem rgba(0, 0, 0, 0.05);
margin-top: 0.4rem; margin-top: 0.4rem;
border: 1px solid #eef2f9; border: .01rem solid #eef2f9;
width: 100%; width: 100%;
@media (min-width: 768px) { @media (min-width: 768px) {
@ -372,13 +388,15 @@
align-items: center; align-items: center;
gap: 0.16rem; gap: 0.16rem;
} }
}下 }
.phone-link { .phone-link {
color: #333; color: #333;
text-decoration: none; text-decoration: none;
transition: all 0.3s; transition: all 0.3s;
font-weight: 500; font-weight: 500;
font-size: 0.208rem; /* 增大30%: 0.16rem * 1.3 = 0.208rem */ font-size: 0.208rem;
/* 增大30%: 0.16rem * 1.3 = 0.208rem */
&:hover { &:hover {
color: #275AFF; color: #275AFF;
@ -400,7 +418,8 @@
text-decoration: none; text-decoration: none;
word-break: break-all; word-break: break-all;
font-weight: 500; font-weight: 500;
font-size: 0.208rem; /* 增大30%: 0.16rem * 1.3 = 0.208rem */ font-size: 0.208rem;
/* 增大30%: 0.16rem * 1.3 = 0.208rem */
&:hover { &:hover {
color: #2ebdfa; color: #2ebdfa;
@ -428,13 +447,12 @@
background: #fff; background: #fff;
border-radius: 0.16rem; border-radius: 0.16rem;
padding: 0.24rem; padding: 0.24rem;
box-shadow: 0 2px 12px rgba(39, 90, 255, 0.08); box-shadow: 0 .02rem .12rem rgba(39, 90, 255, 0.08);
border: 1px solid #eef2f9; border: .01rem solid #eef2f9;
transition: all 0.3s ease; transition: all 0.3s ease;
&:hover { &:hover {
background: #fff; background: #fff;
border-color: #2ebdfa; border-color: #2ebdfa;
transform: translateY(-4px); transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(39, 90, 255, 0.15); box-shadow: 0 8px 24px rgba(39, 90, 255, 0.15);
@ -460,7 +478,8 @@
.qr-content { .qr-content {
color: #333; color: #333;
font-size: 0.182rem; /* 增大30%: 0.14rem * 1.3 = 0.182rem */ font-size: 0.182rem;
/* 增大30%: 0.14rem * 1.3 = 0.182rem */
font-weight: 500; font-weight: 500;
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
@ -697,7 +716,8 @@
.qr-content { .qr-content {
color: #333; color: #333;
font-size: 0.182rem; /* 增大30%: 0.14rem * 1.3 = 0.182rem */ font-size: 0.182rem;
/* 增大30%: 0.14rem * 1.3 = 0.182rem */
font-weight: 500; font-weight: 500;
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }

View File

@ -4,7 +4,8 @@
<div class="top-tit"> <div class="top-tit">
开元云 开元云
</div> </div>
<!-- 搜索 -->
<!-- 搜索 -->
<div class="search"> <div class="search">
<div class="search-box"> <div class="search-box">
<div class="input"> <div class="input">
@ -20,18 +21,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 供应商 -->
<div v-if="cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container"> <!-- 搜索提示 -->
<div <div v-if="isSearching && searchValue" class="search-tip">
v-for="(value, index) in cloudData.secMenu" 搜索关键词: "{{ searchValue }}"
:key="index" <span class="clear-search" @click="clearSearch">× 清空搜索</span>
class="supplier" </div>
@click="selectSupplier(index)"
> <!-- 供应商 - 只在非搜索模式显示 -->
<div <div v-if="!isSearching && cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container">
class="supplier-title" <div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)">
:class="{ 'active': activeSupplierIndex === index }" <div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }">
>
{{ value.secTitle }} {{ value.secTitle }}
</div> </div>
</div> </div>
@ -39,33 +39,45 @@
<!-- 云产品 --> <!-- 云产品 -->
<div class="box"> <div class="box">
<!-- 只显示当前选中的供应商的产品 --> <!-- 搜索模式显示搜索结果 -->
<template v-if="cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0"> <template v-if="isSearching && 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">
{{ product.description }}
</div>
<div class="item-desc">
算力网络
</div>
<div class="item-btn">
<div class="btn" @click="goToDetail(product.id)">
查看详情
</div>
</div>
</div>
</template>
<!-- 搜索模式无结果 -->
<div v-else-if="isSearching && searchResults.length === 0" class="no-data">
未找到与"{{ searchValue }}"相关的产品
</div>
<!-- 正常模式只显示当前选中的供应商的产品 -->
<template v-else-if="!isSearching && cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0">
<template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu"> <template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu">
<!-- 循环每个分类下的产品 --> <div v-for="product in thrMenu.value" :key="product.id" class="box-item">
<div
v-for="product in thrMenu.value"
:key="product.id"
class="box-item"
v-show="shouldShowProduct(product)"
>
<!-- 标题 -->
<div class="item-tit"> <div class="item-tit">
{{ product.name }} {{ product.name }}
</div> </div>
<!-- 详情 -->
<div class="item-detail"> <div class="item-detail">
{{ product.description }} {{ product.description }}
</div> </div>
<!-- 描述 -->
<div class="item-desc"> <div class="item-desc">
算力网络 算力网络
</div> </div>
<!-- 立即咨询 -->
<div class="item-btn"> <div class="item-btn">
<!-- <div class="btn" @click="openConsultDialog(product, thrMenu)">
立即咨询
</div> -->
<div class="btn" @click="goToDetail(product.id)"> <div class="btn" @click="goToDetail(product.id)">
查看详情 查看详情
</div> </div>
@ -73,57 +85,91 @@
</div> </div>
</template> </template>
</template> </template>
<!-- 正常模式无数据 -->
<div v-else-if="!isSearching && (!cloudData.secMenu || cloudData.secMenu.length === 0)" class="no-data">
暂无产品数据
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { reqNavList } from '@/api/H5/index' import { reqNavList } from '@/api/H5/index'
export default {
export default {
data() { data() {
return { return {
cloudData: {}, cloudData: {},
activeSupplierIndex: 0, // activeSupplierIndex: 0,
searchValue: '', // searchValue: '',
isSearching: false, // isSearching: false,
searchResults: []
//
showConsultDialog: false,
platformName: '开元云',
qrCode: '',
consultFormData: {
content: '',
custom_type: '1',
name: '',
phone: '',
company: '',
email: '',
checked: false
},
currentProduct: null,
currentCategory: null
} }
}, },
created() { created() {
this.getCloudData() this.getCloudData()
}, },
methods: { methods: {
async getCloudData() { async getCloudData(keyword) {
const res = await reqNavList({ url_link: window.location.href }) try {
if (res.status == true) { const params = {
this.cloudData = res.data.product_service[2] url_link: window.location.href,
// ...(keyword && { keyword: keyword.trim() })
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
} }
const res = await reqNavList(params)
if (res.status == true) {
if (keyword) {
//
this.isSearching = true
this.searchResults = Array.isArray(res.data) ? res.data : []
} else {
//
this.isSearching = false
this.searchResults = []
this.cloudData = res.data.product_service[2] || {}
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
}
}
}
} catch (error) {
console.error('获取数据失败:', error)
this.isSearching = false
this.searchResults = []
} }
}, },
//
//
handleSearch() {
const keyword = this.searchValue.trim()
if (keyword) {
this.getCloudData(keyword)
} else {
//
this.clearSearch()
}
},
//
clearSearch() {
this.isSearching = false
this.searchValue = ''
this.searchResults = []
this.getCloudData() //
},
//
selectSupplier(index) {
if (!this.isSearching) {
this.activeSupplierIndex = index
}
},
//
goToDetail(productId) { goToDetail(productId) {
// 使productId
this.$router.push({ this.$router.push({
path: '/h5HomePage/netDetail', path: '/h5HomePage/netDetail',
query: { query: {
@ -131,40 +177,54 @@ export default {
} }
}) })
}, },
//
handleSearch() {
this.isSearching = !!this.searchValue.trim()
console.log('搜索关键词:', this.searchValue)
},
//
shouldShowProduct(product) {
if (!this.isSearching) {
return true
}
//
const keyword = this.searchValue.toLowerCase().trim()
return (
(product.name && product.name.toLowerCase().includes(keyword)) ||
(product.description && product.description.toLowerCase().includes(keyword))
)
},
//
selectSupplier(index) {
this.activeSupplierIndex = index
},
} }
} }
</script> </script>
<style> <style>
html, html, body {
body {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
} }
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
@import url('../less/all/index.less'); @import url('../less/all/index.less');
/* 搜索提示样式 */
.search-tip {
padding: 10px 20px;
background-color: #f5f7fa;
color: #666;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e4e7ed;
}
.clear-search {
color: #409EFF;
cursor: pointer;
font-size: 12px;
padding: 2px 8px;
border-radius: 3px;
transition: all 0.3s;
}
.clear-search:hover {
background-color: #ecf5ff;
color: #409EFF;
}
/* 无数据样式 */
.no-data {
text-align: center;
padding: 40px 20px;
color: #909399;
font-size: 14px;
background-color: #f5f7fa;
border-radius: 4px;
margin: 20px;
}
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@ -21,11 +21,9 @@
<!-- 内容 --> <!-- 内容 -->
<div class="content"> <div class="content">
<div class="item-box" v-for="(item, key) in baseData" :key="key"> <div class="item-box" v-for="(item, key) in baseData" :key="key">
<div class="item-title">{{ item.title }}</div> <div class="item-title">{{ item.title }}</div>
<div class="item-description">{{ item.description }}</div> <div class="item-description">{{ item.description }}</div>
<!-- 优势列表 -->
<div class="advantage-list" v-if="item.list && item.list.length"> <div class="advantage-list" v-if="item.list && item.list.length">
<div class="advantage-item" v-for="listItem in item.list" :key="listItem.id"> <div class="advantage-item" v-for="listItem in item.list" :key="listItem.id">
<div> <div>
@ -71,8 +69,12 @@
</div> </div>
<div class="item-price"> <div class="item-price">
<span class="price-icon"></span> <!-- 虚线 -->
<span class="price">{{ item.price }}</span> {{ item.price_unit }} <div class="item-price-line">
<span class="price-icon"></span>
<span class="price">{{ item.price }}</span> {{ item.price_unit }}
</div>
</div> </div>
<div class="item-button"> <div class="item-button">
<div class="item-button-text" @click="openConsultDialog(item, '智算未来征程')">立即咨询</div> <div class="item-button-text" @click="openConsultDialog(item, '智算未来征程')">立即咨询</div>
@ -89,7 +91,7 @@
</div> </div>
<!-- 内容 --> <!-- 内容 -->
<div class="content"> <div class="content">
<div class="item-box" v-for="(item, key) in latitude" :key="key"> <div class="item-box" v-for="(item, key) in latitudeData" :key="key">
<div class="item-title">{{ item.title }}</div> <div class="item-title">{{ item.title }}</div>
<div class="item-description">{{ item.description }}</div> <div class="item-description">{{ item.description }}</div>
@ -127,7 +129,7 @@
<!-- 滚动合作伙伴内容 --> <!-- 滚动合作伙伴内容 -->
<div class="partner-scroll"> <div class="partner-scroll">
<div class="logo-scroll-wrapper"> <div class="logo-scroll-wrapper">
<div class="logo-scroll-container"> <div class="logo-scroll-container" :style="{ animationDuration: 60 + 's' }">
<div v-for="(image, index) in duplicatedImages" :key="index" class="logo-item"> <div v-for="(image, index) in duplicatedImages" :key="index" class="logo-item">
<img :src="image" /> <img :src="image" />
</div> </div>
@ -160,20 +162,13 @@ export default {
data() { data() {
return { return {
// hot container
baseData: {}, baseData: {},
// hot
journeyData: {}, journeyData: {},
latitude: {}, // hot
images: [ latitudeData: {},
require('../images/top/img.png'),
require('../images/top/img_1.png'),
require('../images/top/img_2.png'),
require('../images/top/img_3.png'),
require('../images/top/img_4.png'),
require('../images/top/img_5.png'),
require('../images/top/img_6.png'),
require('../images/top/img_8.png'),
require('../images/top/img_9.png')
],
logoImg: require("@/assets/logo/colorLogo.png"), logoImg: require("@/assets/logo/colorLogo.png"),
logoText: "开元云(北京)科技有限公司", logoText: "开元云(北京)科技有限公司",
url: window.location.href, url: window.location.href,
@ -195,12 +190,26 @@ export default {
checked: false checked: false
}, },
currentItem: null, currentItem: null,
currentCategory: null currentCategory: null,
//
scrollDuration: 6
} }
}, },
computed: { computed: {
duplicatedImages() { duplicatedImages() {
return [...this.images, ...this.images] const images = [];
for (let i = 1; i <= 52; i++) {
try {
const imagePath = require(`./img/image${i}.png`);
images.push(imagePath);
} catch (error) {
continue;
}
}
//
return [...images, ...images, ...images];
} }
}, },
created() { created() {
@ -221,10 +230,20 @@ export default {
console.log('热门产品数据', res) console.log('热门产品数据', res)
if (res.status) { if (res.status) {
// 使 // base hot container
this.baseData = res.data.base || {} const base = res.data.base || {}
this.journeyData = res.data.suan || {} const { container, ...restBase } = base
this.latitude = res.data.net || {} this.baseData = restBase
// suan hot
const suan = res.data.suan || {}
const { hot: suanHot, ...restSuan } = suan
this.journeyData = restSuan
// net hot
const net = res.data.net || {}
const { hot: netHot, ...restNet } = net
this.latitudeData = restNet
} }
}, },
@ -271,8 +290,6 @@ export default {
} }
// 使 require // 使 require
try { try {
//
// @/views/homePage/mainPage/
return require(`@/views/homePage/mainPage/${iconPath}`) return require(`@/views/homePage/mainPage/${iconPath}`)
} catch (e) { } catch (e) {
console.warn('图标加载失败:', iconPath) console.warn('图标加载失败:', iconPath)
@ -326,13 +343,11 @@ export default {
} }
return await reqProductConsult(submitData) return await reqProductConsult(submitData)
}, },
// //
handleConsultSuccess(response) { handleConsultSuccess(response) {
console.log('咨询提交成功:', response) console.log('咨询提交成功:', response)
//
this.$message.success('咨询提交成功,我们将尽快联系您!') this.$message.success('咨询提交成功,我们将尽快联系您!')
}, },
@ -375,5 +390,3 @@ body {
<style lang="less" scoped> <style lang="less" scoped>
@import url('../less/official/index.less'); @import url('../less/official/index.less');
</style> </style>

View File

@ -15,8 +15,15 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 供应商 -->
<div v-if="cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container"> <!-- 搜索提示 -->
<div v-if="isSearching && searchValue" class="search-tip">
搜索关键词: "{{ searchValue }}"
<span class="clear-search" @click="clearSearch">× 清空搜索</span>
</div>
<!-- 供应商只在非搜索模式显示 -->
<div v-if="!isSearching && cloudData.secMenu && cloudData.secMenu.length > 0" class="supplier-container">
<div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)"> <div v-for="(value, index) in cloudData.secMenu" :key="index" class="supplier" @click="selectSupplier(index)">
<div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }"> <div class="supplier-title" :class="{ 'active': activeSupplierIndex === index }">
{{ value.secTitle }} {{ value.secTitle }}
@ -26,24 +33,53 @@
<!-- 云产品 --> <!-- 云产品 -->
<div class="box"> <div class="box">
<!-- 只显示当前选中的供应商的产品 --> <!-- 搜索模式显示搜索结果 -->
<template v-if="cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0"> <template v-if="isSearching && 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">
{{ product.description || '产品描述' }}
</div>
<!-- 描述 -->
<div class="item-desc">
AI应用
</div>
<!-- 查看详情 -->
<div class="item-btn">
<div class="btn" @click="goToDetail(product)">
查看详情
</div>
</div>
</div>
</template>
<!-- 搜索模式无结果 -->
<div v-else-if="isSearching && searchResults.length === 0" class="no-data">
未找到与"{{ searchValue }}"相关的产品
</div>
<!-- 正常模式显示当前供应商的产品 -->
<template v-else-if="cloudData.secMenu && cloudData.secMenu.length > 0 && activeSupplierIndex >= 0">
<template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu"> <template v-for="thrMenu in cloudData.secMenu[activeSupplierIndex].thrMenu">
<!-- 循环每个分类下的产品 --> <!-- 循环每个分类下的产品 -->
<div v-for="product in thrMenu.value" :key="product.id" class="box-item" v-show="shouldShowProduct(product)"> <div v-for="product in thrMenu.value" :key="product.id" class="box-item">
<!-- 标题 --> <!-- 标题 -->
<div class="item-tit"> <div class="item-tit">
{{ product.name }} {{ product.name }}
</div> </div>
<!-- 详情 --> <!-- 详情 -->
<div class="item-detail"> <div class="item-detail">
{{ thrMenu.thrTitle }} {{ thrMenu.thrTitle || '产品分类' }}
</div> </div>
<!-- 描述 --> <!-- 描述 -->
<div class="item-desc"> <div class="item-desc">
AI应用 AI应用
</div> </div>
<!-- 立即咨询 --> <!-- 查看详情 -->
<div class="item-btn"> <div class="item-btn">
<div class="btn" @click="goToDetail(product)"> <div class="btn" @click="goToDetail(product)">
查看详情 查看详情
@ -52,6 +88,11 @@
</div> </div>
</template> </template>
</template> </template>
<!-- 正常模式无数据 -->
<div v-else-if="!isSearching && (!cloudData.secMenu || cloudData.secMenu.length === 0)" class="no-data">
暂无产品数据
</div>
</div> </div>
</div> </div>
@ -67,48 +108,74 @@ export default {
activeSupplierIndex: 0, // activeSupplierIndex: 0, //
searchValue: '', // searchValue: '', //
isSearching: false, // isSearching: false, //
searchResults: [], //
} }
}, },
created() { created() {
this.getCloudData() this.getCloudData()
}, },
methods: { methods: {
async getCloudData() { async getCloudData(keyword) {
const res = await reqNavList({ url_link: window.location.href }) try {
if (res.status == true) { const params = {
this.cloudData = res.data.product_service[3] url_link: window.location.href,
// ...(keyword && { keyword: keyword.trim() })
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
} }
const res = await reqNavList(params)
if (res.status == true) {
if (keyword) {
//
this.isSearching = true
this.searchResults = Array.isArray(res.data) ? res.data : []
console.log('搜索结果:', this.searchResults)
} else {
//
this.isSearching = false
this.searchResults = []
this.cloudData = res.data.product_service[3] || {}
console.log('正常数据:', this.cloudData)
//
if (this.cloudData.secMenu && this.cloudData.secMenu.length > 0) {
this.activeSupplierIndex = 0
}
}
}
} catch (error) {
console.error('获取数据失败:', error)
this.isSearching = false
this.searchResults = []
} }
}, },
// //
handleSearch() { handleSearch() {
this.isSearching = !!this.searchValue.trim() const keyword = this.searchValue.trim()
console.log('搜索关键词:', this.searchValue) if (keyword) {
}, this.getCloudData(keyword)
} else {
// //
shouldShowProduct(product) { this.clearSearch()
if (!this.isSearching) {
return true
} }
//
const keyword = this.searchValue.toLowerCase().trim()
return (
(product.name && product.name.toLowerCase().includes(keyword)) ||
(this.currentCategory && this.currentCategory.thrTitle && this.currentCategory.thrTitle.toLowerCase().includes(keyword))
)
}, },
// //
clearSearch() {
this.isSearching = false
this.searchValue = ''
this.searchResults = []
this.getCloudData() //
},
//
selectSupplier(index) { selectSupplier(index) {
this.activeSupplierIndex = index if (!this.isSearching) {
this.activeSupplierIndex = index
}
}, },
// //
goToDetail(product) { goToDetail(product) {
if (product && product.name === '灵医智能体') { if (product && product.name === '灵医智能体') {
this.$router.push({ this.$router.push({
@ -131,6 +198,44 @@ body {
overflow-y: auto; overflow-y: auto;
} }
</style> </style>
<style lang="less" scoped> <style lang="less" scoped>
@import url('../less/all/index.less'); @import url('../less/all/index.less');
/* 搜索提示样式 */
.search-tip {
padding: 10px 20px;
background-color: #f5f7fa;
color: #666;
font-size: 14px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e4e7ed;
}
.clear-search {
color: #409EFF;
cursor: pointer;
font-size: 12px;
padding: 2px 8px;
border-radius: 3px;
transition: all 0.3s;
}
.clear-search:hover {
background-color: #ecf5ff;
color: #409EFF;
}
/* 无数据样式 */
.no-data {
text-align: center;
padding: 40px 20px;
color: #909399;
font-size: 14px;
background-color: #f5f7fa;
border-radius: 4px;
margin: 20px;
}
</style> </style>

View File

@ -1261,15 +1261,16 @@ export default Vue.extend({
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 30px; background-color: #1A1A1A;
height: 30px; width: 46px;
height: 46px;
border-radius: 50%; border-radius: 50%;
color: white; color: white;
margin-right: 8px; margin-right: 8px;
img { img {
width: 40px; width: 26px;
height: 40px; height: 26px;
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 948 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Some files were not shown because too many files have changed in this diff Show More