592 lines
16 KiB
Vue
592 lines
16 KiB
Vue
<template>
|
||
<div class="conter">
|
||
<div class="banner-box">
|
||
<div class="conter">
|
||
<div class="Toptitle">
|
||
供需广场
|
||
</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="main-box">
|
||
<!-- <div style="margin-top: 25px;">
|
||
<span style="margin-top: 100px;" class="title">
|
||
<span class="leftText">
|
||
算力供需
|
||
</span>
|
||
<span class="rightText"> 广场</span></span>
|
||
</div> -->
|
||
|
||
<!-- 发布商品/需求弹窗 -->
|
||
<el-dialog :title="publish_type === '2' ? '发布需求' : '发布商品'" width="60vw" top="5vh"
|
||
:visible.sync="sendProductVisible">
|
||
<sendProduct :isEdit="false" v-if="publish_type" @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>
|
||
|
||
<!-- 筛选条件区域 - 整合到一个卡片中 -->
|
||
<div class="filter-card">
|
||
<!-- <div class="filter-header">
|
||
<span class="filter-title">筛选条件</span>
|
||
</div> -->
|
||
|
||
<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 class="filter-section">
|
||
<div class="filter-label">所属类别</div>
|
||
<div class="filter-options">
|
||
<span v-for="category in firstCategories" :key="category.id"
|
||
:class="['filter-option', { active: activeFirstId === category.id }]"
|
||
@click="selectFirstCategory(category.id)">
|
||
{{ category.product_category || category.label }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 所属品类 -->
|
||
<div class="filter-section" v-if="secondCategories.length > 0">
|
||
<div class="filter-label">所属品类</div>
|
||
<div class="filter-options">
|
||
<span v-for="category in secondCategories" :key="category.id"
|
||
:class="['filter-option', { active: activeSecondId === category.id }]"
|
||
@click="selectSecondCategory(category.id)">
|
||
{{ category.product_category || category.label }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 公司类别 -->
|
||
<!-- <div class="filter-section">
|
||
<div class="filter-label">公司类别</div>
|
||
<div class="filter-options">
|
||
<span v-for="company in companies" :key="company.id"
|
||
:class="['filter-option', { active: selectedCompanies.includes(company.value) }]"
|
||
@click="selectCompany(company.value)">
|
||
{{ company.label }}
|
||
</span>
|
||
</div>
|
||
</div> -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 产品列表 -->
|
||
<div class="product-card-container">
|
||
<div v-if="productList.length > 0">
|
||
<productCard type="supplyAndDemandSquare" :publish_type="publish_type" :productList="productList">
|
||
</productCard>
|
||
<el-pagination @current-change="handleCurrentChange" :page-size="page_size" layout="total, prev, pager, next"
|
||
:total="total" style="width: 100%; text-align: center;">
|
||
</el-pagination>
|
||
</div>
|
||
<div v-else class="no-data">
|
||
<img style="width: 150px;height: 150px;" src="./img/empty.svg" alt="">
|
||
暂无数据
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { reqGetSupplyAndDemandSquareList, reqCompanyCategorySearch, reqSupplyAndDemandFirstCategory, reqEnterpriseAuditInfoSearch } from '@/api/ncmatch'
|
||
import { mapGetters, mapState } from 'vuex'
|
||
|
||
export default {
|
||
name: 'supplyAndDemandSquare',
|
||
components: {
|
||
productCard: () => import('@/views/homePage/ncmatch/mainPage/productCard/index.vue'),
|
||
sendProduct: () => import('@/views/homePage/ncmatch/mainPage/sendProduct/index.vue')
|
||
},
|
||
data() {
|
||
return {
|
||
page_size: 8,
|
||
current_page: 1,
|
||
typeList: [],
|
||
publish_type: '1',
|
||
selectedCategory: '',
|
||
selectedCompanies: [],
|
||
categories: [],
|
||
companies: [],
|
||
productList: [],
|
||
total: 0,
|
||
firstCategories: [],
|
||
secondCategories: [],
|
||
activeFirstId: null,
|
||
activeSecondId: null,
|
||
showTip: false,
|
||
sendProductVisible: false,
|
||
}
|
||
},
|
||
created() {
|
||
this.initAllData()
|
||
},
|
||
computed: {
|
||
isNcmatchHome() {
|
||
return window.location.href.includes('ncmatchHome')
|
||
},
|
||
...mapGetters(["sidebar", "avatar", "device"]),
|
||
...mapState({
|
||
isShowPanel: (state) => state.product.showHomeNav,
|
||
navIndex: (state) => state.product.navIndex,
|
||
gridObj: state => state.operationAnalysis.gridObj,
|
||
mybalance: state => state.user.mybalance,
|
||
logoutUrl: state => state.login.logoutUrl,
|
||
loginStateVuex: state => state.login.loginState,
|
||
logoInfoNew: state => state.product.logoInfoNew,
|
||
}),
|
||
loginState() {
|
||
const userId = sessionStorage.getItem('userId');
|
||
return this.loginStateVuex || (userId !== null && userId !== 'null' && userId !== '');
|
||
},
|
||
},
|
||
methods: {
|
||
// 发布需求/商品方法
|
||
sendInfo(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.initData()
|
||
},
|
||
|
||
// 跳转到信息完善页面
|
||
goInfo() {
|
||
this.showTip = false
|
||
this.$router.push('/customer/approve')
|
||
},
|
||
|
||
handleCurrentChange(val) {
|
||
this.current_page = val
|
||
this.initData()
|
||
},
|
||
|
||
initAllData() {
|
||
this.init_product_category().then(() => {
|
||
this.init_company_category().then(() => {
|
||
this.initData()
|
||
})
|
||
})
|
||
},
|
||
|
||
init_company_category() {
|
||
return reqCompanyCategorySearch({ url_link: window.location.href }).then(res => {
|
||
if (res.status) {
|
||
this.company_category_list = []
|
||
for (let item of res.data) {
|
||
this.company_category_list.push({
|
||
label: item.company_category,
|
||
value: item.company_category
|
||
})
|
||
}
|
||
this.companies = this.company_category_list
|
||
}
|
||
return res
|
||
})
|
||
},
|
||
|
||
// 选中一级分类
|
||
selectFirstCategory(id) {
|
||
if (id === this.activeFirstId) return
|
||
this.activeFirstId = id
|
||
this.activeSecondId = null
|
||
this.selectedCategory = id
|
||
this.loadSecondCategories(id)
|
||
this.initData()
|
||
},
|
||
|
||
// 选中二级分类
|
||
selectSecondCategory(id) {
|
||
if (id === this.activeSecondId) return
|
||
this.activeSecondId = id
|
||
this.selectedCategory = id
|
||
this.initData()
|
||
},
|
||
|
||
init_product_category() {
|
||
return reqSupplyAndDemandFirstCategory({ to_page: 'show', url_link: window.location.href }).then(res => {
|
||
if (res.status) {
|
||
this.firstCategories = Array.isArray(res.data) ? res.data : []
|
||
if (this.firstCategories.length > 0) {
|
||
this.activeFirstId = this.firstCategories[0].id
|
||
this.selectedCategory = this.activeFirstId
|
||
this.activeSecondId = null
|
||
return this.loadSecondCategories(this.activeFirstId)
|
||
} else {
|
||
this.activeFirstId = null
|
||
this.activeSecondId = null
|
||
this.selectedCategory = ''
|
||
this.secondCategories = []
|
||
}
|
||
}
|
||
return res
|
||
})
|
||
},
|
||
|
||
loadSecondCategories(firstId) {
|
||
return reqSupplyAndDemandFirstCategory({ to_page: 'show', url_link: window.location.href, first_level_id: firstId }).then(res => {
|
||
if (res.status) {
|
||
this.secondCategories = Array.isArray(res.data) ? res.data : []
|
||
} else {
|
||
this.secondCategories = []
|
||
}
|
||
return res
|
||
})
|
||
},
|
||
|
||
handleTypeChange() {
|
||
console.log('切换到:', this.publish_type)
|
||
this.initData()
|
||
},
|
||
|
||
initData() {
|
||
let ploay = {
|
||
product_category: this.selectedCategory,
|
||
to_page: "square",
|
||
url_link: window.location.href,
|
||
page_size: this.page_size,
|
||
current_page: this.current_page,
|
||
company_type: this.selectedCompanies.length > 0 ? this.selectedCompanies.join(",") : "",
|
||
publish_type: this.publish_type
|
||
}
|
||
reqGetSupplyAndDemandSquareList(ploay).then(res => {
|
||
if (res.status) {
|
||
if (res.data.length === 0) {
|
||
this.productList = []
|
||
} else {
|
||
this.productList = res.data[0].product_list
|
||
}
|
||
this.total = res.data[0].total_count
|
||
}
|
||
})
|
||
},
|
||
|
||
selectCompany(companyId) {
|
||
const index = this.selectedCompanies.indexOf(companyId)
|
||
if (index > -1) {
|
||
this.selectedCompanies.splice(index, 1)
|
||
} else {
|
||
this.selectedCompanies.push(companyId)
|
||
}
|
||
this.initData()
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.conter{
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
.banner-box {
|
||
height: 600px!important;
|
||
background: url('./img/tt-banner.png') no-repeat ;
|
||
width: 100%;
|
||
// padding-bottom: 10px;
|
||
|
||
.conter {
|
||
width: 700px;
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
margin: 100px 280px 0px;
|
||
}
|
||
|
||
.Toptitle {
|
||
font-size: 30px;
|
||
font-weight: 600;
|
||
margin-bottom: 18px;
|
||
color: #000;
|
||
}
|
||
|
||
.banner-title {
|
||
width: 700px;
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
.title {
|
||
color: #666 !important;
|
||
font-size: 36px;
|
||
margin: 25px;
|
||
|
||
.leftText {
|
||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
display: inline-block;
|
||
}
|
||
}
|
||
|
||
.product-card-container {
|
||
margin-top: 30px;
|
||
width: 100%;
|
||
}
|
||
|
||
.main-box {
|
||
width: 90%;
|
||
// min-width: 1600px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
max-width: 1600px;
|
||
}
|
||
|
||
/* 筛选卡片样式 */
|
||
.filter-card {
|
||
width: 100%;
|
||
max-width: 1400px;
|
||
background: white;
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||
margin: 20px 0;
|
||
transition: all 0.3s ease;
|
||
overflow: hidden;
|
||
|
||
&: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;
|
||
align-items: center;
|
||
|
||
&::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 {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.filter-label {
|
||
font-size: 14px;
|
||
color: #333;
|
||
font-weight: 500;
|
||
white-space: nowrap;
|
||
flex-shrink: 0;
|
||
line-height: 32px;
|
||
width: 80px;
|
||
margin-right: 20px;
|
||
}
|
||
|
||
.filter-options {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
flex: 1;
|
||
}
|
||
|
||
.filter-option {
|
||
position: relative;
|
||
padding: 8px 20px;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
color: #666;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
background: white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 80px;
|
||
text-align: center;
|
||
|
||
&:hover {
|
||
border-color: #275AFF;
|
||
color: #275AFF;
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 2px 8px rgba(39, 90, 255, 0.2);
|
||
}
|
||
|
||
&.active {
|
||
background: linear-gradient(135deg, #275AFF, #2EBDFA);
|
||
color: white;
|
||
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;
|
||
}
|
||
}
|
||
|
||
.no-data {
|
||
min-height: 500px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 16px;
|
||
color: #7A82A0;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.el-pagination {
|
||
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>
|