首页 home2: - 「碳数字身份证」卡办证指南改为「开始办证」,点击改为 iframe 跳碳证中心 - 注释掉「共性能力」section 及其在 sectionIds 里的位置 - 顶 hero 第三张卡标题由「绿色服务」改为「绿色低碳服务」 - 「核心底座」文案去掉"基础底座上海枢纽"措辞,简化为「国家区块链网络」 - 「申请服务」openService 改为登录态判断:未登录跳 /view/mhzc/login,已登录 iframe 进碳证中心 服务中心 fwsc: - 碳金融市场卡按钮「查看金融产品」→「走进绿金平台」,链接到 https://www.unionecredit.com/greenfinance/#/home - goToPage 增加外链识别(/^https?:\/\// → window.open _blank),同时把按钮 theme 改为 primary 统一三卡样式 数据列表 sjlbc: - 隐藏「浏览次数」统计块 行业专题 hyzt: - 三张卡按钮文案硬编码为「进入专题」,不再读 item.btnText / defaultBtnText,绕开部署包数据未刷新的问题 企业出海 qych: - 深链(?section=section0/1/2)时 v-if 隐藏 landing,配合 sectionIds 响应式 + watch.$route.query.section + activated 钩子 解决「先跳到首页三卡再滚到目标 section」的闪屏,直接落在目标 section - 航运燃料/低碳政策「国际航运碳足迹标识认证平台」立即访问改 showComingSoon() - 引入 comingSoonMixin 修复 this.showComingSoon 未定义导致点击无响应的老 bug - IMO/海事 一网通办卡改名为「国际海事组织(IMO)」,链接到 https://www.imo.org/en/ - #section2 国际航运碳足迹标识认证平台 h4 加 white-space: nowrap 避免标题换行 设置 settings: - 行业专题 hyztList 航运燃料 btnText 由「进入交易大厅」改为「进入专题」 页脚 footer: - 基础设施文案「国家区块链网络基础底座」→「国家区块链网络」 Co-Authored-By: Claude <noreply@anthropic.com>
627 lines
15 KiB
Vue
627 lines
15 KiB
Vue
<template>
|
|
<div class="sjlbc-page portal-page-shell portal-market-figma-page">
|
|
<div class="portal-figma-scale-viewport">
|
|
<div class="portal-figma-scale-stage" ref="figmaStage">
|
|
<!-- 面包屑导航 -->
|
|
<div class="breadcrumb-box">
|
|
<span class="breadcrumb-link" @click="$router.push('/view/mhzc/home')">首页</span>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span class="breadcrumb-link" @click="$router.push('/fwsc')">服务中心</span>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span class="breadcrumb-link" @click="$router.push('/tsjsc')">碳数据市场</span>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span class="breadcrumb-current">{{ sjscInfo && sjscInfo.sjmc || '数据列表' }}</span>
|
|
</div>
|
|
|
|
<!-- 数据市场信息卡片 -->
|
|
<div class="sjsc-info-card" v-if="sjscInfo">
|
|
<div class="sjsc-info-main">
|
|
<h2 class="sjsc-name">{{ sjscInfo.sjmc || '数据市场' }}</h2>
|
|
<p class="sjsc-desc">{{ sjscInfo.sjms || '暂无描述' }}</p>
|
|
</div>
|
|
<div class="sjsc-info-stats" v-if="sjscInfo.llcs">
|
|
<!-- <div class="stat-item" v-if="sjscInfo.llcs">
|
|
<span class="stat-value">{{ sjscInfo.llcs }}</span>
|
|
<span class="stat-label">浏览次数</span>
|
|
</div> -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 主内容区 -->
|
|
<div class="content-wrapper">
|
|
<!-- 右侧数据列表 -->
|
|
<div class="data-list">
|
|
<t-table
|
|
:data="sortedDataList"
|
|
:pagination="null"
|
|
row-key="uuid"
|
|
hover
|
|
:columns="tableColumns"
|
|
>
|
|
<template #td-type="{ row }">
|
|
<span class="type-tag" :class="row.type === '公共数据' ? 'tag-green' : 'tag-blue'">
|
|
{{ row.sjbt }}
|
|
</span>
|
|
</template>
|
|
<template #td-name="{ row }">
|
|
<span :title="row.name">{{ row.name }}</span>
|
|
</template>
|
|
<template #td-time="{ row }">
|
|
<span>{{ row.updateTime || row.publishTime }}</span>
|
|
</template>
|
|
<template #td-count="{ row }">
|
|
<span>{{ row.dataCount === '0' ? '/' : row.dataCount + '条' }}</span>
|
|
</template>
|
|
<template #td-desc="{ row }">
|
|
<span>{{ row.sjms || '-' }}</span>
|
|
</template>
|
|
<template #td-downloads="{ row }">
|
|
<t-button size="small" theme="primary" variant="outline" @click="showContactDialog(row)">获取联系方式</t-button>
|
|
</template>
|
|
</t-table>
|
|
<div v-if="pagination.total > 0" class="sjlbc-pagination">
|
|
<div class="sjlbc-pagination-total">共 {{ pagination.total }} 条数据</div>
|
|
<t-pagination
|
|
v-model="pagination.pageNo"
|
|
:total="pagination.total"
|
|
:page-size.sync="pagination.pageSize"
|
|
:total-content="false"
|
|
:show-jumper="!isMobile"
|
|
:show-page-size="!isMobile"
|
|
:page-size-options="[10, 20, 30, 50]"
|
|
align="center"
|
|
@change="handlePaginationChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 联系方式弹窗 -->
|
|
<t-dialog
|
|
:closeOnOverlayClick="false"
|
|
header="联系方式"
|
|
:footer="false"
|
|
:visible.sync="contactDialogVisible"
|
|
width="400px"
|
|
>
|
|
<div class="contact-dialog-content">
|
|
<div v-if="currentContact" class="contact-info">
|
|
<div class="contact-item">
|
|
<span class="contact-label">联系人:</span>
|
|
<span class="contact-value">{{ currentContact.lxr || '-' }}</span>
|
|
</div>
|
|
<div class="contact-item">
|
|
<span class="contact-label">联系电话:</span>
|
|
<span class="contact-value">{{ currentContact.lxdh || '-' }}</span>
|
|
</div>
|
|
<div class="contact-item">
|
|
<span class="contact-label">联系邮箱:</span>
|
|
<span class="contact-value">{{ currentContact.lxyx || '-' }}</span>
|
|
</div>
|
|
</div>
|
|
<div v-else class="contact-empty">暂无联系方式</div>
|
|
</div>
|
|
</t-dialog>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import NewNav from '@/pages/index/components/new-nav/index.vue';
|
|
import BreadcrumbNav from '@/pages/index/components/breadcrumb/index.vue';
|
|
import gxzxApi from '@/pages/index/api/gxzx/index.js';
|
|
import { isMobileViewport, watchDeviceClass } from '@/pages/index/utils/breakpoint';
|
|
import portalFigmaScaleMixin from '@/pages/index/utils/portal-figma-scale-mixin';
|
|
|
|
export default {
|
|
name: 'SjlbcPage',
|
|
mixins: [portalFigmaScaleMixin],
|
|
components: {
|
|
NewNav,
|
|
BreadcrumbNav,
|
|
},
|
|
data() {
|
|
return {
|
|
currentPageName: '数据列表',
|
|
sortField: '',
|
|
sortOrder: '',
|
|
dataList: [],
|
|
pagination: {
|
|
pageNo: 1,
|
|
pageSize: 10,
|
|
total: 0
|
|
},
|
|
sjscUuid: '',
|
|
sjscInfo: null,
|
|
// 联系方式弹窗
|
|
contactDialogVisible: false,
|
|
currentContact: null,
|
|
// 表格列配置
|
|
tableColumns: [
|
|
{
|
|
width: '120px',
|
|
colKey: 'td-type',
|
|
title: '数据类型',
|
|
},
|
|
{
|
|
colKey: 'td-name',
|
|
title: '名称',
|
|
},
|
|
{
|
|
colKey: 'td-desc',
|
|
title: '描述',
|
|
ellipsis: true,
|
|
tooltip: { theme: 'light', attachTo: () => document.querySelector('.td-desc-cell') },
|
|
},
|
|
{
|
|
width: '180px',
|
|
colKey: 'td-time',
|
|
title: '更新时间',
|
|
},
|
|
{
|
|
width: '120px',
|
|
colKey: 'td-count',
|
|
title: '数据条数',
|
|
},
|
|
{
|
|
width: '120px',
|
|
colKey: 'td-downloads',
|
|
title: '联系方式',
|
|
},
|
|
],
|
|
isMobile: false,
|
|
unwatchDevice: null,
|
|
};
|
|
},
|
|
mounted() {
|
|
this.isMobile = isMobileViewport();
|
|
this.unwatchDevice = watchDeviceClass(() => {
|
|
this.isMobile = isMobileViewport();
|
|
});
|
|
this.sjscUuid = this.$route.query.id || '';
|
|
this.loadSjscInfo();
|
|
this.loadData();
|
|
},
|
|
beforeDestroy() {
|
|
if (this.unwatchDevice) {
|
|
this.unwatchDevice();
|
|
this.unwatchDevice = null;
|
|
}
|
|
},
|
|
computed: {
|
|
totalPages() {
|
|
return Math.ceil(this.pagination.total / this.pagination.pageSize) || 1;
|
|
},
|
|
visiblePages() {
|
|
const total = this.totalPages;
|
|
const current = this.pagination.pageNo;
|
|
const pages = [];
|
|
for (let i = Math.max(1, current - 2); i <= Math.min(total, current + 2); i++) {
|
|
pages.push(i);
|
|
}
|
|
return pages;
|
|
},
|
|
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: {
|
|
loadSjscInfo() {
|
|
if (!this.sjscUuid) return;
|
|
gxzxApi.getSjsc({ uuid: this.sjscUuid }).then(res => {
|
|
if (res && res.data) {
|
|
this.sjscInfo = res.data;
|
|
}
|
|
});
|
|
},
|
|
loadData() {
|
|
const params = {
|
|
pageNo: this.pagination.pageNo,
|
|
pageSize: this.pagination.pageSize,
|
|
sjscUuid: this.sjscUuid,
|
|
};
|
|
gxzxApi.sjlbbList(params).then(res => {
|
|
if (res && res.data && res.data.records) {
|
|
this.dataList = res.data.records.map(item => ({
|
|
uuid: item.uuid,
|
|
name: item.sjmc,
|
|
type: item.sjlxDm,
|
|
sjbt: item.sjbt,
|
|
sjms: item.sjms,
|
|
email: item.emial,
|
|
publishTime: item.lrrq ? this.formatDate(item.lrrq) : '',
|
|
updateTime: item.xgrq ? this.formatDate(item.xgrq) : '',
|
|
dataCount: item.sjsl ? item.sjsl.toLocaleString() : '0',
|
|
views: item.llcs || 0,
|
|
downloads: item.xzcs || 0,
|
|
jg: item.jg,
|
|
jgDw: item.jgDw
|
|
}));
|
|
this.pagination.total = Number(res.data.total);
|
|
}
|
|
});
|
|
},
|
|
sortBy(field) {
|
|
if (this.sortField === field) {
|
|
this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
|
|
} else {
|
|
this.sortField = field;
|
|
this.sortOrder = 'desc';
|
|
}
|
|
},
|
|
formatDate(dateStr) {
|
|
if (!dateStr) return '';
|
|
const d = new Date(dateStr);
|
|
const year = d.getFullYear();
|
|
const month = String(d.getMonth() + 1).padStart(2, '0');
|
|
const day = String(d.getDate()).padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
},
|
|
showContactDialog(item) {
|
|
gxzxApi.getSjlbb({ uuid: item.uuid }).then(res => {
|
|
if (res && res.data) {
|
|
this.currentContact = {
|
|
lxr: res.data.lxr || '-',
|
|
lxdh: res.data.lxdh || '-',
|
|
lxyx: res.data.email || '-',
|
|
};
|
|
} else {
|
|
this.currentContact = null;
|
|
}
|
|
this.contactDialogVisible = true;
|
|
});
|
|
},
|
|
handlePaginationChange(pageInfo) {
|
|
this.pagination.pageNo = pageInfo.current;
|
|
this.pagination.pageSize = pageInfo.pageSize;
|
|
this.loadData();
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
@import '../../styles/home-figma-variables.less';
|
|
|
|
.sjlbc-page {
|
|
background: #f5f5f5;
|
|
.portal-figma-scale-page();
|
|
}
|
|
|
|
// 面包屑导航
|
|
.breadcrumb-box {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 83%;
|
|
max-width: 1400px;
|
|
padding: 20px 20px 0;
|
|
margin: 0 auto;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
// 数据市场信息卡片
|
|
.sjsc-info-card {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
width: 81%;
|
|
max-width: 1400px;
|
|
padding: 24px;
|
|
margin: 16px auto 0;
|
|
background: linear-gradient(135deg, #009a29 0%, #00c853 100%);
|
|
border-radius: 12px;
|
|
box-shadow: 0 4px 12px rgba(0, 154, 41, 0.15);
|
|
color: #fff;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.sjsc-info-main {
|
|
flex: 1;
|
|
}
|
|
|
|
.sjsc-name {
|
|
margin: 0 0 8px;
|
|
font-size: 22px;
|
|
font-weight: 600;
|
|
color: #fff;
|
|
}
|
|
|
|
.sjsc-desc {
|
|
margin: 0;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.sjsc-info-stats {
|
|
display: flex;
|
|
gap: 32px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.stat-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 24px;
|
|
font-weight: 700;
|
|
color: #fff;
|
|
}
|
|
|
|
.stat-label {
|
|
margin-top: 4px;
|
|
font-size: 12px;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.sjsc-info-card {
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
padding: 20px;
|
|
}
|
|
|
|
.sjsc-info-stats {
|
|
gap: 24px;
|
|
width: 100%;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 20px;
|
|
}
|
|
}
|
|
|
|
// 主内容区
|
|
.content-wrapper {
|
|
width: 100%;
|
|
max-width: 1400px;
|
|
padding: 20px;
|
|
margin: 0 auto;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
// 右侧数据列表
|
|
.data-list {
|
|
overflow: hidden;
|
|
background: #fff;
|
|
border-radius: 8px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
// 联系方式弹窗样式
|
|
.contact-dialog-content {
|
|
padding: 16px 0;
|
|
}
|
|
|
|
.contact-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
.contact-item {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.contact-label {
|
|
width: 80px;
|
|
color: #666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.contact-value {
|
|
color: #333;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
.contact-empty {
|
|
text-align: center;
|
|
color: #999;
|
|
padding: 20px 0;
|
|
}
|
|
|
|
// 数据类型标签
|
|
.type-tag {
|
|
padding: 4px 8px;
|
|
font-size: 12px;
|
|
border-radius: 4px;
|
|
|
|
&.tag-green {
|
|
color: #2e7d32;
|
|
background: #e8f5e9;
|
|
}
|
|
|
|
&.tag-blue {
|
|
color: #1565c0;
|
|
background: #e3f2fd;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.breadcrumb-box {
|
|
padding: 12px 12px 0;
|
|
}
|
|
|
|
.content-wrapper {
|
|
flex-direction: column;
|
|
padding: 12px;
|
|
gap: 12px;
|
|
}
|
|
|
|
.data-list {
|
|
overflow-x: auto;
|
|
}
|
|
}
|
|
|
|
// 分页(与 hydt / xqsc 移动端规范一致)
|
|
.sjlbc-pagination {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
padding: 20px 16px 24px;
|
|
border-top: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.sjlbc-pagination-total {
|
|
flex: 0 0 auto;
|
|
font-size: 14px;
|
|
line-height: 22px;
|
|
color: #666;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination {
|
|
flex: 1 1 auto;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.sjlbc-pagination {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
gap: 12px;
|
|
padding: 16px 12px 28px;
|
|
}
|
|
|
|
.sjlbc-pagination-total {
|
|
width: 100%;
|
|
text-align: center;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination {
|
|
display: flex !important;
|
|
flex-wrap: wrap !important;
|
|
align-items: center;
|
|
justify-content: center !important;
|
|
width: 100% !important;
|
|
max-width: 100%;
|
|
row-gap: 12px;
|
|
column-gap: 8px;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__total {
|
|
display: none;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__btn-prev {
|
|
order: 1;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__pager {
|
|
order: 2;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__btn-next {
|
|
order: 3;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__jump {
|
|
display: none !important;
|
|
}
|
|
|
|
@sjlbc-mob-pagination-h: 36px;
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__number {
|
|
min-width: @sjlbc-mob-pagination-h;
|
|
height: @sjlbc-mob-pagination-h;
|
|
line-height: @sjlbc-mob-pagination-h;
|
|
margin: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__btn {
|
|
min-width: @sjlbc-mob-pagination-h;
|
|
width: @sjlbc-mob-pagination-h;
|
|
height: @sjlbc-mob-pagination-h;
|
|
line-height: @sjlbc-mob-pagination-h;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.sjlbc-pagination {
|
|
padding-bottom: 32px;
|
|
}
|
|
|
|
@sjlbc-mob-pagination-h-sm: 32px;
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__number {
|
|
min-width: @sjlbc-mob-pagination-h-sm;
|
|
height: @sjlbc-mob-pagination-h-sm;
|
|
line-height: @sjlbc-mob-pagination-h-sm;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.sjlbc-pagination ::v-deep .t-pagination__btn {
|
|
min-width: @sjlbc-mob-pagination-h-sm;
|
|
width: @sjlbc-mob-pagination-h-sm;
|
|
height: @sjlbc-mob-pagination-h-sm;
|
|
line-height: @sjlbc-mob-pagination-h-sm;
|
|
}
|
|
}
|
|
</style>
|