|
|
@@ -1,99 +1,132 @@
|
|
|
<template>
|
|
|
<view class="container">
|
|
|
- <!-- 品牌头部 -->
|
|
|
- <PageBanner :theme="bannerTheme"
|
|
|
- :tagline="bannerTagline"
|
|
|
- :quote="bannerQuote" />
|
|
|
+ <scroll-view scroll-y class="page-scroll" @scrolltolower="onLoadMore">
|
|
|
+ <!-- 品牌头部 -->
|
|
|
+ <PageBanner :theme="bannerTheme"
|
|
|
+ :tagline="bannerTagline"
|
|
|
+ :quote="bannerQuote" />
|
|
|
|
|
|
- <!-- 维度筛选 -->
|
|
|
- <view class="filter-section">
|
|
|
- <scroll-view scroll-x enable-flex show-scrollbar="false" class="dimension-scroll">
|
|
|
- <view class="filter-chips">
|
|
|
- <view
|
|
|
- v-for="dim in dimensionList"
|
|
|
- :key="dim.code"
|
|
|
- :class="['filter-chip', currentDimension === dim.code ? 'active' : '']"
|
|
|
- :style="currentDimension === dim.code ? { background: dim.color, color: '#fff' } : {}"
|
|
|
- @click="onDimensionChange(dim.code)"
|
|
|
- >
|
|
|
- {{ dim.label }}
|
|
|
- </view>
|
|
|
+ <!-- 推荐阅读 -->
|
|
|
+ <view class="featured-section" v-if="featuredArticles.length > 0">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">🔥 推荐阅读</text>
|
|
|
+ <text class="section-subtitle">精选成长好文</text>
|
|
|
</view>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 分类筛选 -->
|
|
|
- <view class="filter-section" v-if="categoryList.length > 1">
|
|
|
- <scroll-view scroll-x enable-flex show-scrollbar="false" class="category-scroll">
|
|
|
- <view class="filter-chips">
|
|
|
+ <view class="featured-grid">
|
|
|
<view
|
|
|
- v-for="cat in categoryList"
|
|
|
- :key="cat.value"
|
|
|
- :class="['filter-chip', currentCategory === cat.value ? 'active' : '']"
|
|
|
- @click="onCategoryChange(cat.value)"
|
|
|
+ v-for="article in featuredArticles"
|
|
|
+ :key="article.id"
|
|
|
+ class="featured-card"
|
|
|
+ @click="goDetail(article.id)"
|
|
|
>
|
|
|
- {{ cat.label }}
|
|
|
+ <view class="featured-category" :style="{ background: article.categoryColor }">
|
|
|
+ <text class="featured-category-text">{{ article.category }}</text>
|
|
|
+ </view>
|
|
|
+ <text class="featured-title">{{ article.title }}</text>
|
|
|
+ <text class="featured-summary">{{ article.summary }}</text>
|
|
|
+ <view class="featured-meta">
|
|
|
+ <text class="featured-views">👁 {{ article.views }}</text>
|
|
|
+ <text class="featured-date">{{ article.date }}</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
+ </view>
|
|
|
|
|
|
- <!-- 知识列表 -->
|
|
|
- <scroll-view scroll-y class="article-list" @scrolltolower="onLoadMore">
|
|
|
- <view v-if="loading && articles.length === 0" class="loading-wrap">
|
|
|
- <text class="loading-text">加载中...</text>
|
|
|
+ <!-- 维度筛选 -->
|
|
|
+ <view class="filter-section">
|
|
|
+ <scroll-view scroll-x enable-flex show-scrollbar="false" class="dimension-scroll">
|
|
|
+ <view class="filter-chips">
|
|
|
+ <view
|
|
|
+ v-for="dim in dimensionList"
|
|
|
+ :key="dim.code"
|
|
|
+ :class="['filter-chip', currentDimension === dim.code ? 'active' : '']"
|
|
|
+ :style="dim.activeStyle"
|
|
|
+ @click="onDimensionChange(dim.code)"
|
|
|
+ >
|
|
|
+ {{ dim.label }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
</view>
|
|
|
- <view v-else-if="articles.length === 0" class="empty-wrap">
|
|
|
- <text class="empty-icon">📚</text>
|
|
|
- <text class="empty-text">暂无相关知识</text>
|
|
|
+
|
|
|
+ <!-- 分类筛选 -->
|
|
|
+ <view class="filter-section" v-if="categoryList.length > 1">
|
|
|
+ <scroll-view scroll-x enable-flex show-scrollbar="false" class="category-scroll">
|
|
|
+ <view class="filter-chips">
|
|
|
+ <view
|
|
|
+ v-for="cat in categoryList"
|
|
|
+ :key="cat.value"
|
|
|
+ :class="['filter-chip', currentCategory === cat.value ? 'active' : '']"
|
|
|
+ @click="onCategoryChange(cat.value)"
|
|
|
+ >
|
|
|
+ {{ cat.label }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
</view>
|
|
|
- <view v-else class="article-grid">
|
|
|
- <view
|
|
|
- v-for="item in articles"
|
|
|
- :key="item.id"
|
|
|
- class="article-card"
|
|
|
- @click="goDetail(item.id)"
|
|
|
- >
|
|
|
- <image
|
|
|
- class="article-cover"
|
|
|
- :src="item.coverImage || '/static/default-article.png'"
|
|
|
- mode="aspectFill"
|
|
|
- />
|
|
|
- <view class="article-body">
|
|
|
- <view class="article-meta">
|
|
|
- <text class="article-category">{{ item.categoryName || '知识' }}</text>
|
|
|
- <view class="article-type-tags">
|
|
|
- <text v-if="item.contentType" class="type-tag" :class="'type-' + item.contentType">{{ contentTypeLabel(item.contentType) }}</text>
|
|
|
- <text v-if="item.difficultyLevel > 0" class="difficulty-tag">{{ '★'.repeat(item.difficultyLevel) }}</text>
|
|
|
+
|
|
|
+ <!-- 全部文章 -->
|
|
|
+ <view class="all-articles-section">
|
|
|
+ <view class="section-header">
|
|
|
+ <text class="section-title">全部文章</text>
|
|
|
+ <text class="section-subtitle" v-if="total > 0">共 {{ total }} 篇</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view v-if="loading && articles.length === 0" class="loading-wrap">
|
|
|
+ <text class="loading-text">加载中...</text>
|
|
|
+ </view>
|
|
|
+ <view v-else-if="articles.length === 0" class="empty-wrap">
|
|
|
+ <text class="empty-icon">📚</text>
|
|
|
+ <text class="empty-text">暂无相关知识</text>
|
|
|
+ </view>
|
|
|
+ <view v-else class="article-grid">
|
|
|
+ <view
|
|
|
+ v-for="item in articles"
|
|
|
+ :key="item.id"
|
|
|
+ class="article-card"
|
|
|
+ @click="goDetail(item.id)"
|
|
|
+ >
|
|
|
+ <image
|
|
|
+ class="article-cover"
|
|
|
+ :src="item.coverImage || '/static/default-article.png'"
|
|
|
+ mode="aspectFill"
|
|
|
+ />
|
|
|
+ <view class="article-body">
|
|
|
+ <view class="article-meta">
|
|
|
+ <text class="article-category">{{ item.categoryName || '知识' }}</text>
|
|
|
+ <view class="article-type-tags">
|
|
|
+ <text v-if="item.contentType" class="type-tag" :class="'type-' + item.contentType">{{ contentTypeLabel(item.contentType) }}</text>
|
|
|
+ <text v-if="item.difficultyLevel > 0" class="difficulty-tag">{{ '★'.repeat(item.difficultyLevel) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <text class="article-title">{{ item.title }}</text>
|
|
|
+ <text class="article-summary">{{ item.summary || item.content }}</text>
|
|
|
+ <view class="article-footer">
|
|
|
+ <text class="article-author">{{ item.author || '浠艾福' }}</text>
|
|
|
+ <text class="article-read-count">阅读 {{ item.readCount || 0 }}</text>
|
|
|
</view>
|
|
|
- </view>
|
|
|
- <text class="article-title">{{ item.title }}</text>
|
|
|
- <text class="article-summary">{{ item.summary || item.content }}</text>
|
|
|
- <view class="article-footer">
|
|
|
- <text class="article-author">{{ item.author || '浠艾福' }}</text>
|
|
|
- <text class="article-read-count">阅读 {{ item.readCount || 0 }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view v-if="loadingMore" class="loading-more">
|
|
|
+ <text class="loading-text">加载中...</text>
|
|
|
+ </view>
|
|
|
+ <view v-if="noMore && articles.length > 0" class="no-more">
|
|
|
+ <text class="no-more-text">— 没有更多了 —</text>
|
|
|
+ </view>
|
|
|
+ <view v-if="!isLoggedIn" class="login-hint-bar">
|
|
|
+ <text class="login-hint-text">🔒 登录后解锁全部内容</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <view v-if="loadingMore" class="loading-more">
|
|
|
- <text class="loading-text">加载中...</text>
|
|
|
- </view>
|
|
|
- <view v-if="noMore && articles.length > 0" class="no-more">
|
|
|
- <text class="no-more-text">— 没有更多了 —</text>
|
|
|
- </view>
|
|
|
- <view v-if="!isLoggedIn" class="login-hint-bar">
|
|
|
- <text class="login-hint-text">🔒 登录后解锁全部内容</text>
|
|
|
- </view>
|
|
|
+
|
|
|
<view class="bottom-spacer"></view>
|
|
|
</scroll-view>
|
|
|
-
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
|
-import { getArticleCategories, getArticleList } from '../../utils/api.js'
|
|
|
+import { getArticleCategories, getArticleList, getFeaturedArticles } from '../../utils/api.js'
|
|
|
|
|
|
var dimensionConfig = {
|
|
|
all: { label: '全部', color: '#64748B', theme: 'mind-wisdom', tagline: '探索知识,滋养成长', quote: '学而时习之,不亦说乎' },
|
|
|
@@ -108,14 +141,12 @@ export default {
|
|
|
components: { PageBanner },
|
|
|
data() {
|
|
|
return {
|
|
|
- dimensionList: Object.keys(dimensionConfig).map(function(k) {
|
|
|
- return { code: k, label: dimensionConfig[k].label, color: dimensionConfig[k].color }
|
|
|
- }),
|
|
|
currentDimension: 'all',
|
|
|
categoryList: [{ id: '', name: '全部' }],
|
|
|
categoryMap: {},
|
|
|
currentCategory: '',
|
|
|
articles: [],
|
|
|
+ featuredArticles: [],
|
|
|
page: 1,
|
|
|
size: 10,
|
|
|
total: 0,
|
|
|
@@ -126,6 +157,17 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
+ dimensionList: function() {
|
|
|
+ var self = this
|
|
|
+ return Object.keys(dimensionConfig).map(function(k) {
|
|
|
+ var cfg = dimensionConfig[k]
|
|
|
+ var activeStyle = ''
|
|
|
+ if (k === self.currentDimension) {
|
|
|
+ activeStyle = 'background:' + cfg.color + ';color:#fff;'
|
|
|
+ }
|
|
|
+ return { code: k, label: cfg.label, color: cfg.color, activeStyle: activeStyle }
|
|
|
+ })
|
|
|
+ },
|
|
|
bannerTheme: function() {
|
|
|
return dimensionConfig[this.currentDimension] ? dimensionConfig[this.currentDimension].theme : 'mind-wisdom'
|
|
|
},
|
|
|
@@ -138,6 +180,7 @@ export default {
|
|
|
},
|
|
|
onLoad: function(options) {
|
|
|
this.isLoggedIn = !!uni.getStorageSync('token')
|
|
|
+ this.loadFeaturedArticles()
|
|
|
if (options && options.dimension && dimensionConfig[options.dimension]) {
|
|
|
this.currentDimension = options.dimension
|
|
|
}
|
|
|
@@ -147,6 +190,32 @@ export default {
|
|
|
this.isLoggedIn = !!uni.getStorageSync('token')
|
|
|
},
|
|
|
methods: {
|
|
|
+ loadFeaturedArticles: function() {
|
|
|
+ var self = this
|
|
|
+ getFeaturedArticles({ size: 5 }).then(function(res) {
|
|
|
+ if (res.code === 200 && res.data) {
|
|
|
+ var gradientColors = [
|
|
|
+ 'linear-gradient(135deg, #6366F1, #818CF8)',
|
|
|
+ 'linear-gradient(135deg, #8B5CF6, #A78BFA)',
|
|
|
+ 'linear-gradient(135deg, #5B9BD5, #8FC5E8)',
|
|
|
+ 'linear-gradient(135deg, #10B981, #34D399)',
|
|
|
+ 'linear-gradient(135deg, #F97316, #FB923C)'
|
|
|
+ ]
|
|
|
+ var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
|
|
|
+ self.featuredArticles = list.map(function(item, index) {
|
|
|
+ return {
|
|
|
+ id: item.id,
|
|
|
+ category: item.categoryName || '成长文章',
|
|
|
+ categoryColor: gradientColors[index % gradientColors.length],
|
|
|
+ title: item.title || '',
|
|
|
+ summary: item.summary || '',
|
|
|
+ views: item.viewCount ? String(item.viewCount) : '0',
|
|
|
+ date: item.publishedAt ? item.publishedAt.slice(0, 10) : ''
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }).catch(function() {})
|
|
|
+ },
|
|
|
contentTypeLabel: function(type) {
|
|
|
var labels = { article: '文章', knowledge: '知识点', course: '课程', tip: '贴士' }
|
|
|
return labels[type] || type
|
|
|
@@ -239,7 +308,7 @@ export default {
|
|
|
},
|
|
|
goDetail(id) {
|
|
|
if (this.isLoggedIn) {
|
|
|
- uni.navigateTo({ url: '/pages/mind/article-detail?id=' + id })
|
|
|
+ uni.navigateTo({ url: '/pages/mind-detail/article-detail?id=' + id })
|
|
|
} else {
|
|
|
uni.navigateTo({ url: '/pages/login/login?redirect=' + encodeURIComponent('/pages/mind/articles') })
|
|
|
}
|
|
|
@@ -252,10 +321,106 @@ export default {
|
|
|
.container {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- min-height: 100vh;
|
|
|
+ height: 100vh;
|
|
|
background: #f5f7fa;
|
|
|
}
|
|
|
|
|
|
+/* 页面滚动容器 */
|
|
|
+.page-scroll {
|
|
|
+ flex: 1;
|
|
|
+ height: 100vh;
|
|
|
+}
|
|
|
+
|
|
|
+/* 区块通用标题 */
|
|
|
+.section-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: baseline;
|
|
|
+ padding: 0 4rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+.section-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+.section-subtitle {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-left: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+/* ===== 推荐阅读 ===== */
|
|
|
+.featured-section {
|
|
|
+ margin: 24rpx 24rpx 16rpx;
|
|
|
+ padding: 0 4rpx;
|
|
|
+}
|
|
|
+.featured-grid {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+.featured-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 28rpx 24rpx;
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+.featured-card:active {
|
|
|
+ opacity: 0.8;
|
|
|
+}
|
|
|
+.featured-category {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4rpx 18rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ margin-bottom: 14rpx;
|
|
|
+}
|
|
|
+.featured-category-text {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+.featured-title {
|
|
|
+ font-size: 28rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+.featured-summary {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #888;
|
|
|
+ line-height: 1.5;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+}
|
|
|
+.featured-meta {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.featured-views {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #bbb;
|
|
|
+ margin-right: 20rpx;
|
|
|
+}
|
|
|
+.featured-date {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #bbb;
|
|
|
+ margin-left: auto;
|
|
|
+}
|
|
|
+
|
|
|
+/* ===== 全部文章 ===== */
|
|
|
+.all-articles-section {
|
|
|
+ margin: 8rpx 24rpx 0;
|
|
|
+ padding: 0 4rpx;
|
|
|
+}
|
|
|
+
|
|
|
/* 筛选条 */
|
|
|
.filter-section {
|
|
|
background: #fff;
|
|
|
@@ -333,11 +498,6 @@ export default {
|
|
|
color: #f59e0b;
|
|
|
}
|
|
|
|
|
|
-/* 文章列表 */
|
|
|
-.article-list {
|
|
|
- flex: 1;
|
|
|
- height: calc(100vh - 220rpx);
|
|
|
-}
|
|
|
.loading-wrap,
|
|
|
.empty-wrap {
|
|
|
display: flex;
|
|
|
@@ -375,11 +535,6 @@ export default {
|
|
|
.article-body {
|
|
|
padding: 20rpx;
|
|
|
}
|
|
|
-.article-meta {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 10rpx;
|
|
|
-}
|
|
|
.article-category {
|
|
|
font-size: 20rpx;
|
|
|
color: #5B9BD5;
|