20260325稳定版
This commit is contained in:
@@ -0,0 +1,645 @@
|
||||
<template>
|
||||
<view class="detail-page" :style="{paddingTop: paddingTop}">
|
||||
<view class="detail-bg"></view>
|
||||
|
||||
<view class="detail-header">
|
||||
<view class="header-left" @click="goBack">
|
||||
<u-icon name="arrow-left" size="32" color="#1b1b1b"></u-icon>
|
||||
</view>
|
||||
<text class="header-title">详情</text>
|
||||
<!-- <view class="header-right">-->
|
||||
<!-- <u-icon name="more-dot-fill" size="26" color="#1b1b1b"></u-icon>-->
|
||||
<!-- <u-icon name="calendar-fill" size="26" color="#1b1b1b" class="header-icon-gap"></u-icon>-->
|
||||
<!-- </view>-->
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="detail-scroll">
|
||||
<view class="detail-info">
|
||||
<view class="detail-label">{{ detailInfo.category }}</view>
|
||||
<view class="detail-title">{{ detailInfo.title }}</view>
|
||||
<view class="detail-subtitle">{{ detailInfo.source }}</view>
|
||||
<view class="detail-author">
|
||||
<!-- <view class="author-meta">-->
|
||||
<!-- <text class="author-name">{{ detailInfo.author }}</text>-->
|
||||
<!-- <text class="author-desc">{{ detailInfo.authorDesc }}</text>-->
|
||||
<!-- </view>-->
|
||||
<text class="detail-date">{{ dayjs(detailInfo.createTime).format('YYYY-MM-DD') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <image class="detail-cover" :src="detailInfo.image" mode="aspectFill"></image>-->
|
||||
|
||||
<view class="detail-article">
|
||||
<u-parse :content="detailInfo.content"/>
|
||||
</view>
|
||||
<u-gap height="200rpx"/>
|
||||
</scroll-view>
|
||||
|
||||
<view class="detail-action">
|
||||
<view class="flex-1 flex justify-center items-center">
|
||||
<view class="action-item" @click="openCommentPopup" v-if="!authing">
|
||||
<u-icon name="chat" size="28" color="#1b1b1b"></u-icon>
|
||||
<text class="action-text">评论</text>
|
||||
</view>
|
||||
<view class="action-item" @click="toggleFavorite">
|
||||
<u-icon :name="isFavorite ? 'star-fill' : 'star'" size="28" color="#f7b500"></u-icon>
|
||||
<text class="action-text">收藏</text>
|
||||
</view>
|
||||
</view>
|
||||
<button open-type="share" class="action-button" @click="handleShare">
|
||||
<u-icon name="share" size="28" color="#fff"></u-icon>
|
||||
<text class="action-btn-text">分享</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<u-popup
|
||||
:show="showCommentPopup"
|
||||
mode="bottom"
|
||||
round="20"
|
||||
close-on-click-overlay
|
||||
:safe-area-inset-bottom="false"
|
||||
@close="showCommentPopup = false"
|
||||
>
|
||||
<view class="comment-popup">
|
||||
<view class="comment-popup-header">
|
||||
<text class="comment-popup-title">评论 ({{ commentList.length }})</text>
|
||||
<u-icon name="close" size="28" color="#9ca3af" @click="showCommentPopup = false"></u-icon>
|
||||
</view>
|
||||
<scroll-view scroll-y class="comment-list">
|
||||
<view v-if="commentLoading" class="comment-placeholder">评论加载中...</view>
|
||||
<view v-else-if="!commentList.length" class="comment-placeholder">暂时还没有评论</view>
|
||||
<view v-else>
|
||||
<view
|
||||
class="comment-item"
|
||||
v-for="(item, index) in commentList"
|
||||
:key="item.commentId || item.id || index"
|
||||
>
|
||||
<view class="comment-item-header">
|
||||
<text class="comment-user">{{ item.userName || item.nickname || '匿名用户' }}</text>
|
||||
<text class="comment-time">{{ formatCommentTime(item.createTime || item.createdAt) }}</text>
|
||||
</view>
|
||||
<view class="comment-content">{{ item.content }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="comment-footer">
|
||||
<view class="comment-publish-btn" @click="openPublishPopup">发表评论</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<u-popup
|
||||
:show="showPublishPopup"
|
||||
mode="center"
|
||||
round="20"
|
||||
close-on-click-overlay
|
||||
:safe-area-inset-bottom="false"
|
||||
@close="closePublishPopup"
|
||||
>
|
||||
<view class="publish-popup">
|
||||
<view class="publish-header">写评论</view>
|
||||
<textarea
|
||||
class="publish-textarea"
|
||||
v-model="newCommentContent"
|
||||
maxlength="200"
|
||||
auto-height
|
||||
placeholder="请输入评论内容"
|
||||
placeholder-style="color:#9ca3af"
|
||||
></textarea>
|
||||
<view class="publish-actions">
|
||||
<view class="publish-cancel" @click="closePublishPopup">取消</view>
|
||||
<view
|
||||
class="publish-submit"
|
||||
:class="{'is-disabled': commentSubmitting}"
|
||||
@click="submitComment"
|
||||
>
|
||||
发表
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<Login ref="loginPopup" @done="onLoginDone"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
addArticleCollectReq,
|
||||
articleInfoReq,
|
||||
articleCommentListReq,
|
||||
addArticleCommentReq, dictDataReq
|
||||
} from "@/api/common";
|
||||
import {dayjs} from '@/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js'
|
||||
import Login from "@/components/Login.vue";
|
||||
import {getUserInfo} from "@/util/user";
|
||||
|
||||
export default {
|
||||
components: {Login},
|
||||
data() {
|
||||
return {
|
||||
detailInfo: {
|
||||
category: '',
|
||||
title: '',
|
||||
subtitle: '',
|
||||
author: '',
|
||||
authorDesc: '',
|
||||
date: '',
|
||||
image: '',
|
||||
content: []
|
||||
},
|
||||
isFavorite: false,
|
||||
articleImages: [
|
||||
'/static/icon/article_1.png',
|
||||
'/static/icon/article_2.png',
|
||||
'/static/icon/article_3.png',
|
||||
'/static/icon/article_4.png',
|
||||
'/static/icon/article_5.png',
|
||||
'/static/icon/article_6.png'
|
||||
],
|
||||
mockArticles: [
|
||||
{
|
||||
id: 5,
|
||||
category: '',
|
||||
title: '',
|
||||
subtitle: '',
|
||||
author: '',
|
||||
authorDesc: '8年情感心理师 · 自由写作者',
|
||||
date: '',
|
||||
image: '',
|
||||
content: ''
|
||||
}
|
||||
],
|
||||
paddingTop: '40px',
|
||||
showCommentPopup: false,
|
||||
commentList: [],
|
||||
commentLoading: false,
|
||||
showPublishPopup: false,
|
||||
newCommentContent: '',
|
||||
commentSubmitting: false,
|
||||
authing: true,
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const {id} = options || {}
|
||||
this.getInfo(id)
|
||||
this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 'px'
|
||||
},
|
||||
onShow(){
|
||||
this.getDictList()
|
||||
},
|
||||
methods: {
|
||||
dayjs,
|
||||
async getDictList() {
|
||||
const {data} = await dictDataReq({dictId: '171'})
|
||||
this.authing = parseInt(data[0].dictDataCode) === 1
|
||||
},
|
||||
async getInfo(id) {
|
||||
const {data} = await articleInfoReq(id)
|
||||
this.detailInfo = data
|
||||
this.isFavorite = data.hasCollect
|
||||
},
|
||||
goBack() {
|
||||
if (getCurrentPages().length === 1) uni.switchTab({url: '/pages/index/index'})
|
||||
else uni.navigateBack()
|
||||
},
|
||||
toggleFavorite() {
|
||||
this.isFavorite = !this.isFavorite
|
||||
uni.showToast({
|
||||
title: this.isFavorite ? '已收藏' : '已取消',
|
||||
icon: 'none'
|
||||
})
|
||||
addArticleCollectReq({
|
||||
articleId: this.detailInfo.articleId
|
||||
})
|
||||
},
|
||||
handleShare() {
|
||||
uni.showToast({
|
||||
title: '已复制分享链接',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
openCommentPopup() {
|
||||
if (!this.detailInfo.articleId) return
|
||||
this.showCommentPopup = true
|
||||
this.fetchComments()
|
||||
},
|
||||
async fetchComments() {
|
||||
if (!this.detailInfo.articleId) return
|
||||
this.commentLoading = true
|
||||
try {
|
||||
const {data} = await articleCommentListReq({articleId: this.detailInfo.articleId})
|
||||
this.commentList = this.normalizeCommentList(data)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
uni.showToast({
|
||||
title: '评论加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.commentLoading = false
|
||||
}
|
||||
},
|
||||
normalizeCommentList(data) {
|
||||
if (Array.isArray(data)) return data
|
||||
if (data && Array.isArray(data.records)) return data.records
|
||||
if (data && Array.isArray(data.list)) return data.list
|
||||
if (data && Array.isArray(data.rows)) return data.rows
|
||||
return []
|
||||
},
|
||||
openPublishPopup() {
|
||||
if (!this.ensureLogin()) return
|
||||
this.showPublishPopup = true
|
||||
this.newCommentContent = ''
|
||||
},
|
||||
closePublishPopup() {
|
||||
this.showPublishPopup = false
|
||||
},
|
||||
async submitComment() {
|
||||
if (this.commentSubmitting) return
|
||||
if (!this.ensureLogin()) return
|
||||
const content = (this.newCommentContent || '').trim()
|
||||
if (!content) {
|
||||
return uni.showToast({
|
||||
title: '请输入评论内容',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
this.commentSubmitting = true
|
||||
try {
|
||||
await addArticleCommentReq({
|
||||
content,
|
||||
articleId: this.detailInfo.articleId
|
||||
})
|
||||
uni.showToast({
|
||||
title: '发表成功',
|
||||
icon: 'success'
|
||||
})
|
||||
this.newCommentContent = ''
|
||||
this.showPublishPopup = false
|
||||
this.fetchComments()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
const message = error && (error.msg || error.message)
|
||||
uni.showToast({
|
||||
title: message || '发表评论失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.commentSubmitting = false
|
||||
}
|
||||
},
|
||||
ensureLogin() {
|
||||
const {token} = getUserInfo()
|
||||
if (!token) {
|
||||
this.$refs.loginPopup && this.$refs.loginPopup.open()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
onLoginDone() {
|
||||
if (this.showCommentPopup) {
|
||||
this.fetchComments()
|
||||
}
|
||||
},
|
||||
formatCommentTime(time) {
|
||||
if (!time) return '--'
|
||||
const parsed = dayjs(time)
|
||||
return typeof parsed.isValid === 'function' && parsed.isValid() ? parsed.format('YYYY-MM-DD HH:mm') : time
|
||||
}
|
||||
},
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: this.detailInfo.title,
|
||||
path: '/pages/index/detail?id=' + this.detailInfo.articleId
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.detailInfo.title,
|
||||
path: '/pages/index/detail?id=' + this.detailInfo.articleId
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail-page {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #e5edff 0%, #f6f4ff 45%, #fef7ff 100%);
|
||||
//padding: 60rpx 32rpx 140rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.detail-bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 300rpx;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
filter: blur(35rpx);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.header-left,
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: #1b1b1b;
|
||||
}
|
||||
|
||||
.header-icon-gap {
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
.detail-scroll {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
max-height: calc(100vh - 260rpx);
|
||||
padding-bottom: 220rpx;
|
||||
}
|
||||
|
||||
.detail-info {
|
||||
padding: 20rpx 16rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
display: inline-flex;
|
||||
padding: 8rpx 22rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 24rpx;
|
||||
color: #4a5568;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #16171d;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.detail-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #8b8f99;
|
||||
margin-top: 16rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.detail-author {
|
||||
margin-top: 22rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.6);
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.author-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
}
|
||||
|
||||
.author-name {
|
||||
font-size: 28rpx;
|
||||
color: #2c2c2c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.author-desc {
|
||||
font-size: 24rpx;
|
||||
color: #a0a3b0;
|
||||
}
|
||||
|
||||
.detail-date {
|
||||
font-size: 24rpx;
|
||||
color: #babec6;
|
||||
}
|
||||
|
||||
.detail-cover {
|
||||
//width: 100%;
|
||||
height: 360rpx;
|
||||
border-radius: 30rpx;
|
||||
margin: 30rpx;
|
||||
box-shadow: 0 20rpx 40rpx rgba(128, 139, 255, 0.2);
|
||||
}
|
||||
|
||||
.detail-article {
|
||||
margin: 30rpx;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 32rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 20rpx 40rpx rgba(128, 139, 255, 0.15);
|
||||
}
|
||||
|
||||
.detail-paragraph {
|
||||
font-size: 26rpx;
|
||||
color: #555c6b;
|
||||
line-height: 1.8;
|
||||
margin-bottom: 26rpx;
|
||||
}
|
||||
|
||||
.detail-paragraph:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-action {
|
||||
z-index: 999;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 26rpx 40rpx calc(26rpx + env(safe-area-inset-bottom));
|
||||
background: #ffffff;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 -12rpx 40rpx rgba(99, 102, 241, 0.12);
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
color: #1b1b1b;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.action-text {
|
||||
color: #1f2a37;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
flex: 1;
|
||||
margin-left: 40rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 50rpx;
|
||||
background: linear-gradient(120deg, #0b1c56, #1a2e8e);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.action-btn-text {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.comment-popup {
|
||||
padding: 30rpx;
|
||||
max-height: 70vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.comment-popup-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.comment-popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1f2933;
|
||||
}
|
||||
|
||||
.comment-list {
|
||||
flex: 1;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1px solid #eef2ff;
|
||||
}
|
||||
|
||||
.comment-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.comment-user {
|
||||
font-size: 28rpx;
|
||||
color: #111827;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.comment-time {
|
||||
font-size: 22rpx;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.comment-content {
|
||||
margin-top: 12rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
color: #4b5563;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.comment-placeholder {
|
||||
text-align: center;
|
||||
color: #9ca3af;
|
||||
padding: 80rpx 0;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.comment-footer {
|
||||
padding-top: 24rpx;
|
||||
}
|
||||
|
||||
.comment-publish-btn {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 22rpx 0;
|
||||
border-radius: 50rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
background: linear-gradient(120deg, #0b1c56, #1a2e8e);
|
||||
}
|
||||
|
||||
.publish-popup {
|
||||
width: 640rpx;
|
||||
padding: 40rpx 32rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.publish-header {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.publish-textarea {
|
||||
width: 100%;
|
||||
min-height: 200rpx;
|
||||
background: #f3f4f6;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx;
|
||||
font-size: 26rpx;
|
||||
color: #1f2937;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.publish-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.publish-cancel {
|
||||
padding: 16rpx 32rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 26rpx;
|
||||
color: #6b7280;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.publish-submit {
|
||||
padding: 16rpx 40rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(120deg, #0b1c56, #1a2e8e);
|
||||
}
|
||||
|
||||
.publish-submit.is-disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<view class="discover-page" :style="{paddingTop: paddingTop}">
|
||||
<view class="blur-bg"></view>
|
||||
|
||||
<view class="header-area">
|
||||
<view class="status-bar">
|
||||
<text class="header-title">发现</text>
|
||||
</view>
|
||||
|
||||
<view class="search-section">
|
||||
<view class="search-input">
|
||||
<u-icon name="search" size="28" color="#9EA3B0"></u-icon>
|
||||
<input
|
||||
class="search-field"
|
||||
v-model="searchKeyword"
|
||||
placeholder="请输入关键词搜索"
|
||||
placeholder-class="placeholder"
|
||||
confirm-type="search"
|
||||
@confirm="handleSearch"
|
||||
/>
|
||||
</view>
|
||||
<view class="search-btn" @click="handleSearch">搜索</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="category-scroll" scroll-x="true" enable-flex>
|
||||
<view
|
||||
class="category-item"
|
||||
v-for="item in categories"
|
||||
:key="item"
|
||||
:class="{ active: currentCategory === item.categoryId }"
|
||||
@click="selectCategory(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<view class="card-grid">
|
||||
<view
|
||||
class="discover-card"
|
||||
v-for="card in cardList"
|
||||
:key="card.articleId"
|
||||
@click="goToDetail(card)"
|
||||
>
|
||||
<image class="card-cover" :src="`${card.image}`" mode="aspectFill"></image>
|
||||
<view class="card-title">{{ card.title }}</view>
|
||||
<view class="card-desc">{{ card.source }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="indicator">
|
||||
<view
|
||||
v-for="dotIndex in indicatorDots"
|
||||
:key="dotIndex"
|
||||
class="dot"
|
||||
:class="{ active: dotIndex - 1 === activeIndicator }"
|
||||
></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {dictDataReq, listArticleCateReq, listArticleReq} from "@/api/common";
|
||||
import {getUserInfo} from "@/util/user";
|
||||
import {chatListReq} from "@/api/chat";
|
||||
import {coinAddReq} from "@/api/coin";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
searchKeyword: '',
|
||||
categories: [],
|
||||
currentCategory: null,
|
||||
indicatorDots: 2,
|
||||
activeIndicator: 0,
|
||||
paddingTop: '100px',
|
||||
cardList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getCategories() {
|
||||
const {data} = await listArticleCateReq()
|
||||
this.categories = [{categoryId: null, title: '全部'}, ...data]
|
||||
await this.getArticleList()
|
||||
},
|
||||
selectCategory(category) {
|
||||
this.currentCategory = category.categoryId
|
||||
this.getArticleList()
|
||||
},
|
||||
async getArticleList() {
|
||||
const {data} = await listArticleReq({
|
||||
categoryId: this.currentCategory,
|
||||
title: this.searchKeyword ?? null
|
||||
})
|
||||
this.cardList = data
|
||||
// console.log(this.cardList)
|
||||
},
|
||||
goToDetail(card) {
|
||||
const targetId = card && card.articleId ? card.articleId : ''
|
||||
uni.navigateTo({
|
||||
url: `/pages/index/detail?id=${targetId}`
|
||||
})
|
||||
},
|
||||
handleSearch() {
|
||||
const keyword = this.searchKeyword.trim()
|
||||
this.getCategories()
|
||||
},
|
||||
async getMessageList() {
|
||||
const res = await chatListReq()
|
||||
this.messageList = res.data
|
||||
if (!this.messageList.length) this.toSelect()
|
||||
},
|
||||
toSelect(){
|
||||
if (!uni.getStorageSync('forceNoJump'))
|
||||
uni.navigateTo({url: '/pages/chat/select'})
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.paddingTop = uni.getSystemInfoSync().statusBarHeight + 40 + 'px'
|
||||
this.getCategories()
|
||||
if (!getUserInfo().token) {
|
||||
this.toSelect()
|
||||
} else {
|
||||
this.getMessageList()
|
||||
}
|
||||
},
|
||||
onShareTimeline() {
|
||||
coinAddReq({
|
||||
type: '+',
|
||||
desc: '分享获得',
|
||||
num: 1
|
||||
})
|
||||
return {
|
||||
title: '简幸',
|
||||
path: '/pages/index/index'
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
coinAddReq({
|
||||
type: '+',
|
||||
desc: '分享获得',
|
||||
num: 1
|
||||
})
|
||||
return {
|
||||
title: '简幸',
|
||||
path: '/pages/index/index'
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.discover-page {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #e4f0ff 0%, #f4f3ff 45%, #fef9ff 100%);
|
||||
padding: 40rpx 30rpx 80rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.blur-bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 220rpx;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
filter: blur(30rpx);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.header-area {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 38rpx;
|
||||
font-weight: 600;
|
||||
color: #151515;
|
||||
}
|
||||
|
||||
.header-icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-icon-gap {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
|
||||
.search-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 76rpx;
|
||||
border-radius: 48rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 28rpx;
|
||||
box-shadow: 0 8rpx 30rpx rgba(124, 157, 255, 0.2);
|
||||
}
|
||||
|
||||
.search-field {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #9EA3B0;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
width: 140rpx;
|
||||
height: 76rpx;
|
||||
border-radius: 50rpx;
|
||||
background: linear-gradient(120deg, #5fb3f0, #8b7df0);
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.category-scroll {
|
||||
margin-top: 30rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60rpx;
|
||||
padding: 0 32rpx;
|
||||
border-radius: 40rpx;
|
||||
font-size: 26rpx;
|
||||
color: #7a7d85;
|
||||
background-color: rgba(255, 255, 255, 0.6);
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.category-item.active {
|
||||
color: #111;
|
||||
font-weight: 600;
|
||||
background: #fff;
|
||||
box-shadow: 0 8rpx 20rpx rgba(130, 152, 255, 0.25);
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.discover-card {
|
||||
width: calc(50% - 12rpx);
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 26rpx;
|
||||
background-color: rgba(255, 255, 255, 0.92);
|
||||
box-shadow: 0 10rpx 30rpx rgba(133, 149, 255, 0.2);
|
||||
padding: 16rpx 18rpx 26rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card-cover {
|
||||
width: 100%;
|
||||
height: 260rpx;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 18rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 28rpx;
|
||||
color: #1f1f1f;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
font-size: 24rpx;
|
||||
color: #6b6f7a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
margin: 0 8rpx;
|
||||
}
|
||||
|
||||
.dot.active {
|
||||
width: 28rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #151515;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user