This commit is contained in:
hrx 2025-11-12 14:38:09 +08:00
parent 0acedc3543
commit 1a5e57a603
5 changed files with 449 additions and 454 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 KiB

View File

@ -1,97 +1,114 @@
<template> <template>
<div id="homeOut" class="homeOut"> <div id="homeOut" class="homeOut">
<TopBox id="topBox"></TopBox> <TopBox id="topBox"></TopBox>
<div class="banner-box">
<div class="conter">
<div class="title">
供需广场
</div>
<div class="banner-title">
开元算力供需对接平台精准攻克算力资源错配利用低效的行业痛点依托技术整合与生态共建双引擎
构建灵活适配高效协同的一站式算力服务体系支持供需信息发布与精准对接致力于成为链接算力资源赋能产业升级推动人工智能技术规模化落地的核心载体与关键桥梁
</div>
<div class="btn">
<div class="btn-box" @click="sendInfo('2')">发布需求</div>
<div class="btn-box" @click="sendInfo('1')">发布商品</div>
</div>
</div>
</div>
<div class="search-box"> <div class="search-box">
<search></search> <search></search>
</div> </div>
<div style="width: 90%;max-width: 1600px;"> <div style="width: 90%;max-width: 1600px;">
<router-view></router-view> <router-view></router-view>
</div> </div>
<el-dialog :title="productDetailInfo.publish_type==='1'? '商品详情' :'需求详情'" top="5vh" :visible.sync="showProductDetail" width="80%" @open="scrollToTop">
<!-- 发布商品/需求弹窗 -->
<el-dialog :title="publish_type === '2' ? '发布需求' : '发布商品'" width="60vw" top="5vh"
:visible.sync="sendProductVisible">
<sendProduct :isEdit="false" v-if="sendProductVisible" @success="sendProductSuccess" :publish_type="publish_type">
</sendProduct>
</el-dialog>
<!-- 审核提示弹窗 -->
<el-dialog title="温馨提示" :visible.sync="showTip" width="30%">
<span>您还没有完善企业信息完善企业信息审核通过后您可以发布需求与商品</span>
<span slot="footer" class="dialog-footer">
<span> <span style="margin-right: 10px;"> 跳转到</span> <el-button size="small" type="primary"
@click="goInfo">信息完善</el-button></span>
</span>
</el-dialog>
<el-dialog :title="productDetailInfo.publish_type === '1' ? '商品详情' : '需求详情'" top="5vh" :visible.sync="showProductDetail"
width="80%" @open="scrollToTop">
<ProductDetail></ProductDetail> <ProductDetail></ProductDetail>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<!-- <el-button @click="closeProductDetail"> </el-button> -->
<el-button type="primary" @click="closeProductDetail"> </el-button> <el-button type="primary" @click="closeProductDetail"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<!-- footer-->
<!-- Footer -->
<div class="footer"> <div class="footer">
<div class="left-box" style="border-bottom: 1px solid #7A82A0"> <div class="left-box" style="border-bottom: 1px solid #7A82A0">
<div style="display: flex;flex-direction: column"> <div style="display: flex;flex-direction: column">
<img v-if="JSON.stringify(logoInfoNew) !== '{}'" style="width: 148px;height: 48px;" <img v-if="JSON.stringify(logoInfoNew) !== '{}'" style="width: 148px;height: 48px;"
:src="logoInfoNew.home.logoImg" alt="" class="img"> :src="logoInfoNew.home.logoImg" alt="" class="img">
<div class="content-main"> <div class="content-main">
<ul class="info"> <ul class="info">
<li>地址<span v-if="JSON.stringify(logoInfoNew) !== '{}'">{{ logoInfoNew.home.adress }}</span> <li>地址<span v-if="JSON.stringify(logoInfoNew) !== '{}'">{{ logoInfoNew.home.adress }}</span></li>
</li>
<li v-if="JSON.stringify(logoInfoNew) !== '{}'"> 邮箱{{ logoInfoNew.home.email }}</li> <li v-if="JSON.stringify(logoInfoNew) !== '{}'"> 邮箱{{ logoInfoNew.home.email }}</li>
<li v-if="JSON.stringify(logoInfoNew) !== '{}'">电话: <span class="tel">{{ logoInfoNew.home.mobile }}</span> <li v-if="JSON.stringify(logoInfoNew) !== '{}'">电话: <span class="tel">{{ logoInfoNew.home.mobile }}</span></li>
</li>
<li>
<!-- <a href="" rel="noreferrer" target="_blank"></a> -->
</li>
</ul> </ul>
</div> </div>
</div> </div>
<ul class="bigUl"> <ul class="bigUl"></ul>
</ul>
<div v-if="JSON.stringify(logoInfoNew) !== '{}' && logoInfoNew.home.bannerTitle !== '开元数智'" class="right-box"> <div v-if="JSON.stringify(logoInfoNew) !== '{}' && logoInfoNew.home.bannerTitle !== '开元数智'" class="right-box">
<div class="qr-box"> <div class="qr-box">
<div class="qr-code">
<img src="../img/kefu.jpg" style="padding: 0.08rem" alt=""> <img src="../img/kefu.jpg" style="padding: 0.08rem" alt="">
</div>
<span class="qr-content">微信客服</span> <span class="qr-content">微信客服</span>
</div> </div>
<div class="qr-box" style="margin-left: 0.667rem"> <div class="qr-box" style="margin-left: 0.667rem">
<div class="qr-code">
<img src="../img/img.png" alt=""> <img src="../img/img.png" alt="">
</div>
<span class="qr-content">关注公众号</span> <span class="qr-content">关注公众号</span>
</div> </div>
</div> </div>
</div> </div>
<div style="display: flex;justify-content: center;align-items: center;width: 100%; "> <div style="display: flex;justify-content: center;align-items: center;width: 100%; ">
<span v-if="JSON.stringify(logoInfoNew) !== '{}'" <span v-if="JSON.stringify(logoInfoNew) !== '{}'"
style="margin:15px 0 ;width: 1400px;display:flex;justify-content:center;align-items:center;color: #7A82A0;"><span style="margin:15px 0 ;width: 1400px;display:flex;justify-content:center;align-items:center;color: #7A82A0;">
class="goStyle" @click="goOut('https://beian.miit.gov.cn/#/Integrated/index')"> <span class="goStyle" @click="goOut('https://beian.miit.gov.cn/#/Integrated/index')">
京ICP备{{ 京ICP备{{ logoInfoNew.home.license }}&nbsp;
logoInfoNew.home.license </span>
}}&nbsp; &nbsp;&nbsp;{{ logoInfoNew.home.footerTitle }}&nbsp;{{ logoInfoNew.home.copyright }}&nbsp;
</span> &nbsp;&nbsp;{{ </span>
logoInfoNew.home.footerTitle
}}&nbsp;{{
logoInfoNew.home.copyright
}}&nbsp; </span>
<!-- IPC备案号:{{ ICP }} <span style="margin-left: 0.267rem">版权所有 @kaiyuanyun 2023</span>-->
<!-- <img src="../../image/login/policeInsignia/policeInsignia.png" alt=""-->
<!-- style="width:0.227rem;height:0.227rem;margin-right: 0.027rem;">-->
<!-- <a href="https://beian.mps.gov.cn/#/query/webSearch?code=11010502054007" rel="noreferrer"-->
<!-- target="_blank"-->
<!-- style="margin-right:0.4rem;">京公网安备11010502054007</a>-->
<!-- <span>-->
<!-- <router-link tag="a" target="_blank"-->
<!-- :to="{ name: 'homePageImage' }">经营许可证:京B2-20232313</router-link>-->
<!-- </span>-->
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Vue from 'vue' import Vue from 'vue'
import TopBox from "@/views/homePage/components/topBox/index.vue"; import TopBox from "@/views/homePage/components/topBox/index.vue";
import { mapGetters, mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
import search from "./search/index.vue"; import search from "./search/index.vue";
import { reqEnterpriseAuditInfoSearch } from '@/api/ncmatch'
import productDetail from "./proDetail/index.vue"; import productDetail from "./proDetail/index.vue";
export default Vue.extend({ export default Vue.extend({
name: "indexLast", name: "indexLast",
components: { TopBox, search, ProductDetail: productDetail }, components: {
TopBox,
search,
ProductDetail: productDetail,
sendProduct: () => import('@/views/homePage/ncmatch/mainPage/sendProduct/index.vue')
},
data() { data() {
return { return {
currentBaseMenu: "hot", // currentBaseMenu: "hot",
//
sendProductVisible: false,
showTip: false,
publish_type: "",
} }
}, },
computed: { computed: {
@ -114,23 +131,12 @@ export default Vue.extend({
this.$store.commit('SHOWPRODUCTDETAIL', value); this.$store.commit('SHOWPRODUCTDETAIL', value);
} }
}, },
showRegisterButton() {
const orgType = window.sessionStorage.getItem('org_type');
const userId = window.sessionStorage.getItem('userId');
console.log("此时是:", orgType !== '2' && orgType !== '3' && userId !== null)
return orgType !== '2' && orgType !== '3' && userId === null;
},
username() {
return sessionStorage.getItem('username') || '';
},
}, },
methods: { methods: {
closeProductDetail() { closeProductDetail() {
this.$store.commit('SHOWPRODUCTDETAIL', false) this.$store.commit('SHOWPRODUCTDETAIL', false)
}, },
scrollToTop() { scrollToTop() {
// 使nextTickDOM
this.$nextTick(() => { this.$nextTick(() => {
const dialogBody = document.querySelector('.el-dialog__body'); const dialogBody = document.querySelector('.el-dialog__body');
if (dialogBody) { if (dialogBody) {
@ -145,13 +151,12 @@ export default Vue.extend({
const element = document.getElementById(id); const element = document.getElementById(id);
if (element) { if (element) {
element.scrollIntoView({ element.scrollIntoView({
behavior: 'smooth', // behavior: 'smooth',
block: 'start', // 'start', 'center', 'end', 'nearest' block: 'start',
}); });
} }
}, },
clickBaseMenu(menu) { clickBaseMenu(menu) {
console.log("emnu", menu)
this.currentBaseMenu = menu.id; this.currentBaseMenu = menu.id;
}, },
async goBaidu() { async goBaidu() {
@ -160,22 +165,122 @@ export default Vue.extend({
await this.$store.commit('setNavIndex', 0) await this.$store.commit('setNavIndex', 0)
}, },
async goAliyun() { async goAliyun() {
this.scrollToElement('topBox') this.scrollToElement('topBox')
await this.$store.commit('setShowHomeNav', true) await this.$store.commit('setShowHomeNav', true)
await this.$store.commit('setNavIndex', 1) await this.$store.commit('setNavIndex', 1)
}, },
// /
sendInfo(type) {
console.log("发布类型:", type);
if (this.loginState) {
reqEnterpriseAuditInfoSearch({
url_link: window.location.href,
}).then(res => {
const dataList = res && res.data && res.data.data
const hasAuditInfo = Array.isArray(dataList) && dataList.length !== 0
const roles = sessionStorage.getItem('jueseNew')
const isCustomer = roles ? roles.includes('客户') : true
if (hasAuditInfo && dataList[0]) {
const auditStatus = dataList[0].audit_status
if (auditStatus === 'pending') {
this.$message.warning('您的审核状态为待审核,请等待审核通过后发布~')
} else if (auditStatus === 'rejected') {
this.$message.warning('您的审核状态为驳回,请重新提交~')
} else {
//
this.publish_type = type
this.sendProductVisible = true
}
} else if (!isCustomer) {
//
this.publish_type = type
this.sendProductVisible = true
} else {
//
this.showTip = true
}
})
} else {
this.$router.push('/login')
}
},
//
sendProductSuccess() {
this.sendProductVisible = false;
this.$message.success(this.publish_type === '1' ? '商品发布成功' : '需求发布成功');
// 广
if (this.$route.path === '/supplyAndDemandSquare') {
// 广
this.$bus.$emit('refreshSupplyDemandList');
}
},
//
goInfo() {
this.showTip = false
this.$router.push('/customer/approve')
},
} }
}) })
</script> </script>
<style scoped lang="less">
/deep/.banner-box {
height: 700px!important;
background: url('./img/tt-banner.png') no-repeat ;
width: 100%;
padding-bottom: 200px;
.conter {
width: 700px;
position: relative;
display: flex;
flex-direction: column;
align-items: flex-start;
margin: 140px 240px 0px;
}
.title {
font-size: 30px;
font-weight: 600;
}
.banner-title {
width: 500px;
font-size: 16px;
color: #8890ab;
line-height: 2 !important;
}
.btn{
display: flex;
}
.btn-box{
padding: 10px 20px;
background: linear-gradient(90deg, rgb(39, 90, 255), rgb(46, 189, 250));
border-radius: 14px;
color: #fff;
margin-right: 20px;
margin-top: 20px;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(39, 90, 255, 0.3);
}
}
}
<style scoped lang="scss">
.search-box { .search-box {
width: 100%; width: 100%;
margin-top: 15px; // margin: 45px 0 25px 0;
margin: 45px 0; margin-bottom: 20px;
margin-bottom: 25px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -183,7 +288,6 @@ export default Vue.extend({
} }
.homeOut { .homeOut {
//padding-top: 60px;
height: 100%; height: 100%;
overflow: auto !important; overflow: auto !important;
min-width: 1500px; min-width: 1500px;
@ -192,12 +296,9 @@ export default Vue.extend({
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
background-color: #f6f8fd; background-color: #f6f8fd;
} }
.footer { .footer {
padding: 35px 0; padding: 35px 0;
width: 100%; width: 100%;
display: flex; display: flex;
@ -227,13 +328,11 @@ export default Vue.extend({
font-size: 0.187rem; font-size: 0.187rem;
} }
.qr-code { .qr-code {
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
width: 1.853rem; width: 1.853rem;
height: 1.853rem; height: 1.853rem;
} }
@ -253,19 +352,9 @@ export default Vue.extend({
align-items: center; align-items: center;
} }
.logo {
background-color: #32abfc;
img {
width: 100%;
height: 100%;
}
}
.bigUl { .bigUl {
margin: 0 15px; margin: 0 15px;
margin-left: -250px; margin-left: -250px;
//padding-top: 15px;
width: fit-content; width: fit-content;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
@ -273,7 +362,6 @@ export default Vue.extend({
.bigLi { .bigLi {
margin: 0 25px; margin: 0 25px;
} }
height: 100%; height: 100%;
.title { .title {
@ -283,7 +371,6 @@ export default Vue.extend({
} }
.smallUl { .smallUl {
font-size: 16px; font-size: 16px;
color: #7A82A0; color: #7A82A0;
@ -323,4 +410,7 @@ export default Vue.extend({
color: #1b5bff; color: #1b5bff;
} }
} }
/deep/.el-pagination{
text-align: center !important;
}
</style> </style>

View File

@ -1,25 +1,11 @@
<template> <template>
<div class="main-box"> <div class="main-box">
<div class="class">
<div class="class-box" @mouseenter="hoverClassBox = 1" @mouseleave="hoverClassBox = 0" :class="{ active: hoverClassBox === 1 }">
<div class="class-title" @click="sendInfo('2')">
发布需求
</div>
</div>
<div class="class-box" @mouseenter="hoverClassBox = 2" @mouseleave="hoverClassBox = 0" :class="{ active: hoverClassBox === 2 }">
<div class="class-title" @click="sendInfo('1')">
发布商品
</div>
</div>
</div>
<div style="margin-top: 25px;"> <div style="margin-top: 25px;">
<span style="margin-top: 100px;" class="title"> <span style="margin-top: 100px;" class="title">
<span class="leftText"> <span class="leftText">
算力供需 算力供需
</span> </span>
<span class="rightText"> 广场</span></span> <span class="rightText"> 广场</span></span>
</div> </div>
<!-- 发布商品/需求弹窗 --> <!-- 发布商品/需求弹窗 -->
@ -38,80 +24,88 @@
</span> </span>
</el-dialog> </el-dialog>
<!-- <div style="width: 100%;max-width: 1600px;"> --> <!-- 筛选条件区域 - 整合到一个卡片中 -->
<div class="category-filter"> <div class="filter-card">
<!-- 新增的需求和商品radio按钮组 --> <!-- <div class="filter-header">
<div class="radio-group-container"> <span class="filter-title">筛选条件</span>
<div class="radio-group"> </div> -->
<label class="radio-item" style="margin-right: 25px;" :class="{ active: publish_type === '1' }">
<input type="radio" v-model="publish_type" value="1" @change="handleTypeChange">
<span class="radio-text">企业商品</span>
</label>
<label class="radio-item" :class="{ active: publish_type === '2' }">
<input type="radio" v-model="publish_type" value="2" @change="handleTypeChange">
<span class="radio-text">企业需求</span>
</label>
<div class="filter-content">
<!-- 发布类型 -->
<div class="filter-section">
<div class="filter-label">发布类型</div>
<div class="filter-options">
<label class="filter-option" :class="{ active: publish_type === '1' }">
<input type="radio" v-model="publish_type" value="1" @change="handleTypeChange">
<span class="option-text">企业商品</span>
</label>
<label class="filter-option" :class="{ active: publish_type === '2' }">
<input type="radio" v-model="publish_type" value="2" @change="handleTypeChange">
<span class="option-text">企业需求</span>
</label>
</div> </div>
</div> </div>
<!-- 所属类别 --> <!-- 所属类别 -->
<div class="category-section"> <div class="filter-section">
<div class="category-title">所属类别</div> <div class="filter-label">所属类别</div>
<div class="category-tags"> <div class="filter-options">
<span v-for="category in firstCategories" :key="category.id" <span v-for="category in firstCategories" :key="category.id"
:class="['category-tag', { active: activeFirstId === category.id }]" :class="['filter-option', { active: activeFirstId === category.id }]"
@click="selectFirstCategory(category.id)"> @click="selectFirstCategory(category.id)">
{{ category.product_category || category.label }} {{ category.product_category || category.label }}
</span> </span>
</div> </div>
</div> </div>
<div class="category-section" v-if="secondCategories.length > 0"> <!-- 所属品类 -->
<div class="category-title">所属品类</div> <div class="filter-section" v-if="secondCategories.length > 0">
<div class="category-tags"> <div class="filter-label">所属品类</div>
<div class="filter-options">
<span v-for="category in secondCategories" :key="category.id" <span v-for="category in secondCategories" :key="category.id"
:class="['category-tag', { active: activeSecondId === category.id }]" :class="['filter-option', { active: activeSecondId === category.id }]"
@click="selectSecondCategory(category.id)"> @click="selectSecondCategory(category.id)">
{{ category.product_category || category.label }} {{ category.product_category || category.label }}
</span> </span>
</div> </div>
</div> </div>
<!-- 公司类别 --> <!-- 公司类别 -->
<div class="category-section"> <div class="filter-section">
<div class="category-title">公司类别</div> <div class="filter-label">公司类别</div>
<div class="category-tags"> <div class="filter-options">
<span v-for="company in companies" :key="company.id" <span v-for="company in companies" :key="company.id"
:class="['category-tag', { active: selectedCompanies.includes(company.value) }]" :class="['filter-option', { active: selectedCompanies.includes(company.value) }]"
@click="selectCompany(company.value)"> @click="selectCompany(company.value)">
{{ company.label }} {{ company.label }}
</span> </span>
</div> </div>
</div> </div>
<!-- 产品 --> </div>
</div>
<!-- 产品列表 -->
<div class="product-card-container"> <div class="product-card-container">
<div v-if="productList.length > 0"> <div v-if="productList.length > 0">
<productCard type="supplyAndDemandSquare" :publish_type="publish_type" <productCard type="supplyAndDemandSquare" :publish_type="publish_type"
:productList="productList"> :productList="productList">
</productCard> </productCard>
<el-pagination @current-change="handleCurrentChange" :page-size="page_size" <el-pagination @current-change="handleCurrentChange" :page-size="page_size"
layout="total, prev, pager, next" :total="total"> layout="total, prev, pager, next" :total="total" style="width: 100%; text-align: center;">
</el-pagination> </el-pagination>
</div> </div>
<div v-else class="no-data"> <div v-else class="no-data">
<img style="width: 150px;height: 10px;" src="./img/empty.svg" alt=""> <img style="width: 150px;height: 150px;" src="./img/empty.svg" alt="">
暂无数据 暂无数据
</div> </div>
</div> </div>
</div>
<!-- </div> -->
</div> </div>
</template> </template>
<script> <script>
import { reqGetSupplyAndDemandSquareList, reqCompanyCategorySearch, reqSupplyAndDemandFirstCategory, reqEnterpriseAuditInfoSearch } from '@/api/ncmatch' import { reqGetSupplyAndDemandSquareList, reqCompanyCategorySearch, reqSupplyAndDemandFirstCategory, reqEnterpriseAuditInfoSearch } from '@/api/ncmatch'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
export default { export default {
name: 'supplyAndDemandSquare', name: 'supplyAndDemandSquare',
components: { components: {
@ -120,26 +114,20 @@ export default {
}, },
data() { data() {
return { return {
// hover
hoverClassBox: 0, // 0: , 1: , 2:
page_size: 8, page_size: 8,
current_page: 1, current_page: 1,
typeList: [], typeList: [],
publish_type: '1', // publish_type: '1',
selectedCategory: '', // selectedCategory: '',
selectedCompanies: [], // selectedCompanies: [],
categories: [], categories: [],
companies: [], companies: [],
productList: [], productList: [],
detailVisible: false, total: 0,
oneLevelCategory:[],
twoLevelCategory:[],
//
firstCategories: [], firstCategories: [],
secondCategories: [], secondCategories: [],
activeFirstId: null, activeFirstId: null,
activeSecondId: null, activeSecondId: null,
//
showTip: false, showTip: false,
sendProductVisible: false, sendProductVisible: false,
} }
@ -178,7 +166,6 @@ export default {
const roles = sessionStorage.getItem('jueseNew') const roles = sessionStorage.getItem('jueseNew')
const isCustomer = roles ? roles.includes('客户') : true const isCustomer = roles ? roles.includes('客户') : true
// data[0]
if (hasAuditInfo && dataList[0]) { if (hasAuditInfo && dataList[0]) {
const auditStatus = dataList[0].audit_status const auditStatus = dataList[0].audit_status
@ -187,16 +174,13 @@ export default {
} else if (auditStatus === 'rejected') { } else if (auditStatus === 'rejected') {
this.$message.warning('您的审核状态为驳回,请重新提交~') this.$message.warning('您的审核状态为驳回,请重新提交~')
} else { } else {
//
this.publish_type = type this.publish_type = type
this.sendProductVisible = true this.sendProductVisible = true
} }
} else if (!isCustomer) { } else if (!isCustomer) {
//
this.publish_type = type this.publish_type = type
this.sendProductVisible = true this.sendProductVisible = true
} else { } else {
//
this.showTip = true this.showTip = true
} }
}) })
@ -207,8 +191,8 @@ export default {
// //
sendProductSuccess() { sendProductSuccess() {
this.sendProductVisible = false; // this.sendProductVisible = false;
this.initData() // this.initData()
}, },
// //
@ -217,32 +201,19 @@ export default {
this.$router.push('/customer/approve') this.$router.push('/customer/approve')
}, },
getOneLevelCategory(){
// reqSupplyAndDemandFirstCategory({url_link:window.location.href}).then(res=>{
// if(res.status){
// this.oneLevelCategory=res.data
// }
// })
},
getTwoLevelCategory(){
// reqSupplyAndDemandSecondCategory({url_link:window.location.href}).then(res=>{
// if(res.status){
// this.twoLevelCategory=res.data
// }
// })
},
handleCurrentChange(val) { handleCurrentChange(val) {
this.current_page = val this.current_page = val
this.initData() this.initData()
}, },
initAllData() { initAllData() {
//
this.init_product_category().then(() => { this.init_product_category().then(() => {
this.init_company_category().then(() => { this.init_company_category().then(() => {
this.initData() this.initData()
}) })
}) })
}, },
init_company_category() { init_company_category() {
return reqCompanyCategorySearch({ url_link: window.location.href }).then(res => { return reqCompanyCategorySearch({ url_link: window.location.href }).then(res => {
if (res.status) { if (res.status) {
@ -253,23 +224,22 @@ export default {
value: item.company_category value: item.company_category
}) })
} }
this.companies = this.company_category_list this.companies = this.company_category_list
} }
return res return res
}) })
}, },
// //
selectFirstCategory(id) { selectFirstCategory(id) {
if (id === this.activeFirstId) return if (id === this.activeFirstId) return
this.activeFirstId = id this.activeFirstId = id
//
this.activeSecondId = null this.activeSecondId = null
this.selectedCategory = id this.selectedCategory = id
//
this.loadSecondCategories(id) this.loadSecondCategories(id)
this.initData() this.initData()
}, },
// //
selectSecondCategory(id) { selectSecondCategory(id) {
if (id === this.activeSecondId) return if (id === this.activeSecondId) return
@ -277,8 +247,8 @@ export default {
this.selectedCategory = id this.selectedCategory = id
this.initData() this.initData()
}, },
init_product_category() { init_product_category() {
//
return reqSupplyAndDemandFirstCategory({to_page: 'show', url_link: window.location.href }).then(res => { return reqSupplyAndDemandFirstCategory({to_page: 'show', url_link: window.location.href }).then(res => {
if (res.status) { if (res.status) {
this.firstCategories = Array.isArray(res.data) ? res.data : [] this.firstCategories = Array.isArray(res.data) ? res.data : []
@ -286,7 +256,6 @@ export default {
this.activeFirstId = this.firstCategories[0].id this.activeFirstId = this.firstCategories[0].id
this.selectedCategory = this.activeFirstId this.selectedCategory = this.activeFirstId
this.activeSecondId = null this.activeSecondId = null
//
return this.loadSecondCategories(this.activeFirstId) return this.loadSecondCategories(this.activeFirstId)
} else { } else {
this.activeFirstId = null this.activeFirstId = null
@ -298,8 +267,8 @@ export default {
return res return res
}) })
}, },
loadSecondCategories(firstId) { loadSecondCategories(firstId) {
// first_level_id /
return reqSupplyAndDemandFirstCategory({ to_page: 'show',url_link: window.location.href, first_level_id: firstId }).then(res => { return reqSupplyAndDemandFirstCategory({ to_page: 'show',url_link: window.location.href, first_level_id: firstId }).then(res => {
if (res.status) { if (res.status) {
this.secondCategories = Array.isArray(res.data) ? res.data : [] this.secondCategories = Array.isArray(res.data) ? res.data : []
@ -309,12 +278,12 @@ export default {
return res return res
}) })
}, },
handleTypeChange() { handleTypeChange() {
//
console.log('切换到:', this.publish_type) console.log('切换到:', this.publish_type)
//
this.initData() this.initData()
}, },
initData() { initData() {
let ploay = { let ploay = {
product_category: this.selectedCategory, product_category: this.selectedCategory,
@ -335,197 +304,22 @@ export default {
this.total = res.data[0].total_count this.total = res.data[0].total_count
} }
}) })
}, },
selectCompany(companyId) { selectCompany(companyId) {
const index = this.selectedCompanies.indexOf(companyId) const index = this.selectedCompanies.indexOf(companyId)
if (index > -1) { if (index > -1) {
//
this.selectedCompanies.splice(index, 1) this.selectedCompanies.splice(index, 1)
} else { } else {
//
this.selectedCompanies.push(companyId) this.selectedCompanies.push(companyId)
} }
console.log("this.selectedCompanies", this.selectedCompanies);
this.initData() this.initData()
}, },
getProductList() {
this.productList = [
{
id: 1,
name: 'NVIDIA-4090',
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
price: 6000,
cpu: 'AMD EPYC 7542 32 C * 2',
memory: '64G DDR4-3200 * 8',
gpu: 'NVIDIA-4090-24GB * 8',
sys_disk: '960G SATA SSD * 2 (Raid)',
data_disk: '3.84T U.2 NVMe SSD * 1',
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
},
{
id: 2,
name: 'NVIDIA-A100',
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
price: 8000,
cpu: 'AMD EPYC 7542 32 C * 2',
memory: '128G DDR4-3200 * 8',
gpu: 'NVIDIA-A100-80GB * 8',
sys_disk: '1.92T SATA SSD * 2 (Raid)',
data_disk: '7.68T U.2 NVMe SSD * 1',
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
},
{
id: 3,
name: '昇腾910B',
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
price: 5000,
cpu: 'Kunpeng 920 64 C * 2',
memory: '64G DDR4-3200 * 8',
gpu: '昇腾910B-32GB * 8',
sys_disk: '960G SATA SSD * 2 (Raid)',
data_disk: '3.84T U.2 NVMe SSD * 1',
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
},
{
id: 4,
name: '昆仑芯P800',
image: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDIwMCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMTUwIiBmaWxsPSIjMjIyMjIyIi8+Cjx0ZXh0IHg9IjEwMCIgeT0iNzUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPk5WSUQpQSBSVFggNDA5MDwvdGV4dD4KPC9zdmc+Cg==',
price: 4000,
cpu: 'Kunpeng 920 64 C * 2',
memory: '64G DDR4-3200 * 8',
gpu: '昆仑芯P800-16GB * 8',
sys_disk: '960G SATA SSD * 2 (Raid)',
data_disk: '3.84T U.2 NVMe SSD * 1',
net_card: 'Mellanox Connect4 25G SFP28 2-port * 1'
}
]
}
},
mounted() {
// this.getProductList()
} }
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.class{
margin: 40px 0;
min-width: 1200px;
display: flex;
background-color: #fff;
padding:8px 10px;
.class-box{
width: 50%;
padding: 10px 20px;
// border-radius: 8px;
transition: all 0.3s ease;
cursor: pointer;
border: 1px solid transparent;
text-align: center;
/* 悬停时的渐变背景 */
&:hover,
&.active {
background: linear-gradient(to right, #2979fe, #2eb8fa);
border-color: #2979fe;
color: #fff;
box-shadow: 0 4px 12px rgba(41, 121, 254, 0.3);
.class-title {
color: #fff;
}
}
}
.class-title{
font-size: 16px;
color: #333;
transition: color 0.3s ease;
}
}
.back-btn {
width: 100%;
height: 40px;
line-height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 20px;
font-size: 16px;
color: #666;
&:hover {
cursor: pointer;
color: #275AFF;
}
}
/* 新增的radio按钮组样式 */
.radio-group-container {
width: 100% !important;
display: flex;
justify-content: flex-start;
// margin: 20px 0;
align-items: center;
max-width: 1400px;
}
.radio-group {
display: flex;
//background: #fff;
border-radius: 8px;
margin-bottom: 15px;
// box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.radio-item {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
background: #fff;
border: 1px solid #e8e8e8;
margin-right: 4px;
font-size: 16px !important;
&:last-child {
margin-right: 0;
}
input[type="radio"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
.radio-text {
font-size: 16px;
color: #275AFF;
font-weight: 500;
transition: all 0.3s ease;
}
&:hover {
border-color: #275AFF;
}
&.active {
background: linear-gradient(to right, #275AFF, #2EBDFA);
border-color: #275AFF;
box-shadow: 0 2px 8px rgba(39, 90, 255, 0.3);
.radio-text {
color: #fff;
}
}
}
.title { .title {
color: #666 !important; color: #666 !important;
font-size: 36px; font-size: 36px;
@ -533,52 +327,15 @@ export default {
.leftText { .leftText {
background: linear-gradient(to right, #275AFF, #2EBDFA); background: linear-gradient(to right, #275AFF, #2EBDFA);
/* 渐变方向颜色 */
-webkit-background-clip: text; -webkit-background-clip: text;
/* 关键属性:裁剪背景到文字 */
background-clip: text; background-clip: text;
color: transparent; color: transparent;
/* 文字颜色透明 */
display: inline-block; display: inline-block;
/* 确保渐变生效 */
} }
} }
.itemTitle {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
.topText {
color: #222F60;
font-size: 48px;
font-weight: bold;
}
.bottomText {
font-size: 24px;
color: #7A82A0;
margin-top: 15px;
}
}
.product-list {
width: 100%;
// display: grid;
// grid-template-columns: repeat(4, 1fr);
// gap: 20px;
.no-data {
text-align: center;
font-size: 16px;
}
}
/* 产品卡片容器样式 */
.product-card-container { .product-card-container {
margin-top: 20px; margin-top: 30px;
width: 100%; width: 100%;
} }
@ -591,66 +348,119 @@ export default {
max-width: 1600px; max-width: 1600px;
} }
.category-filter { /* 筛选卡片样式 */
// padding: 20px; .filter-card {
bottom: 1rem; width: 100%;
// background-color: #; max-width: 1400px;
border-radius: 8px; background: white;
margin: 20px; border-radius: 16px;
margin-left: 0; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
margin-right: 0; margin: 20px 0;
transition: all 0.3s ease;
overflow: hidden;
.category-section { &:hover {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
}
}
.filter-header {
padding: 20px 25px;
border-bottom: 1px solid #f0f0f0;
background: linear-gradient(135deg, #f8faff 0%, #f0f4ff 100%);
}
.filter-title {
font-size: 18px;
font-weight: 600;
color: #111e52;
display: flex; display: flex;
justify-content: flex-start;
align-items: center; align-items: center;
margin-bottom: 20px;
&::before {
content: '';
display: inline-block;
width: 4px;
height: 16px;
background: linear-gradient(135deg, #275AFF, #2EBDFA);
border-radius: 2px;
margin-right: 10px;
}
}
.filter-content {
padding: 25px;
}
.filter-section {
display: flex;
align-items: flex-start;
margin-bottom: 25px;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
}
.category-title { .filter-label {
font-size: 16px; font-size: 14px;
color: #333; color: #333;
// margin-bottom: 12px;
font-weight: 500; font-weight: 500;
display: flex; white-space: nowrap;
justify-content: flex-end; flex-shrink: 0;
align-items: center; line-height: 32px;
height: 100%; width: 80px;
margin-right: 15px; margin-right: 20px;
} }
.category-tags { .filter-options {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 12px;
flex: 1;
}
.filter-option {
.category-tag { position: relative;
padding: 8px 20px;
padding: 3px 6px; border: 1px solid #e0e0e0;
background-color: #fff; border-radius: 8px;
border: 1px solid #e8e8e8; font-size: 14px;
border-radius: 2px;
color: #666; color: #666;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
font-size: 14px; background: white;
display: flex;
align-items: center;
justify-content: center;
min-width: 80px;
text-align: center;
&:hover { &:hover {
border-color: #1890ff; border-color: #275AFF;
color: #1890ff; color: #275AFF;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(39, 90, 255, 0.2);
} }
&.active { &.active {
background-color: #e6f7ff; background: linear-gradient(135deg, #275AFF, #2EBDFA);
border-color: #1890ff; /* 激活状态下的边框颜色 */ color: white;
color: #1890ff; border-color: #275AFF;
} box-shadow: 0 2px 8px rgba(39, 90, 255, 0.3);
} }
/* 隐藏原生radio */
input[type="radio"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
} }
.option-text {
font-weight: 500;
pointer-events: none;
} }
} }
@ -662,11 +472,50 @@ export default {
font-size: 16px; font-size: 16px;
color: #7A82A0; color: #7A82A0;
flex-direction: column; flex-direction: column;
} }
.el-pagination{ .el-pagination {
text-align: center; text-align: center;
margin-top: 30px;
} }
/* 响应式调整 */
@media (max-width: 768px) {
.filter-card {
margin: 15px 10px;
}
.filter-content {
padding: 15px;
}
.filter-section {
flex-direction: column;
margin-bottom: 20px;
}
.filter-label {
width: 100%;
margin-bottom: 10px;
margin-right: 0;
}
.filter-options {
width: 100%;
gap: 8px;
}
.filter-option {
padding: 6px 12px;
font-size: 12px;
min-width: 60px;
}
}
@media (max-width: 1200px) {
.filter-card {
max-width: calc(100% - 40px);
margin: 20px;
}
}
</style> </style>

View File

@ -99,9 +99,9 @@
<el-input ref="vcode" v-model="loginForm.vcode" placeholder="请输入验证码" name="vcode" type="text" /> <el-input ref="vcode" v-model="loginForm.vcode" placeholder="请输入验证码" name="vcode" type="text" />
</div> </div>
</el-form-item> </el-form-item>
<!-- 获取验证码按钮 --> <!-- 获取验证码按钮 - 添加防抖功能 -->
<span :disabled="isDisabled" class="getCodeStyleNew" style="height:40px;margin-left:10px" <span :disabled="isDisabled || isGettingCode" class="getCodeStyleNew" style="height:40px;margin-left:10px"
@click="getCode"> @click="debouncedGetCode">
{{ SendCode_text }} {{ SendCode_text }}
</span> </span>
</div> </div>
@ -155,7 +155,7 @@
<el-input style="border:1px solid #d9d9d9;border-radius: 3px" ref="vcode" v-model="form.vcode" <el-input style="border:1px solid #d9d9d9;border-radius: 3px" ref="vcode" v-model="form.vcode"
placeholder="请输入验证码" name="vcode" type="text" /> placeholder="请输入验证码" name="vcode" type="text" />
<el-button type="primary" size="mini" style="height: 40px; margin-left: 10px" <el-button type="primary" size="mini" style="height: 40px; margin-left: 10px"
:disabled="isDisabled1" @click="getCode1"> :disabled="isDisabled1 || isGettingCode1" @click="debouncedGetCode1">
{{ SendCode_text1 }} {{ SendCode_text1 }}
</el-button> </el-button>
</div> </div>
@ -246,6 +246,12 @@ export default {
timer: null, // timer: null, //
timer1: null, // timer1: null, //
//
isGettingCode: false, //
isGettingCode1: false, //
debounceTimer: null, //
debounceTimer1: null, //
// //
dialogVisible: false, // dialogVisible: false, //
loading: false, // loading: false, //
@ -347,6 +353,50 @@ export default {
}, },
methods: { methods: {
//
debounce(func, wait) {
return function() {
const context = this;
const args = arguments;
clearTimeout(this.debounceTimer);
this.debounceTimer = setTimeout(() => {
func.apply(context, args);
}, wait);
};
},
//
debouncedGetCode: function() {
if (this.isDisabled || this.isGettingCode) return;
this.isGettingCode = true;
//
clearTimeout(this.debounceTimer);
// 300ms
this.debounceTimer = setTimeout(() => {
this.getCode();
this.isGettingCode = false;
}, 300);
},
//
debouncedGetCode1: function() {
if (this.isDisabled1 || this.isGettingCode1) return;
this.isGettingCode1 = true;
//
clearTimeout(this.debounceTimer1);
// 300ms
this.debounceTimer1 = setTimeout(() => {
this.getCode1();
this.isGettingCode1 = false;
}, 300);
},
// //
goBaidu(listUrl, url) { goBaidu(listUrl, url) {
this.$store.commit('setRedirectUrl', url) this.$store.commit('setRedirectUrl', url)
@ -695,6 +745,9 @@ export default {
}); });
} }
} }
}).catch(error => {
this.isGettingCode = false;
this.$message.error('验证码获取失败');
}); });
}, },
@ -743,6 +796,9 @@ export default {
type: "error", type: "error",
}); });
} }
}).catch(error => {
this.isGettingCode1 = false;
this.$message.error('验证码获取失败');
}); });
}, },