feat: 共性能力平台全面优化6项

① 空状态/加载态替换为 EmptyState + SkeletonCard 组件
② 列表顶部增加统计摘要 (收录链接/覆盖分类/我的收藏)
③ 卡片去灰色实线边框,改用阴影,与列表页统一
④ 卡片 hover 上浮 -3px + 绿色阴影
⑤ '查看更多'按钮升级:箭头图标+hover圆角边框+绿色反馈
⑥ 收藏空态加引导按钮'浏览链接'

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
liulujian 2026-07-04 23:41:07 +08:00
parent dc1fcb5134
commit 5bd0c81020

View File

@ -155,8 +155,15 @@
<span class="gxnlpt-favorites-star" aria-hidden="true"></span>
<h2 class="gxnlpt-block-title">我的收藏</h2>
</header>
<div v-if="favoritesLoading" class="gxnlpt-state">加载中...</div>
<div v-else-if="!favoriteCards.length" class="gxnlpt-state">暂无收藏</div>
<SkeletonCard v-if="favoritesLoading" :count="3" />
<EmptyState
v-else-if="!favoriteCards.length"
type="empty"
text="暂无收藏"
hint="浏览共性能力链接,收藏感兴趣的内容"
action-text="浏览链接"
@action="contentView = 'list'"
/>
<div v-else class="gxnlpt-card-grid">
<article
v-for="card in favoriteCards"
@ -189,6 +196,10 @@
</section>
<template v-else>
<!-- 统计摘要 -->
<StatsSummary v-if="!pageLoading" :items="statsItems" />
<!-- 加载骨架 -->
<SkeletonCard v-if="pageLoading" :count="6" />
<section
v-for="{ item, index } in listSections"
:key="item.id"
@ -201,8 +212,12 @@
<h2 class="gxnlpt-block-title">{{ item.title }}</h2>
</header>
<div v-if="pageLoading && index === 0" class="gxnlpt-state">加载中...</div>
<div v-else-if="!pageLoading && !item.displayList.length" class="gxnlpt-state">暂无相关服务</div>
<div v-if="pageLoading && index === 0"></div>
<EmptyState
v-else-if="!pageLoading && !item.displayList.length"
type="empty"
text="暂无相关服务"
/>
<template v-else-if="item.displayList.length">
<div class="gxnlpt-card-grid">
<article
@ -235,7 +250,8 @@
class="gxnlpt-more-wrap"
>
<button type="button" class="gxnlpt-more" @click="toggleViewMore(item)">
{{ item.visibleCount >= item.cardList.length ? '收起' : '查看更多>>' }}
<span>{{ item.visibleCount >= item.cardList.length ? '收起' : '查看更多' }}</span>
<span class="gxnlpt-more-arrow" :class="{ 'is-reverse': item.visibleCount >= item.cardList.length }"></span>
</button>
</div>
</template>
@ -290,6 +306,9 @@
<script>
import GxnlptCardTags from '@/pages/index/views/gxnlpt/components/GxnlptCardTags.vue';
import EmptyState from '@/pages/index/components/EmptyState.vue';
import StatsSummary from '@/pages/index/components/StatsSummary.vue';
import SkeletonCard from '@/pages/index/components/SkeletonCard.vue';
// import api from '@/pages/index/api/gxnl/index.js'; // TODO
// 204
// .xlsx
@ -705,7 +724,7 @@ const SUBMIT_FORM_EMPTY = () => ({
export default {
name: 'GxnlptIndex',
mixins: [portalFigmaScaleMixin, comingSoonMixin],
components: { GxnlptCardTags },
components: { GxnlptCardTags, EmptyState, StatsSummary, SkeletonCard },
data() {
return {
starOutline,
@ -764,6 +783,16 @@ export default {
});
return list;
},
statsItems() {
const totalLinks = this.categoryList.reduce((s, c) => s + c.cardList.length, 0);
const totalCats = this.categoryList.filter((c) => c.cardList.length > 0).length;
const totalFavs = this.favoriteCards.length;
return [
{ label: '收录链接', value: totalLinks || 0 },
{ label: '覆盖分类', value: totalCats || '—' },
{ label: '我的收藏', value: totalFavs || 0 },
];
},
},
created() {
this.stackedNavLayout = readStackedNavLayout();
@ -2454,15 +2483,16 @@ html.portal-figma-scale-active .gxnlpt-page {
min-height: @gxnlpt-card-min-height;
padding: @gxnlpt-card-padding-y @gxnlpt-card-padding-x;
background: #fff;
border: 1px solid fade(#000, 10%);
border: none;
border-radius: @gxnlpt-card-radius;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
cursor: pointer;
transition: border-color 0.2s ease, box-shadow 0.2s ease, border-radius 0.2s ease;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-radius 0.2s ease;
&:hover {
border-color: @home-color-primary-green;
transform: translateY(-3px);
border-radius: @gxnlpt-card-radius-hover;
box-shadow: @home-shadow-card-green;
box-shadow: 0 8px 24px rgba(0, 154, 41, 0.12);
}
}
@ -2579,9 +2609,11 @@ html.portal-figma-scale-active .gxnlpt-page {
}
.gxnlpt-more {
display: inline-block;
display: inline-flex;
align-items: center;
gap: 4px;
margin: 0;
padding: 0;
padding: 4px 12px;
font-family: @home-font-family;
font-size: 14px;
font-weight: 400;
@ -2592,19 +2624,31 @@ html.portal-figma-scale-active .gxnlpt-page {
cursor: pointer;
appearance: none;
background: transparent;
border: none;
border: 1px solid transparent;
border-radius: 6px;
outline: none;
transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
&:hover {
opacity: 0.75;
color: @home-color-primary-green;
border-color: fade(@home-color-primary-green, 30%);
background: fade(@home-color-primary-green, 4%);
}
&:focus-visible {
box-shadow: 0 0 0 2px fade(@home-color-primary-dark, 25%);
border-radius: 2px;
border-radius: 6px;
}
}
.gxnlpt-more-arrow {
display: inline-block;
font-size: 18px;
line-height: 1;
transition: transform 0.2s ease;
&.is-reverse { transform: rotate(180deg); }
}
/* 收录表单 */
.gxnlpt-submit {
display: flex;