feat: 创建碳数据市场页面

- 实现左侧筛选栏(数据类型:全部、公共数据、因子库、社会性数据)
- 实现右侧数据库卡片列表(2列Grid布局)
- 数据类型标签颜色区分:公共数据/公益数据(绿色)、社会性数据(蓝色)、商业数据(灰色)
- 价格标签:免费(绿色)、付费(橙色)
- 使用NewNav和Footer组件

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
liulujian 2026-04-03 16:31:06 +08:00
parent 0de9cb3a3f
commit 25f6982fd2

View File

@ -0,0 +1,385 @@
<template>
<div class="sjsc-page">
<NewNav />
<div class="main-content">
<!-- 当前位置导航 -->
<div class="breadcrumb-box">
<span class="breadcrumb-text">当前位置</span>
<span class="breadcrumb-link" @click="goHome">首页</span>
<span class="breadcrumb-separator">/</span>
<span class="breadcrumb-link" @click="goService">服务中心</span>
<span class="breadcrumb-separator">/</span>
<span class="breadcrumb-current">碳数据市场</span>
</div>
<!-- 页面主体 -->
<div class="page-body">
<!-- 左侧筛选栏 -->
<div class="sidebar">
<div class="sidebar-title">数据类型</div>
<div class="filter-list">
<div
v-for="item in dataTypeList"
:key="item.value"
class="filter-item"
:class="{ active: selectedType === item.value }"
@click="handleTypeChange(item.value)"
>
{{ item.label }}
</div>
</div>
</div>
<!-- 右侧数据库卡片列表 -->
<div class="content-area">
<div class="card-grid">
<div
v-for="card in filteredCards"
:key="card.id"
class="database-card"
>
<div class="card-header">
<h3 class="card-title">{{ card.name }}</h3>
<div class="card-tags">
<span
v-for="tag in card.tags"
:key="tag"
class="tag"
:class="getTagClass(tag)"
>
{{ tag }}
</span>
</div>
</div>
<p class="card-desc">{{ card.description }}</p>
<div class="card-footer">
<span class="price-tag" :class="card.price === '免费' ? 'free' : 'paid'">
{{ card.price }}
</span>
<t-button theme="primary" size="small" variant="outline">
查看数据库
</t-button>
</div>
</div>
</div>
</div>
</div>
</div>
<Footer />
</div>
</template>
<script>
import NewNav from '@/pages/index/components/new-nav/index.vue';
import Footer from '@/pages/index/components/footer/index.vue';
export default {
name: 'SjscPage',
components: {
NewNav,
Footer
},
data() {
return {
selectedType: 'all',
dataTypeList: [
{ label: '全部', value: 'all' },
{ label: '公共数据', value: 'public' },
{ label: '因子库', value: 'factor' },
{ label: '社会性数据', value: 'social' }
],
cardList: [
{
id: 1,
name: '宝山绿色低碳数据创新实验室',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['公共数据', '社会性数据'],
price: '免费'
},
{
id: 2,
name: 'HiQLCD数据库',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['商业数据'],
price: '付费'
},
{
id: 3,
name: '天工数据库',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['公益数据'],
price: '免费'
},
{
id: 4,
name: 'ecoinvent数据库',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['商业数据'],
price: '付费'
},
{
id: 5,
name: 'ecoinvent数据库',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['商业数据'],
price: '付费'
},
{
id: 6,
name: '天工数据库',
description: '汇聚全国优质第三方服务机构,提供从核算到认证的全链条专业服务。',
tags: ['公益数据'],
price: '免费'
}
]
};
},
computed: {
filteredCards() {
if (this.selectedType === 'all') {
return this.cardList;
}
const typeMap = {
'public': '公共数据',
'factor': '因子库',
'social': '社会性数据'
};
const targetTag = typeMap[this.selectedType];
return this.cardList.filter(card => card.tags.includes(targetTag));
}
},
methods: {
goHome() {
this.$router.push('/view/mhzc/home');
},
goService() {
this.$router.push('/fwsc/fwsc');
},
handleTypeChange(value) {
this.selectedType = value;
},
getTagClass(tag) {
const classMap = {
'公共数据': 'tag-green',
'社会性数据': 'tag-blue',
'商业数据': 'tag-gray',
'公益数据': 'tag-green'
};
return classMap[tag] || 'tag-gray';
}
}
};
</script>
<style lang="less" scoped>
.sjsc-page {
min-height: 100vh;
background: #f5f5f5;
}
.main-content {
padding-top: 64px;
}
//
.breadcrumb-box {
display: flex;
align-items: center;
height: 48px;
padding: 0 200px;
background: #fff;
border-bottom: 1px solid #eee;
}
.breadcrumb-text {
font-size: 14px;
color: #666;
}
.breadcrumb-link {
font-size: 14px;
color: #009a29;
cursor: pointer;
transition: color 0.3s;
&:hover {
color: #007a1f;
}
}
.breadcrumb-separator {
margin: 0 8px;
font-size: 14px;
color: #999;
}
.breadcrumb-current {
font-size: 14px;
color: #333;
}
//
.page-body {
display: flex;
padding: 24px 200px;
gap: 24px;
}
//
.sidebar {
position: sticky;
top: 88px;
width: 220px;
height: fit-content;
min-width: 220px;
padding: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.sidebar-title {
padding-bottom: 12px;
margin-bottom: 16px;
font-size: 16px;
font-weight: 600;
color: #333;
border-bottom: 1px solid #eee;
}
.filter-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.filter-item {
padding: 10px 16px;
font-size: 14px;
color: #666;
cursor: pointer;
border-radius: 6px;
transition: all 0.3s;
&:hover {
color: #009a29;
background: #f0f9f0;
}
&.active {
color: #fff;
background: #009a29;
&:hover {
color: #fff;
background: #007a1f;
}
}
}
//
.content-area {
flex: 1;
min-width: 0;
}
//
.card-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.database-card {
display: flex;
flex-direction: column;
padding: 24px;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
transition: all 0.3s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 154, 41, 0.12);
}
}
.card-header {
margin-bottom: 12px;
}
.card-title {
margin-bottom: 12px;
font-size: 18px;
font-weight: 600;
line-height: 1.4;
color: #1a1a1a;
}
.card-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag {
display: inline-block;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
border-radius: 4px;
}
.tag-green {
color: #2e7d32;
background: #e8f5e9;
}
.tag-blue {
color: #1565c0;
background: #e3f2fd;
}
.tag-gray {
color: #666;
background: #f5f5f5;
}
.tag-orange {
color: #e65100;
background: #fff3e0;
}
.card-desc {
margin-bottom: 20px;
font-size: 14px;
line-height: 1.6;
color: #666;
flex: 1;
}
.card-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.price-tag {
padding: 4px 12px;
font-size: 14px;
font-weight: 600;
border-radius: 4px;
&.free {
color: #2e7d32;
background: #e8f5e9;
}
&.paid {
color: #e65100;
background: #fff3e0;
}
}
</style>