feat: 创建数据列表页面(sjlbc)
- 添加数据列表页面,包含顶部导航、左侧筛选栏、右侧数据表格 - 实现价格区间和有效期筛选功能 - 实现表格排序功能(按数据类型、发布时间、数据条数、浏览量、下载量) - 添加数据类型标签(公共数据-绿色、社会性数据-蓝色) - 添加奇偶行颜色区分和分页组件 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
25f6982fd2
commit
b286a17ed4
628
txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue
Normal file
628
txw-mhzc-web/src/pages/index/views/fwsc/sjlbc.vue
Normal file
@ -0,0 +1,628 @@
|
||||
<template>
|
||||
<div class="sjlbc-page">
|
||||
<!-- 顶部导航 -->
|
||||
<NewNav />
|
||||
|
||||
<div class="main-content">
|
||||
<!-- 当前位置 -->
|
||||
<div class="current-position">
|
||||
<span>当前位置:</span>
|
||||
<span class="position-item" @click="goHome">首页</span>
|
||||
<span class="separator">/</span>
|
||||
<span class="position-item" @click="goService">服务中心</span>
|
||||
<span class="separator">/</span>
|
||||
<span class="position-item" @click="goDataMarket">碳数据市场</span>
|
||||
<span class="separator">/</span>
|
||||
<span class="position-current">数据列表</span>
|
||||
</div>
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧筛选栏 -->
|
||||
<div class="filter-sidebar">
|
||||
<div class="filter-box">
|
||||
<!-- 价格区间 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-title">价格区间</div>
|
||||
<div class="price-range">
|
||||
<input type="text" v-model="filterParams.priceMin" placeholder="最低" class="price-input" />
|
||||
<span class="price-separator">-</span>
|
||||
<input type="text" v-model="filterParams.priceMax" placeholder="最高" class="price-input" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 有效期 -->
|
||||
<div class="filter-section">
|
||||
<div class="filter-title">有效期</div>
|
||||
<div class="date-picker-box">
|
||||
<input type="date" v-model="filterParams.validDate" class="date-input" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选按钮 -->
|
||||
<div class="filter-buttons">
|
||||
<button class="btn-reset" @click="resetFilter">重置</button>
|
||||
<button class="btn-confirm" @click="confirmFilter">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧数据列表 -->
|
||||
<div class="data-list">
|
||||
<!-- 表头 -->
|
||||
<div class="table-header">
|
||||
<div class="th th-type" @click="sortBy('type')">
|
||||
数据类型
|
||||
<span class="sort-icon">
|
||||
<span class="sort-up" :class="{ active: sortField === 'type' && sortOrder === 'asc' }">▲</span>
|
||||
<span class="sort-down" :class="{ active: sortField === 'type' && sortOrder === 'desc' }">▲</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="th th-name">名称</div>
|
||||
<div class="th th-time" @click="sortBy('time')">
|
||||
发布时间/更新时间
|
||||
<span class="sort-icon">
|
||||
<span class="sort-up" :class="{ active: sortField === 'time' && sortOrder === 'asc' }">▲</span>
|
||||
<span class="sort-down" :class="{ active: sortField === 'time' && sortOrder === 'desc' }">▲</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="th th-count" @click="sortBy('count')">
|
||||
数据条数
|
||||
<span class="sort-icon">
|
||||
<span class="sort-up" :class="{ active: sortField === 'count' && sortOrder === 'asc' }">▲</span>
|
||||
<span class="sort-down" :class="{ active: sortField === 'count' && sortOrder === 'desc' }">▲</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="th th-views" @click="sortBy('views')">
|
||||
浏览量
|
||||
<span class="sort-icon">
|
||||
<span class="sort-up" :class="{ active: sortField === 'views' && sortOrder === 'asc' }">▲</span>
|
||||
<span class="sort-down" :class="{ active: sortField === 'views' && sortOrder === 'desc' }">▲</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="th th-downloads" @click="sortBy('downloads')">
|
||||
下载量
|
||||
<span class="sort-icon">
|
||||
<span class="sort-up" :class="{ active: sortField === 'downloads' && sortOrder === 'asc' }">▲</span>
|
||||
<span class="sort-down" :class="{ active: sortField === 'downloads' && sortOrder === 'desc' }">▲</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<div class="table-body">
|
||||
<div
|
||||
v-for="(item, index) in sortedDataList"
|
||||
:key="index"
|
||||
class="table-row"
|
||||
:class="{ 'row-even': index % 2 === 1 }"
|
||||
>
|
||||
<div class="td td-type">
|
||||
<span class="type-tag" :class="item.type === '公共数据' ? 'tag-green' : 'tag-blue'">
|
||||
{{ item.type }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="td td-name" :title="item.name">{{ item.name }}</div>
|
||||
<div class="td td-time">
|
||||
<div class="time-info">
|
||||
<span>发布时间:{{ item.publishTime }}</span>
|
||||
<span v-if="item.updateTime">更新时间:{{ item.updateTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="td td-count">{{ item.dataCount }}条</div>
|
||||
<div class="td td-views">{{ item.views }}次浏览</div>
|
||||
<div class="td td-downloads">{{ item.downloads }}次下载</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination">
|
||||
<span class="page-btn">上一页</span>
|
||||
<span class="page-btn active">1</span>
|
||||
<span class="page-btn">2</span>
|
||||
<span class="page-btn">3</span>
|
||||
<span class="page-btn">4</span>
|
||||
<span class="page-btn">5</span>
|
||||
<span class="page-btn">下一页</span>
|
||||
</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: 'SjlbcPage',
|
||||
components: {
|
||||
NewNav,
|
||||
Footer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filterParams: {
|
||||
priceMin: '',
|
||||
priceMax: '',
|
||||
validDate: '',
|
||||
},
|
||||
sortField: '',
|
||||
sortOrder: '',
|
||||
dataList: [
|
||||
{
|
||||
name: '全球多源高分辨温室气体及大气污染物排放清单',
|
||||
type: '社会性数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '2026-03-30 10:00',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '国家温室气体排放因子数据库',
|
||||
type: '公共数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '碳排放数据库',
|
||||
type: '公共数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '全球多源高分辨温室气体及大气污染物排放清单',
|
||||
type: '社会性数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '2026-03-30 10:00',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '国家温室气体排放因子数据库',
|
||||
type: '公共数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '碳排放数据库',
|
||||
type: '公共数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '全球多源高分辨温室气体及大气污染物排放清单',
|
||||
type: '社会性数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '2026-03-30 10:00',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
{
|
||||
name: '国家温室气体排放因子数据库',
|
||||
type: '公共数据',
|
||||
publishTime: '2026-03-30 10:00',
|
||||
updateTime: '',
|
||||
dataCount: '45,000',
|
||||
views: '475',
|
||||
downloads: '18',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
sortedDataList() {
|
||||
if (!this.sortField) {
|
||||
return this.dataList;
|
||||
}
|
||||
return [...this.dataList].sort((a, b) => {
|
||||
let valA = a[this.sortField];
|
||||
let valB = b[this.sortField];
|
||||
|
||||
// 如果是时间字段,转换为时间戳比较
|
||||
if (this.sortField === 'time') {
|
||||
valA = a.updateTime || a.publishTime;
|
||||
valB = b.updateTime || b.publishTime;
|
||||
}
|
||||
|
||||
// 移除逗号的数字字符串
|
||||
if (this.sortField === 'count' || this.sortField === 'views' || this.sortField === 'downloads') {
|
||||
valA = parseInt(valA.replace(/,/g, ''));
|
||||
valB = parseInt(valB.replace(/,/g, ''));
|
||||
}
|
||||
|
||||
if (valA < valB) {
|
||||
return this.sortOrder === 'asc' ? -1 : 1;
|
||||
}
|
||||
if (valA > valB) {
|
||||
return this.sortOrder === 'asc' ? 1 : -1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
sortBy(field) {
|
||||
if (this.sortField === field) {
|
||||
this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
|
||||
} else {
|
||||
this.sortField = field;
|
||||
this.sortOrder = 'desc';
|
||||
}
|
||||
},
|
||||
resetFilter() {
|
||||
this.filterParams = {
|
||||
priceMin: '',
|
||||
priceMax: '',
|
||||
validDate: '',
|
||||
};
|
||||
},
|
||||
confirmFilter() {
|
||||
console.log('筛选条件:', this.filterParams);
|
||||
},
|
||||
goHome() {
|
||||
window.location.href = '/view/mhzc/home';
|
||||
},
|
||||
goService() {
|
||||
window.location.href = '/view/mhzc/fwsc/fwsc';
|
||||
},
|
||||
goDataMarket() {
|
||||
window.location.href = '/view/mhzc/fwsc/sjsc';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sjlbc-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
width: 1920px;
|
||||
padding-top: 64px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
// 当前位置
|
||||
.current-position {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
padding: 0 60px;
|
||||
line-height: 48px;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
|
||||
.position-item {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #009a29;
|
||||
}
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin: 0 8px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.position-current {
|
||||
color: #009a29;
|
||||
}
|
||||
}
|
||||
|
||||
// 主内容区
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
padding: 20px 60px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
// 左侧筛选栏
|
||||
.filter-sidebar {
|
||||
width: 220px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.filter-box {
|
||||
position: sticky;
|
||||
top: 84px;
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.filter-title {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.price-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.price-input {
|
||||
flex: 1;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color: #009a29;
|
||||
}
|
||||
}
|
||||
|
||||
.price-separator {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.date-picker-box {
|
||||
.date-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color: #009a29;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-buttons {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.btn-reset,
|
||||
.btn-confirm {
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn-reset {
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-confirm {
|
||||
color: #fff;
|
||||
background: #009a29;
|
||||
|
||||
&:hover {
|
||||
background: #008f26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧数据列表
|
||||
.data-list {
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
// 表头
|
||||
.table-header {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
background: #f5f5f5;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.th {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
.th-type {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.th-name {
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.th-time {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.th-count {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.th-views {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.th-downloads {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.sort-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
font-size: 8px;
|
||||
color: #ccc;
|
||||
|
||||
.sort-up,
|
||||
.sort-down {
|
||||
&.active {
|
||||
color: #009a29;
|
||||
}
|
||||
}
|
||||
|
||||
.sort-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
// 表格数据
|
||||
.table-body {
|
||||
.table-row {
|
||||
display: flex;
|
||||
min-height: 72px;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
&:hover {
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
&.row-even {
|
||||
background: #fafafa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.td {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.td-type {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.td-name {
|
||||
flex: 1;
|
||||
justify-content: flex-start;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.td-time {
|
||||
width: 180px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.td-count {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.td-views {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.td-downloads {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
// 数据类型标签
|
||||
.type-tag {
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.tag-green {
|
||||
color: #2e7d32;
|
||||
background: #e8f5e9;
|
||||
}
|
||||
|
||||
&.tag-blue {
|
||||
color: #1565c0;
|
||||
background: #e3f2fd;
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 24px 0;
|
||||
gap: 8px;
|
||||
|
||||
.page-btn {
|
||||
height: 36px;
|
||||
min-width: 40px;
|
||||
padding: 0 12px;
|
||||
line-height: 36px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
color: #009a29;
|
||||
border-color: #009a29;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #fff;
|
||||
background: #009a29;
|
||||
border-color: #009a29;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user