1
0
mirror of https://github.com/ialley-workshop-open/uni-halo.git synced 2026-06-12 13:19:31 +08:00

release: 发布 uni-halo beta-v2.0 版本

This commit is contained in:
小莫唐尼
2024-05-20 01:27:15 +08:00
parent a81c506a14
commit 057a7cf6f0
49 changed files with 2696 additions and 2531 deletions
+148 -118
View File
@@ -8,33 +8,33 @@
<block v-else>
<!-- 顶部信息 -->
<view class="head ma-24">
<view class="title">{{ result.title }}</view>
<view class="title">{{ result.spec.title }}</view>
<view class="detail">
<view class="author">
<text class="author-name">博主{{ author.nickname }}</text>
<text class="author-name">作者{{ result.owner.displayName }}</text>
<text class="author-time">
时间{{ { d: result.createTime, f: 'yyyy年MM月dd日 星期w' } | formatTime }}
时间{{ { d: result.spec.publishTime, f: 'yyyy年MM月dd日 星期w' } | formatTime }}
</text>
</view>
<view class="cover" v-if="result.thumbnail">
<image class="cover-img" mode="aspectFill" :src="calcUrl(result.thumbnail)"></image>
<view class="cover" v-if="result.spec.cover">
<image class="cover-img" mode="aspectFill" :src="calcUrl(result.spec.cover)"></image>
</view>
<view class="count" :class="{ 'no-thumbnail': !result.thumbnail }">
<view class="count" :class="{ 'no-thumbnail': !result.spec.cover }">
<view class="count-item">
<text class="value">{{ result.visits }}</text>
<text class="value">{{ result.stats.visit }}</text>
<text class="label">阅读</text>
</view>
<view class="count-item">
<text class="value">{{ result.likes }}</text>
<text class="value">{{ result.stats.upvote }}</text>
<text class="label">喜欢</text>
</view>
<view class="count-item">
<text class="value">{{ result.commentCount }}</text>
<text class="value">{{ result.stats.comment }}</text>
<text class="label">评论</text>
</view>
<view class="count-item">
<text class="value">{{ result.wordCount }}</text>
<text class="value">{{ result.content.raw.length }}</text>
<text class="label">字数</text>
</view>
</view>
@@ -46,8 +46,9 @@
<text class="text-weight-b">分类</text>
<text v-if="result.categories.length == 0" class="category-tag is-empty">未选择分类</text>
<block v-else>
<text class="category-tag" v-for="(item, index) in result.categories" :key="index" @click="fnToCate(item)">
{{ item.name }}
<text class="category-tag" v-for="(item, index) in result.categories" :key="index"
@click="fnToCate(item)">
{{ item.spec.displayName }}
</text>
</block>
</view>
@@ -55,21 +56,25 @@
<text class="text-weight-b">标签</text>
<text v-if="result.tags.length == 0" class="category-tag is-empty">未选择标签</text>
<block v-else>
<text class="category-tag" :style="{ backgroundColor: item.color }" v-for="(item, index) in result.tags" :key="index" @click="fnToTag(item)">
{{ item.name }}
<text class="category-tag" :style="{ backgroundColor: item.color }"
v-for="(item, index) in result.tags" :key="index" @click="fnToTag(item)">
{{ item.spec.displayName }}
</text>
</block>
</view>
<view v-if="originalURL" class="mt-18 category-type original-url">
<view class="original-url_left text-weight-b">原文</view>
<view class="original-url_right text-grey">
<text class="original-url_right__link" @click.stop="fnToOriginal(originalURL)">{{ originalURL }}</text>
<text class="original-url_right__btn" @click.stop="fnToOriginal(originalURL)">阅读原文<text class="iconfont icon-angle-right ml-5 text-size-s"></text> </text>
<text class="original-url_right__link"
@click.stop="fnToOriginal(originalURL)">{{ originalURL }}</text>
<text class="original-url_right__btn" @click.stop="fnToOriginal(originalURL)">阅读原文<text
class="iconfont icon-angle-right ml-5 text-size-s"></text> </text>
</view>
</view>
</view>
<!-- 广告区域 -->
<view v-if="haloAdConfig.articleDetail.use && (haloAdConfig.unitId || haloAdConfig.adpid)" class="ad-wrap ma-24 mb-0">
<view v-if="haloAdConfig.articleDetail.use && (haloAdConfig.unitId || haloAdConfig.adpid)"
class="ad-wrap ma-24 mb-0">
<!-- #ifdef MP-WEIXIN -->
<ad v-if="haloAdConfig.unitId" :unit-id="haloAdConfig.unitId"></ad>
<!-- #endif -->
@@ -81,8 +86,13 @@
<view class="content ml-24 mr-24">
<!-- markdown渲染 -->
<view class="markdown-wrap">
<tm-more :disabled="true" :maxHeight="1500" :isRemovBar="true" :open="showValidVisitMore" @click="fnOnShowValidVisitMore">
<mp-html class="evan-markdown" lazy-load :domain="markdownConfig.domain" :loading-img="markdownConfig.loadingGif" :scroll-table="true" :selectable="true" :tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle" :content="result.content || result.formatContent" :markdown="true" :showLineNumber="true" :showLanguageName="true" :copyByLongPress="true" />
<tm-more :disabled="true" :maxHeight="1500" :isRemovBar="true" :open="showValidVisitMore"
@click="fnOnShowValidVisitMore">
<mp-html class="evan-markdown" lazy-load :domain="markdownConfig.domain"
:loading-img="markdownConfig.loadingGif" :scroll-table="true" :selectable="true"
:tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle"
:content="result.content.raw" :markdown="true" :showLineNumber="true"
:showLanguageName="true" :copyByLongPress="true" />
<template v-slot:more="{ data }">
<view class="">
<text class="text-blue text-size-m text-weight-b">文章部分内容已加密点击解锁</text>
@@ -92,7 +102,8 @@
</tm-more>
</view>
<!-- 广告区域微信/decloud申请 -->
<view v-if="haloAdConfig.articleDetail.use && (haloAdConfig.unitId || haloAdConfig.adpid)" class="ad-wrap mt-24 mb-24 ">
<view v-if="haloAdConfig.articleDetail.use && (haloAdConfig.unitId || haloAdConfig.adpid)"
class="ad-wrap mt-24 mb-24 ">
<!-- #ifdef MP-WEIXIN -->
<ad v-if="haloAdConfig.unitId" :unit-id="haloAdConfig.unitId"></ad>
<!-- #endif -->
@@ -104,11 +115,13 @@
<!-- 广告区域自定义广告位 -->
<view class="ad-card mt-24" v-if="haloAdConfig.articleDetail.custom.use">
<text class="ad-card_tip">广告</text>
<image class="ad-card_cover" :src="haloAdConfig.articleDetail.custom.cover" mode="scaleToFill"></image>
<image class="ad-card_cover" :src="haloAdConfig.articleDetail.custom.cover" mode="scaleToFill">
</image>
<view class="ad-card_info">
<view class="ad-card_info-title">{{ haloAdConfig.articleDetail.custom.title }}</view>
<view class="ad-card_info-desc">{{ haloAdConfig.articleDetail.custom.content }}</view>
<view v-if="haloAdConfig.articleDetail.custom.url" class="ad-card_info-link" @click="fnToWebview(haloAdConfig.articleDetail.custom)">
<view v-if="haloAdConfig.articleDetail.custom.url" class="ad-card_info-link"
@click="fnToWebview(haloAdConfig.articleDetail.custom)">
立即查看
</view>
</view>
@@ -117,7 +130,8 @@
<!-- 版权声明 -->
<view v-if="copyright.use" class="copyright-wrap bg-white mt-24 pa-24 round-4">
<view class="copyright-title text-weight-b">版权声明</view>
<view class="copyright-content mt-12 grey-lighten-5 text-grey-darken-2 round-4 pt-12 pb-12 pl-24 pr-24 ">
<view
class="copyright-content mt-12 grey-lighten-5 text-grey-darken-2 round-4 pt-12 pb-12 pl-24 pr-24 ">
<view v-if="copyright.author" class="copyright-text text-size-s ">
版权归属{{ copyright.author }}
</view>
@@ -131,24 +145,29 @@
</view>
<!-- 评论展示区域 -->
<view class="comment-wrap bg-white mt-24 pa-24 round-4">
<commentList :disallowComment="result.disallowComment" :postId="result.id" :post="result" @on-comment-detail="fnOnShowCommentDetail" @on-loaded="fnOnCommentLoaded"></commentList>
<view v-if="result" class="comment-wrap bg-white mt-24 pa-24 round-4">
<commentList :disallowComment="!result.spec.allowComment" :postName="result.metadata.name"
:post="result" @on-comment-detail="fnOnShowCommentDetail" @on-loaded="fnOnCommentLoaded">
</commentList>
</view>
</view>
<!-- 弹幕效果 -->
<barrage ref="barrage" :maxTop="240" :type="globalAppSettings.barrage.type"></barrage>
<!-- 返回顶部 -->
<tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent" @click="fnToTopPage()"></tm-flotbutton>
<tm-flotbutton :actions="btnOption.actions" actions-pos="left" :show-text="true" color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton>
<tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent"
@click="fnToTopPage()"></tm-flotbutton>
<tm-flotbutton :actions="btnOption.actions" actions-pos="left" :show-text="true"
color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton>
</block>
<!-- 评论详情 -->
<tm-poup v-model="commentDetail.show" height="auto" :round="6" :over-close="true" position="bottom">
<view class="pa-24">
<view v-if="result" class="pa-24">
<view class="poup-head pb-24">
<view class="poup-title text-align-center text-size-g text-weight-b mb-32">评论详情</view>
<comment-item :useContentBg="false" :useActions="false" :isChild="false" :comment="commentDetail.comment" :postId="result.id"></comment-item>
<comment-item :useContentBg="false" :useActions="false" :isChild="false"
:comment="commentDetail.comment" :postName="result.metadata.name"></comment-item>
</view>
<scroll-view :scroll-y="true" class="poup-body">
@@ -159,7 +178,7 @@
</view>
<view v-else-if="commentDetail.loading == 'error'" class="error">
<tm-empty icon="icon-wind-cry" label="加载失败">
<tm-button theme="bg-gradient-light-blue-accent" size="m" v-if="!disallowComment" @click="fnGetChildComments()">
<tm-button theme="bg-gradient-light-blue-accent" size="m" @click="fnGetChildComments()">
刷新试试
</tm-button>
</tm-empty>
@@ -171,7 +190,9 @@
</view>
<block v-else>
<comment-item v-for="(comment, index) in commentDetail.list" :useContentBg="false" :useSolid="false" :useActions="false" :key="index" :isChild="false" :comment="comment" :postId="result.id"></comment-item>
<comment-item v-for="(comment, index) in commentDetail.list" :useContentBg="false"
:useSolid="false" :useActions="false" :key="index" :isChild="false" :comment="comment"
:postName="result.metadata.name"></comment-item>
</block>
</block>
</scroll-view>
@@ -203,7 +224,10 @@
</tm-poup>
<!-- 密码访问解密弹窗 -->
<tm-dialog :disabled="true" :input-val.sync="validVisitModal.value" title="验证提示" confirmText="立即验证" :showCancel="validVisitModal.useCancel" model="confirm" v-model="validVisitModal.show" content="博主设置了需要密码才能查看该文章内容,请输入文章密码进行验证" theme="split" confirmColor="blue shadow-blue-0" @cancel="fnOnValidVisitCancel" @confirm="fnOnValidVisitConfirm"></tm-dialog>
<tm-dialog :disabled="true" :input-val.sync="validVisitModal.value" title="验证提示" confirmText="立即验证"
:showCancel="validVisitModal.useCancel" model="confirm" v-model="validVisitModal.show"
content="博主设置了需要密码才能查看该文章内容,请输入文章密码进行验证" theme="split" confirmColor="blue shadow-blue-0"
@cancel="fnOnValidVisitCancel" @confirm="fnOnValidVisitConfirm"></tm-dialog>
</view>
</template>
@@ -226,7 +250,9 @@
import rCanvas from '@/components/r-canvas/r-canvas.vue';
import barrage from '@/components/barrage/barrage.vue';
import { haloWxShareMixin } from '@/common/mixins/wxshare.mixin.js';
import {
haloWxShareMixin
} from '@/common/mixins/wxshare.mixin.js';
export default {
components: {
tmSkeleton,
@@ -248,10 +274,11 @@
loading: 'loading',
markdownConfig: MarkdownConfig,
btnOption: {
actions: [{
icon: 'icon-like',
color: 'bg-gradient-orange-accent'
},
actions: [
// {
// icon: 'icon-like',
// color: 'bg-gradient-orange-accent'
// },
{
icon: 'icon-commentdots-fill',
color: 'bg-gradient-green-accent'
@@ -263,15 +290,15 @@
]
},
queryParams: {
articleId: null
name: null
},
result: {},
result: null,
commentDetail: {
loading: 'loading',
show: false,
comment: {},
postId: undefined,
postName: undefined,
list: []
},
poster: {
@@ -354,7 +381,7 @@
},
onLoad(e) {
this.fnSetPageTitle('文章加载中...');
this.queryParams.articleId = e.articleId;
this.queryParams.name = e.name;
this.fnGetData();
},
@@ -364,31 +391,27 @@
methods: {
fnGetData() {
this.loading = 'loading';
// uni.showLoading({
// mask: true,
// title: '加载中...'
// });
this.$httpApi
.getArticleDetail(this.queryParams.articleId)
this.$httpApi.v2
.getPostByName(this.queryParams.name)
.then(res => {
if (res.status == 200) {
this.result = res.data;
this.metas = res.data.metas;
this.fnSetPageTitle('文章详情');
this.loading = 'success';
this.fnSetWxShareConfig({
title: this.result.title,
desc: this.result.summary,
imageUrl: this.$utils.checkThumbnailUrl(this.result.thumbnail),
path: `/pagesA/article-detail/article-detail?articleId=${this.queryParams.articleId}`,
copyLink: this.$haloConfig.apiUrl,
query: {}
});
} else {
this.loading = 'error';
}
console.log('详情', res);
this.result = res;
this.metas = [];
this.fnSetPageTitle('文章详情');
this.loading = 'success';
this.fnSetWxShareConfig({
title: this.result.spec.title,
desc: this.result.content.raw,
imageUrl: this.$utils.checkThumbnailUrl(this.result.spec.cover),
path: `/pagesA/article-detail/article-detail?name=${this.result.metadata.name}`,
copyLink: this.$baseApiUrl,
query: {}
});
})
.catch(err => {
console.log("错误", err)
this.loading = 'error';
})
.finally(() => {
@@ -400,28 +423,28 @@
// 浮动按钮点击
fnOnFlotButtonChange(index) {
switch (index) {
// case 0:
// this.fnDoLikes();
// break;
case 0:
this.fnDoLikes();
break;
case 1:
this.fnToComment();
break;
case 2:
case 1:
this.fnShowShare();
break;
}
},
fnToComment() {
if (this.result.disallowComment) {
if (!this.result.spec.allowComment) {
return uni.$tm.toast('文章已开启禁止评论!');
}
this.$Router.push({
path: '/pagesA/comment/comment',
query: {
id: this.result.id,
parentId: 0,
title: this.result.title,
isComment: true,
postName: this.result.metadata.name,
title: this.result.spec.title,
from: 'posts',
formPage: 'comment_list',
type: 'post'
@@ -474,7 +497,7 @@
this.$nextTick(async () => {
const systemInfo = await uni.getSystemInfoSync();
const _bloggerAvatar = this.$utils.checkAvatarUrl(this.bloggerInfo.avatar, true);
const _articleCover = this.$utils.checkThumbnailUrl(this.result.thumbnail, true);
const _articleCover = this.$utils.checkThumbnailUrl(this.result.spec.cover, true);
// 初始化
await this.$refs.rCanvas.init({
canvas_id: 'rCanvas',
@@ -566,7 +589,7 @@
// 文章标题
await this.$refs.rCanvas
.drawText({
text: this.result.title,
text: this.result.spec.title,
max_width: 312,
line_clamp: 1,
x: 12,
@@ -583,7 +606,7 @@
});
await this.$refs.rCanvas
.drawText({
text: this.result.summary,
text: this.result.content.raw,
max_width: 312,
line_clamp: 2,
x: 12,
@@ -674,9 +697,9 @@
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
href: this.$haloConfig.apiUrl,
title: this.result.title,
summary: this.result.summary,
href: this.$baseApiUrl,
title: this.result.spec.title,
summary: this.result.content.raw,
imageUrl: this.poster.res.tempFilePath,
success: function(res) {
console.log('success:' + JSON.stringify(res));
@@ -688,41 +711,45 @@
// #endif
},
fnOnShowCommentDetail(data) {
const { postId, comment } = data;
const {
postName,
comment
} = data;
this.commentDetail.comment = comment;
this.commentDetail.postId = postId;
this.commentDetail.postName = postName;
this.commentDetail.list = [];
this.commentDetail.show = true;
this.fnGetChildComments();
},
fnGetChildComments() {
this.commentDetail.loading = 'loading';
this.$httpApi
.getPostChildrenCommentList(this.commentDetail.postId, this.commentDetail.comment.id, {})
this.$httpApi.v2
.getPostCommentReplyList(this.commentDetail.postName, {
page: 1,
size: 100
})
.then(res => {
if (res.status == 200) {
this.commentDetail.loading = 'success';
this.commentDetail.list = res.data;
} else {
this.commentDetail.loading = 'error';
}
console.log('getPostChildrenCommentList', res);
console.log('getPostChildrenCommentList res', res);
this.commentDetail.loading = 'success';
this.commentDetail.list = res.items;
})
.catch(err => {
console.log('getPostChildrenCommentList err', error);
this.commentDetail.loading = 'error';
});
},
fnToCate(category) {
uni.navigateTo({
url: `/pagesA/category-detail/category-detail?slug=${category.slug}&name=${category.name}`
url: `/pagesA/category-detail/category-detail?name=${category.metadata.name}&title=${category.spec.displayName}`
});
},
fnToTag(tag) {
uni.navigateTo({
url: `/pagesA/tag-detail/tag-detail?id=${tag.id}&slug=${tag.slug}&name=${tag.name}`
url: `/pagesA/tag-detail/tag-detail?name=${tag.metadata.name}&title=${tag.spec.displayName}`
});
},
async fnOnCommentLoaded(data) {
console.log("data", data)
const _list = [];
const _handleData = list => {
return new Promise(resolve => {
@@ -731,8 +758,8 @@
} else {
list.forEach(item => {
_list.push(item);
if (item.children && item.children.length != 0) {
_handleData(item.children);
if (item.replies && item.replies.length != 0) {
_handleData(item.replies.items);
}
resolve();
});
@@ -740,31 +767,31 @@
});
};
await _handleData(data);
if (this.globalAppSettings.barrage.use) {
this.$nextTick(() => {
if (_list.length != 0) {
_handleAddBarrage();
}
});
}
const _handleRemove = () => {
this.$refs['barrage'] && this.$refs['barrage'].remove({
duration: 5000, // 延迟关闭的时间
speed: 600 // 弹幕消失的速度
});
};
let index = 0;
const _handleAddBarrage = () => {
setTimeout(() => {
this.$refs['barrage'] && this.$refs['barrage'].add(_list[index]);
index += 1;
if (index < _list.length - 1) {
_handleAddBarrage();
} else {
_handleRemove();
}
}, 1000);
};
// if (this.globalAppSettings.barrage.use) {
// this.$nextTick(() => {
// if (_list.length != 0) {
// _handleAddBarrage();
// }
// });
// }
// const _handleRemove = () => {
// this.$refs['barrage'] && this.$refs['barrage'].remove({
// duration: 5000, // 延迟关闭的时间
// speed: 600 // 弹幕消失的速度
// });
// };
// let index = 0;
// const _handleAddBarrage = () => {
// setTimeout(() => {
// this.$refs['barrage'] && this.$refs['barrage'].add(_list[index]);
// index += 1;
// if (index < _list.length - 1) {
// _handleAddBarrage();
// } else {
// _handleRemove();
// }
// }, 1000);
// };
},
fnToWebview(data) {
uni.navigateTo({
@@ -776,7 +803,10 @@
});
},
fnToOriginal(originalURL) {
this.fnToWebview({ title: this.result.title, url: originalURL });
this.fnToWebview({
title: this.result.title,
url: originalURL
});
},
// 查看密码验证确认
fnOnValidVisitConfirm() {
+56 -49
View File
@@ -2,11 +2,13 @@
<view class="app-page" :class="{ 'is-balck grey-darken-6': isBlackTheme }">
<!-- 顶部切换 -->
<view class="e-fixed shadow-2">
<tm-search v-model="queryParams.keyword" :round="24" :shadow="0" color="light-blue" insert-color="light-blue" :clear="true" @confirm="fnOnSearch"></tm-search>
<tm-tabs color="light-blue" :shadow="0" v-model="tab.activeIndex" :list="tab.list" align="center" @change="fnOnTabChange"></tm-tabs>
<tm-search v-model="queryParams.keyword" :round="24" :shadow="0" color="light-blue"
insert-color="light-blue" :clear="true" @input="fnOnSearch" @confirm="fnOnSearch"></tm-search>
<tm-tabs v-if="false" color="light-blue" :shadow="0" v-model="tab.activeIndex" :list="tab.list"
align="center" @change="fnOnTabChange"></tm-tabs>
</view>
<!-- 占位区域 -->
<view style="width: 100vw;height: 184rpx;"></view>
<view style="width: 100vw;height: 100rpx;"></view>
<!-- 加载区域 -->
<view v-if="loading != 'success'" class="loading-wrap pa-24">
<tm-skeleton model="listAvatr"></tm-skeleton>
@@ -18,24 +20,23 @@
<view v-else class="content">
<view v-if="dataList.length == 0" class="content-empty flex flex-center">
<!-- 空布局 -->
<tm-empty icon="icon-shiliangzhinengduixiang-" label="该分类下暂无数据"></tm-empty>
<tm-empty v-if="!queryParams.keyword" icon="icon-shiliangzhinengduixiang-" label="请输入关键词搜索"></tm-empty>
<tm-empty v-else icon="icon-shiliangzhinengduixiang-"
:label="`未搜到 ${queryParams.keyword} 相关文章`"></tm-empty>
</view>
<block v-else>
<block v-for="(article, index) in dataList" :key="article.id">
<!-- 文章卡片 -->
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)">
<article-card :article="article" @on-click="fnToArticleDetail"></article-card>
<!-- 广告区域 -->
<view v-if="haloAdConfig.articles.use && (index + 1) % haloAdConfig.frequency == 0" class="ad-wrap ma-24">
<!-- #ifdef MP-WEIXIN -->
<ad v-if="haloAdConfig.unitId" :unit-id="haloAdConfig.unitId"></ad>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<ad v-if="haloAdConfig.adpid" :adpid="haloAdConfig.adpid"></ad>
<!-- #endif -->
</view>
</tm-translate>
</block>
<!-- 文章卡片 -->
<tm-translate v-for="(article, index) in dataList" :key="article.name" animation-name="fadeUp"
:wait="calcAniWait(index)">
<view class="article-card" @click="fnToArticleDetail(article)">
<text style="font-size: 32rpx;font-weight: bold;color: #333;" v-html="article.title">{{article.title}}</text>
<text style="font-size: 28rpx;margin-top: 16rpx;color: #555;" v-html="article.content">{{article.content}}
</text>
<text style="font-size: 24rpx;margin-top: 24rpx;color:#888">
发布日期{{ { d: article.publishTimestamp, f: 'yyyy年MM月dd日' } | formatTime }}
</text>
</view>
</tm-translate>
<tm-flotbutton @click="fnToTopPage" size="m" color="light-blue" icon="icon-angle-up"></tm-flotbutton>
<view class="load-text">{{ loadMoreText }}</view>
@@ -70,10 +71,10 @@
list: ['全部', '最新文章', '热门文章', '最近更新', '最多点赞']
},
queryParams: {
size: 10,
page: 0,
sort: 'topPriority,createTime,desc',
keyword: ''
keyword: "",
limit: 5,
highlightPreTag: "<text>",
highlightPostTag: "</text>"
},
cache: {
dataList: [],
@@ -88,27 +89,19 @@
onLoad() {
this.fnSetPageTitle('文章列表');
},
created() {
this.fnGetData();
created() {
if (!this.queryParams.keyword) {
this.loading = 'success'
} else {
this.fnGetData();
}
},
onPullDownRefresh() {
this.fnResetSetAniWaitIndex();
this.isLoadMore = false;
this.queryParams.page = 0;
this.fnGetData();
},
onReachBottom(e) {
if (this.result.hasNext) {
this.queryParams.page += 1;
this.isLoadMore = true;
this.fnGetData();
} else {
uni.showToast({
icon: 'none',
title: '没有更多数据了'
});
}
},
methods: {
fnOnTabChange(index) {
this.fnResetSetAniWaitIndex();
@@ -121,16 +114,18 @@
4: 'topPriority,likes,desc'
};
this.queryParams.sort = _sorts[index];
this.queryParams.page = 0;
this.dataList = [];
this.fnToTopPage();
this.fnGetData();
},
fnOnSearch() {
this.fnResetSetAniWaitIndex();
this.queryParams.page = 0;
this.isLoadMore = false;
this.fnGetData();
if (!this.queryParams.keyword) {
this.dataList = []
} else {
this.fnGetData();
}
},
fnGetData() {
// uni.showLoading({
@@ -142,20 +137,19 @@
this.loading = 'loading';
}
this.loadMoreText = '加载中...';
this.$httpApi
.getPostList(this.queryParams)
this.$httpApi.v2
.getPostListByKeyword(this.queryParams)
.then(res => {
console.log('请求结果:');
console.log(res);
this.loading = 'success';
this.loadMoreText = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
// 处理数据
this.result = res.data;
this.loadMoreText = res.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
this.result = res;
if (this.isLoadMore) {
this.dataList = this.dataList.concat(res.data.content);
this.dataList = this.dataList.concat(res.hits);
} else {
this.dataList = res.data.content;
this.dataList = res.hits;
}
})
.catch(err => {
@@ -174,7 +168,7 @@
//跳转文章详情
fnToArticleDetail(article) {
uni.navigateTo({
url: '/pagesA/article-detail/article-detail?articleId=' + article.id,
url: '/pagesA/article-detail/article-detail?name=' + article.name,
animationType: 'slide-in-right'
});
}
@@ -203,4 +197,17 @@
height: 60vh;
}
}
.article-card {
display: flex;
flex-direction: column;
box-sizing: border-box;
margin: 0 24rpx;
padding: 24rpx;
border-radius: 12rpx;
background-color: #ffff;
box-shadow: 0rpx 2rpx 24rpx rgba(0, 0, 0, 0.03);
overflow: hidden;
margin-bottom: 24rpx;
}
</style>
+11 -10
View File
@@ -42,7 +42,7 @@
size: 10,
page: 0
},
slug: '',
name: '',
pageTitle: '加载中...',
result: null,
dataList: [],
@@ -52,8 +52,8 @@
},
onLoad(e) {
this.slug = e.slug;
this.pageTitle = e.name;
this.name = e.name;
this.pageTitle = e.title;
this.fnGetData();
},
onPullDownRefresh() {
@@ -85,16 +85,17 @@
}
this.loadMoreText = '加载中...';
this.$httpApi
.getCategoryPostList(this.slug, this.queryParams)
.getCategoryPostList(this.name, this.queryParams)
.then(res => {
this.fnSetPageTitle(`分类:${this.pageTitle} (共${res.data.total}篇)`);
this.result = res.data;
console.log("请求成功:",res)
this.fnSetPageTitle(`${this.pageTitle} (共${res.total}篇)`);
this.result = res;
if (this.isLoadMore) {
this.dataList = this.dataList.concat(res.data.content);
this.dataList = this.dataList.concat(res.items);
} else {
this.dataList = res.data.content;
this.dataList = res.items;
}
this.loadMoreText = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
this.loadMoreText = res.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
setTimeout(() => {
this.loading = 'success';
}, 500);
@@ -114,7 +115,7 @@
//跳转文章详情
fnToArticleDetail(article) {
uni.navigateTo({
url: '/pagesA/article-detail/article-detail?articleId=' + article.id,
url: '/pagesA/article-detail/article-detail?name=' + article.metadata.name,
animationType: 'slide-in-right'
});
}
+97 -53
View File
@@ -3,15 +3,19 @@
<view class="content pt-24 pb-24 round-4">
<!-- 表单区域 -->
<tm-form @submit="fnOnSubmit">
<tm-input :auto-focus="true" name="content" :vertical="true" required :height="220" input-type="textarea" bg-color="grey-lighten-5" :maxlength="200" :borderBottom="false" placeholder="请输入内容,不超过200字符..." v-model="form.content"></tm-input>
<tm-input name="author" align="right" required title="我的昵称" placeholder="请输入您的昵称..." v-model="form.author"></tm-input>
<tm-input name="email" align="right" title="邮箱地址" placeholder="请输入您的邮箱..." v-model="form.email"></tm-input>
<tm-input name="authorUrl" align="right" title="我的网站" placeholder="请输入您的网址..." v-model="form.authorUrl"></tm-input>
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-n ">接收提醒</text>
<view><tm-switch :text="['是', '否']" v-model="form.allowNotification" color="bg-gradient-blue-accent"></tm-switch></view>
</view>
<view class="pa-24 pl-30 pr-30"><tm-button navtie-type="form" theme="bg-gradient-blue-accent" block>提交</tm-button></view>
<tm-input :auto-focus="true" name="content" :vertical="true" required :height="220"
input-type="textarea" bg-color="grey-lighten-5" :maxlength="200" :borderBottom="false"
placeholder="请输入内容,不超过200字符..." v-model="form.content"></tm-input>
<tm-input name="author" align="right" required title="我的昵称" placeholder="请输入您的昵称..."
v-model="form.author"></tm-input>
<tm-input name="avatar" align="right" required title="我的头像" placeholder="请输入您的头像..."
v-model="form.avatar"></tm-input>
<tm-input name="email" align="right" required title="邮箱地址" placeholder="请输入您的邮箱..."
v-model="form.email"></tm-input>
<tm-input name="authorUrl" align="right" required title="我的网站" placeholder="请输入您的网址..."
v-model="form.authorUrl"></tm-input>
<view class="pa-24 pl-30 pr-30"><tm-button navtie-type="form" theme="bg-gradient-blue-accent"
block>提交</tm-button></view>
</tm-form>
</view>
</view>
@@ -32,9 +36,9 @@
},
data() {
return {
isComment: true,
params: {
postId: '',
parentId: '',
postName: '',
title: '', // 被回复的标题 type=user =用户名 否则为文章标题
form: '',
formPage: '', // 来自哪个页面
@@ -46,40 +50,39 @@
avatar: '',
authorUrl: '', // 作者主页
content: '', // 评论内容
email: '', // 邮件
parentId: 0,
postId: 0
email: '', // 邮件
postName: ""
}
};
},
computed: {
// 评论游客信息
wxLoginVisitorUser() {
return uni.$tm.vx.getters().getWxLoginInfo;
}
},
onLoad() {
this.params = this.$Route.query;
this.form.postId = this.params.id;
if (this.params.type == 'user') {
this.form.parentId = this.params.parentId;
this.isComment = this.params.isComment;
this.form.postName = this.params.postName;
if (!this.isComment) {
this.fnSetPageTitle('回复用户:' + this.params.title);
} else {
this.form.parentId = 0;
this.fnSetPageTitle(this.params.title);
}
this.form.author = this.wxLoginVisitorUser.nickName;
this.form.avatar = this.wxLoginVisitorUser.avatarUrl;
this.form.email = this.wxLoginVisitorUser.email;
this.form.authorUrl = this.wxLoginVisitorUser.url;
try {
let visitor = uni.getStorageSync('Visitor')
if (visitor) {
visitor = JSON.parse(visitor)
this.form.author = visitor.author;
this.form.avatar = visitor.avatar;
this.form.email = visitor.email;
this.form.authorUrl = visitor.authorUrl;
}
} catch (e) {}
},
methods: {
fnOnSubmit(e) {
console.log('提交评论');
if (e === false) {
return uni.$tm.toast('请检查所有的必填项是否填写完整!');
}
if (this.form.allowNotification && !this.form.email) {
if (!this.form.email) {
return uni.$tm.toast('未填写邮箱地址,将无法接收提醒!');
}
if (this.form.email && !uni.$tm.test.email(this.form.email)) {
@@ -90,36 +93,77 @@
}
this.fnHandle();
},
handleSetVisitor() {
uni.setStorageSync('Visitor', JSON.stringify({
author: this.form.author,
avatar: this.form.avatar,
email: this.form.email,
authorUrl: this.form.authorUrl,
}))
},
fnHandle() {
uni.showLoading({
title: '正在提交...'
});
const _api = {
sheets: this.$httpApi.postSheetsComments,
posts: this.$httpApi.postCommentPost
};
_api[this.params.from](this.form)
.then(res => {
if (res.status == 200) {
uni.$tm.toast('提交成功,待博主审核通过后即可展示!');
// 更新评论者信息
uni.$tm.vx.commit('user/setWxLoginInfo', {
avatarUrl: this.wxLoginVisitorUser.avatarUrl,
nickName: this.form.author,
email: this.form.email,
url: this.form.authorUrl
});
// 清空评论内容
this.form.content = '';
// 触发刷新评论(可能需要评论审核不会有改变)
// uni.$emit(this.params.formPage + '_refresh');
} else {
uni.$tm.toast('操作失败,请重试!');
// 评论
if (this.isComment) {
const commentForm = {
allowNotification: true,
raw: this.form.content,
content: this.form.content,
owner: {
avatar: this.form.avatarUrl,
displayName: this.form.author,
email: this.form.email,
website: this.form.authorUrl,
},
subjectRef: {
group: "content.halo.run",
kind: "Post",
name: this.form.postName,
version: "v1alpha1",
}
}
this.$httpApi.v2.addPostComment(commentForm)
.then(res => {
uni.$tm.toast('日志:提交成功!');
// 更新评论者信息
this.handleSetVisitor();
setTimeout(() => {
uni.navigateBack()
}, 1500)
})
.catch(err => {
uni.$tm.toast("提示:评论失败");
});
return;
}
// 回复
const replyForm = {
allowNotification: true,
raw: this.form.content,
content: this.form.content,
owner: {
avatar: this.form.avatarUrl,
displayName: this.form.author,
email: this.form.email,
website: this.form.authorUrl,
},
quoteReply: this.form.postName
}
this.$httpApi.v2.addPostCommentReply(this.form.postName, replyForm)
.then(res => {
uni.$tm.toast('提示:提交成功!');
// 更新评论者信息
this.handleSetVisitor();
setTimeout(() => {
uni.navigateBack()
}, 1500)
})
.catch(err => {
uni.$tm.toast(err.message);
uni.$tm.toast("提示:回复失败");
});
}
}
+455
View File
@@ -0,0 +1,455 @@
<template>
<view class="app-page card-shadow">
<view v-if="loading != 'success'" class="loading-wrap">
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
</view>
<view v-else class="content" :class="{ 'bg-white': dataList.length !== 0 }">
<!-- 空数据 -->
<view v-if="dataList.length == 0" class="content-empty flex flex-center">
<tm-empty icon="icon-shiliangzhinengduixiang-" label="啊偶,博主还没有朋友呢~"></tm-empty>
</view>
<!-- 如果只有一个分组使用列表的形式 dataList.length == 1 -->
<view v-else class="flex flex-col pb-24">
<block v-for="(link, index) in dataList" :key="index">
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)">
<!-- 色彩版本 -->
<view v-if="!globalAppSettings.links.useSimple" class="info flex pt-24 pb-24 pl-12 pr-12"
:class="{ 'border-b-1': index != dataList.length - 1 }" @click="fnCopyLink(link)">
<view class="link-logo">
<cache-image class="link-logo_img" radius="12rpx" :url="link.spec.logo"
:fileMd5="link.spec.logo" mode="aspectFill"></cache-image>
</view>
<view class="flex flex-col pl-30 info-detail">
<view class="link-card_name text-size-l text-weight-b text-red">
<tm-tags style="margin-right: 12rpx;margin-left: -2rpx;" color="bg-gradient-light-blue-lighten"
:shadow="0" size="s" model="fill">
{{ link.spec.groupName || '暂未分组' }}
</tm-tags>
{{ link.spec.displayName }}
</view>
<view class="poup-tag mt-6" style="font-size: 28rpx;">
站点地址{{ link.spec.url }}
<!-- <tm-tags color="bg-gradient-amber-accent" :shadow="0" size="s" model="fill">
URL{{ link.spec.url }}
</tm-tags>
<tm-tags color=" bg-gradient-light-blue-lighten" :shadow="0" size="s" model="fill">
{{ link.spec.groupName || '暂未分组' }}
</tm-tags> -->
</view>
<view class="link-card_desc text-overflow mt-4" style="font-size: 28rpx;">
博客简介{{ link.spec.description || '这个博主很懒,没写简介~' }}
</view>
</view>
</view>
<!-- 简洁版本 -->
<view v-else class="link-card flex ml-24 mr-24 pt-24 pb-24" @click="fnCopyLink(link)">
<image class="logo shadow-6" :src="link.spec.logo" mode="aspectFill"></image>
<view class="info pl-24">
<view class="name text-size-g">{{ link.spec.displayName }}</view>
<view class="desc mt-12 text-size-s text-grey-darken-1">{{ link.spec.description }}
</view>
<view v-if="false" class="link mt-12 text-size-m text-grey-darken-1">
<text class="iconfont icon-link mr-6 text-size-s"></text>
{{ link.spec.url }}
</view>
</view>
</view>
</tm-translate>
</block>
</view>
<!-- 如果大于一个分组使用联系人的索引形式 dataList.length > 1 -->
<block v-if="false">
<block v-for="(team, index) in dataList" :key="index">
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)">
<view class="grey-lighten-4 text text-size-s text-weight-b px-32 py-12">{{ team.title }}</view>
<block v-for="(link, linkIndex) in team.children" :key="link.metadata.name">
<tm-translate animation-name="fadeUp" :wait="calcAniWait(linkIndex)">
<!-- 色彩版本 -->
<view v-if="!globalAppSettings.links.useSimple"
class="info flex pt-24 pb-24 pl-12 pr-12" :class="{
'border-b-1':
linkIndex != team.children.length - 1 || index == dataList.length - 1
}" @click="fnCopyLink(link)">
<view class="link-logo">
<cache-image class="link-logo_img" radius="12rpx" :url="link.spec.logo"
:fileMd5="link.spec.logo" mode="aspectFill"></cache-image>
</view>
<view class="flex flex-col pl-30 info-detail">
<view class="link-card_name text-size-l text-weight-b text-red">
{{ link.spec.displayName }}
</view>
<view class="poup-tag ml--10 mt-6">
<tm-tags color="bg-gradient-amber-accent" :shadow="0" size="s" model="fill">
ID{{ link.metadata.name }}
</tm-tags>
<tm-tags color=" bg-gradient-light-blue-lighten" :shadow="0" size="s"
model="fill">
{{ link.spec.groupName || '暂未分组' }}
</tm-tags>
</view>
<view class="link-card_desc text-overflow text-size-s mt-4">
博客简介{{ link.spec.description || '这个博主很懒,没写简介~' }}
</view>
</view>
</view>
<!-- 简洁版本 -->
<view v-else class="link-card flex ml-24 mr-24 pt-24 pb-24" @click="fnCopyLink(link)">
<image class="logo shadow-6" :src="link.spec.logo" mode="aspectFill"></image>
<view class="info pl-24">
<view class="name text-size-g">{{ link.spec.displayName }}</view>
<view class="desc mt-12 text-size-s text-grey-darken-1">
{{ link.spec.description }}
</view>
<view v-if="false" class="link mt-12 text-size-m text-grey-darken-1">
<text class="iconfont icon-link mr-6 text-size-s"></text>
{{ link.spec.url }}
</view>
</view>
</view>
</tm-translate>
</block>
</tm-translate>
</block>
</block>
<!-- 返回顶部 -->
<tm-flotbutton color="light-blue" @click="fnToTopPage" size="m" icon="icon-angle-up"></tm-flotbutton>
<!-- 详情弹窗 -->
<tm-poup v-model="detail.show" :width="640" height="auto" position="center" :round="6">
<view class="poup pa-36">
<view class="info flex">
<view class="poup-logo bg-gradient-amber-accent pa-4 shadow-24">
<image class="poup-logo_img" :src="detail.data.logo" mode="aspectFill"></image>
</view>
<view class="pl-24 info-detail">
<view class="poup-name text-size-lg text-weight-b">{{ detail.data.name }}</view>
<view class="poup-tag ml--10">
<tm-tags color="bg-gradient-amber-accent" size="n" model="fill">
ID{{ detail.data.id }}
</tm-tags>
<tm-tags color="bg-gradient-light-blue-lighten" size="n" model="fill">
{{ detail.data.team || '暂未分组' }}
</tm-tags>
</view>
<view class="poup-link text-size-m" @click="fnCopyLink(detail.data)">
<text class="text-orange">{{ detail.data.url }}</text>
<text class="iconfont icon-copy text-size-s ml-6 text-grey"></text>
</view>
</view>
</view>
<view class="poup-desc mt-20">
博客简介{{ detail.data.description || '这个博主很懒,没写简介~' }}
</view>
<!-- 博客预览图 -->
<view class="mt-24">
<tm-images :width="568" :round="2" :src="caclSiteThumbnail(detail.data.url)"
mode="aspectFill"></tm-images>
</view>
</view>
</tm-poup>
<view class="load-text">{{ loadMoreText }}</view>
</view>
</view>
</template>
<script>
import tmSkeleton from '@/tm-vuetify/components/tm-skeleton/tm-skeleton.vue';
import tmTranslate from '@/tm-vuetify/components/tm-translate/tm-translate.vue';
import tmFlotbutton from '@/tm-vuetify/components/tm-flotbutton/tm-flotbutton.vue';
import tmTags from '@/tm-vuetify/components/tm-tags/tm-tags.vue';
import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
import tmImages from '@/tm-vuetify/components/tm-images/tm-images.vue';
import tmPoup from '@/tm-vuetify/components/tm-poup/tm-poup.vue';
import {
GetRandomNumberByRange
} from '@/utils/random.js';
export default {
components: {
tmSkeleton,
tmTranslate,
tmFlotbutton,
tmTags,
tmEmpty,
tmImages,
tmPoup
},
data() {
return {
loading: 'loading',
queryParams: {
size: 10,
page: 1
},
result: {},
detail: {
show: false,
data: {}
},
isLoadMore: false,
loadMoreText: '',
dataList: [],
cacheDataList: []
};
},
computed: {
caclSiteThumbnail(val) {
return val => {
if (!val) return '';
if (val.charAt(val.length - 1) != '/') {
val = val + '/';
}
return 'https://image.thum.io/get/width/1000/crop/800/' + val;
};
}
},
onLoad() {
this.fnSetPageTitle('朋友圈');
this.fnGetData();
},
onPullDownRefresh() {
this.isLoadMore = false;
this.queryParams.page = 1;
this.dataList = []
this.cacheDataList = []
this.fnGetData();
},
onReachBottom(e) {
if (this.result.hasNext) {
this.queryParams.page += 1;
this.isLoadMore = true;
this.fnGetData();
} else {
uni.showToast({
icon: 'none',
title: '没有更多数据了'
});
}
},
methods: {
fnRandomColor() {
const _r = GetRandomNumberByRange(0, this.$haloConfig.colors.length - 1);
return this.$haloConfig.colors[_r];
},
fnGetData() {
if (!this.isLoadMore) {
this.loading = 'loading';
}
this.loadMoreText = '';
this.$httpApi.v2
.getFriendLinkList(this.queryParams)
.then(res => {
console.log('请求结果:');
console.log(res);
this.result = res;
const list = res.items.map(item => {
item.spec.logo = this.$utils.checkAvatarUrl(item.spec.logo)
return item;
})
this.dataList = this.dataList.concat(list);
// this.cacheDataList = this.cacheDataList.concat(list);
// this.dataList = this.handleGroup(this.cacheDataList).reverse();
setTimeout(() => {
this.loading = 'success';
this.loadMoreText = res.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
}, 500);
})
.catch(err => {
console.error(err);
this.loading = 'error';
this.loadMoreText = '加载失败,请下拉刷新!';
})
.finally(() => {
setTimeout(() => {
uni.hideLoading();
uni.stopPullDownRefresh();
}, 500);
});
},
handleGroup(list) {
const group = {}
list.forEach(item => {
if (group[item.spec.groupName]) {
group[item.spec.groupName].children.push(item)
} else {
group[item.spec.groupName] = {
title: item.spec.groupName,
children: [item]
}
}
})
return Object.keys(group).map(key => {
const {
title,
children = []
} = group[key]
return {
title,
children
}
})
},
fnOnLinkEvent(link) {
this.detail.data = link;
this.detail.show = true;
},
fnCopyLink(link) {
uni.setClipboardData({
data: `${link.name}:${link.url}`,
showToast: false,
success: () => {
uni.showToast({
icon: 'none',
title: '链接复制成功!'
});
},
fail: () => {
uni.showToast({
icon: 'none',
title: '复制失败!'
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
.app-page {
width: 100vw;
min-height: 100vh;
display: flex;
flex-direction: column;
background-color: #fafafd;
}
.loading-wrap {
padding: 24rpx;
min-height: 100vh;
}
.content {
padding: 0 24rpx;
padding-top: 24rpx;
.content-empty {
height: 60vh;
display: flex;
align-items: center;
justify-content: center;
}
}
.link-card {
border-bottom: 2rpx solid #f5f5f5;
background-color: #ffffff;
&.one {
border: 0;
box-shadow: 0rpx 2rpx 24rpx 0rpx rgba(0, 0, 0, 0.03);
.logo {
box-shadow: 0rpx 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
}
.logo {
// width: 126rpx;
// height: 126rpx;
width: 80rpx;
height: 80rpx;
border-radius: 12rpx;
border: 6rpx solid #ffffff;
box-shadow: none;
}
.info {
width: 0;
flex-grow: 1;
.name {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #303133;
font-size: 30rpx;
font-weight: bold;
}
.desc {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #303133;
font-size: 28rpx;
}
}
}
.link-card_name {
// color: #303133;
// color: #0080fe;
}
.link-card_desc {
font-size: 24rpx;
line-height: 1.6;
color: #303133;
}
.link-logo {
width: 140rpx;
height: 140rpx;
&_img {
width: 100%;
height: 100%;
}
}
.poup-logo {
width: 140rpx;
height: 140rpx;
border-radius: 50%;
&_img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.info-detail {
width: 0;
flex-grow: 1;
justify-content: center;
}
.poup-desc {
font-size: 28rpx;
line-height: 1.6;
color: #555 !important;
}
.preview-site {
width: 100%;
height: 300rpx;
}
</style>
-257
View File
@@ -1,257 +0,0 @@
<template>
<view class="app-page">
<view v-if="loading != 'success'" class="loading-wrap pa-24">
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
<tm-skeleton model="listAvatr"></tm-skeleton>
</view>
<!-- 内容区域 -->
<view v-else class="app-page-content pa-24" :class="{ 'bg-white': dataList.length !== 0 }">
<view v-if="dataList.length == 0" class="content-empty flex flex-center">
<!-- 空布局 -->
<tm-empty icon="icon-shiliangzhinengduixiang-" label="啊偶,博主还没有留言~"></tm-empty>
</view>
<block v-else>
<block v-for="(item, index) in dataList" :key="index">
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)">
<!-- 列表项 -->
<comment-item class="mb-12" :isChild="false" :comment="item" :postId="sheetId" :useSolid="false" @on-copy="fnCopyContent" @on-comment="fnToComment" @on-detail="fnOnShowCommentDetail"></comment-item>
</tm-translate>
</block>
<tm-flotbutton :offset="[16, 80]" @click="fnToTopPage" size="m" color="light-blue" icon="icon-angle-up"></tm-flotbutton>
<view class="load-text">{{ loadMoreText }}</view>
</block>
<tm-flotbutton actions-pos="left" :show-text="true" color="bg-gradient-orange-accent" @click="fnToComment(null)"></tm-flotbutton>
</view>
<!-- 评论详情 -->
<tm-poup v-model="commentDetail.show" height="auto" :round="6" :over-close="true" position="bottom">
<view class="pa-24">
<view class="poup-head pb-24">
<view class="poup-title text-align-center text-size-g text-weight-b mb-32">留言详情</view>
<comment-item :useActions="false" :isChild="false" :comment="commentDetail.comment" :postId="sheetId"></comment-item>
</view>
<scroll-view :scroll-y="true" class="poup-body">
<view v-if="commentDetail.loading != 'success'" class="poup-loading-wrap flex flex-center">
<view v-if="commentDetail.loading == 'loading'" class="loading flex flex-center flex-col">
<text class="e-loading-icon iconfont icon-loading text-blue"></text>
<view class="text-size-n text-grey-lighten-1 py-12 mt-12">加载中请稍等...</view>
</view>
<view v-else-if="commentDetail.loading == 'error'" class="error">
<tm-empty icon="icon-wind-cry" label="加载失败">
<tm-button theme="bg-gradient-light-blue-accent" size="m" @click="fnGetChildComments()">刷新试试</tm-button>
</tm-empty>
</view>
</view>
<block v-else>
<view v-if="commentDetail.list.length == 0" class="poup-empty flex flex-center">
<tm-empty icon="icon-shiliangzhinengduixiang-" label="没有更多评论啦~"></tm-empty>
</view>
<block v-else>
<comment-item v-for="(comment, index) in commentDetail.list" :useSolid="false" :useActions="false" :key="index" :isChild="false" :comment="comment" :postId="sheetId"></comment-item>
</block>
</block>
</scroll-view>
</view>
</tm-poup>
</view>
</template>
<script>
import AppKeys from '@/config/keys.js';
import SheetConfig from '@/config/sheets.config.js';
import tmSkeleton from '@/tm-vuetify/components/tm-skeleton/tm-skeleton.vue';
import tmFlotbutton from '@/tm-vuetify/components/tm-flotbutton/tm-flotbutton.vue';
import tmTranslate from '@/tm-vuetify/components/tm-translate/tm-translate.vue';
import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
import tmPoup from '@/tm-vuetify/components/tm-poup/tm-poup.vue';
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
import commentItem from '@/components/comment-item/comment-item.vue';
export default {
components: {
tmSkeleton,
tmFlotbutton,
tmTranslate,
tmEmpty,
tmPoup,
tmButton,
commentItem
},
data() {
return {
loading: 'loading',
queryParams: {
size: 10,
page: 0
},
result: null,
dataList: [],
isLoadMore: false,
loadMoreText: '加载中...',
sheetId: SheetConfig[AppKeys.SHEET_LEAVING],
commentDetail: {
loading: 'loading',
show: false,
comment: {},
postId: undefined,
list: []
}
};
},
onLoad() {
this.fnSetPageTitle('留言板');
},
created() {
this.fnGetData();
uni.$on('leaving_refresh', () => {
this.fnGetData();
});
},
onPullDownRefresh() {
this.isLoadMore = false;
this.queryParams.page = 0;
this.fnGetData();
},
onReachBottom(e) {
if (this.result.hasNext) {
this.queryParams.page += 1;
this.isLoadMore = true;
this.fnGetData();
} else {
uni.showToast({
icon: 'none',
title: '没有更多数据了'
});
}
},
methods: {
fnGetData() {
// uni.showLoading({
// mask: true,
// title: '加载中...'
// });
// 设置状态为加载中
if (!this.isLoadMore) {
this.loading = 'loading';
}
this.loadMoreText = '加载中...';
this.$httpApi
.getSheetsCommentsTreeBySheetId(this.sheetId, this.queryParams)
.then(res => {
if (res.status == 200) {
this.loading = 'success';
// return;
this.loadMoreText = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
// 处理数据
this.result = res.data;
if (this.isLoadMore) {
this.dataList = this.dataList.concat(res.data.content);
} else {
this.dataList = res.data.content;
}
} else {
this.loading = 'error';
this.loadMoreText = '加载失败,请下拉刷新!';
}
})
.catch(err => {
console.error(err);
this.loading = 'error';
this.loadMoreText = '加载失败,请下拉刷新!';
})
.finally(() => {
setTimeout(() => {
uni.hideLoading();
uni.stopPullDownRefresh();
}, 500);
});
},
fnToComment(data) {
let _comment = {};
if (data) {
_comment = {
id: this.sheetId,
parentId: data.comment.id,
title: data.comment.author,
from: 'sheets',
formPage: 'leaving',
type: 'user'
};
} else {
_comment = {
id: this.sheetId,
parentId: 0,
title: '留言板留言',
from: 'sheets',
formPage: 'leaving',
type: 'post'
};
}
uni.$tm.vx.commit('comment/setCommentInfo', _comment);
this.$Router.push({
path: '/pagesA/comment/comment',
query: _comment
});
},
fnCopyContent(content) {
uni.$tm.u.setClipboardData(content);
uni.$tm.toast('内容已复制成功!');
},
fnOnShowCommentDetail(comment) {
this.commentDetail.comment = comment;
this.commentDetail.list = [];
this.commentDetail.show = true;
this.fnGetChildComments();
},
fnGetChildComments() {
this.commentDetail.loading = 'loading';
this.$httpApi
.getSheetsChildrenCommentList(this.sheetId, this.commentDetail.comment.id, {})
.then(res => {
if (res.status == 200) {
this.commentDetail.loading = 'success';
this.commentDetail.list = res.data;
} else {
this.commentDetail.loading = 'error';
}
})
.catch(err => {
this.commentDetail.loading = 'error';
});
}
}
};
</script>
<style lang="scss" scoped>
.app-page {
width: 100vw;
display: flex;
flex-direction: column;
background-color: #fafafd;
}
.app-page-content {
box-sizing: border-box;
// box-shadow: 0rpx 0rpx 24rpx rgba(0, 0, 0, 0.05);
}
.content-empty {
width: 100%;
height: 60vh;
}
.loading-wrap {
box-sizing: border-box;
padding: 24rpx;
}
</style>
+270 -259
View File
@@ -14,43 +14,16 @@
<text class="text-grey text-size-xs px-10 ml-12">应用以及文章列表布局设置</text>
</view>
<view class="sheet-content">
<tm-pickers
title="请选择首页布局"
btn-color="light-blue"
:default-value.sync="homeLayout.selectDefault"
rang-key="name"
:list="homeLayout.list"
@confirm="fnOnHomeLayoutConfirm"
>
<tm-input
name="status"
required
title="首页文章布局"
placeholder="请选择首页文章布局"
disabled
align="right"
:value="homeLayout.selectLabel"
right-icon="icon-angle-right"
></tm-input>
<tm-pickers title="请选择首页布局" btn-color="light-blue" :default-value.sync="homeLayout.selectDefault"
rang-key="name" :list="homeLayout.list" @confirm="fnOnHomeLayoutConfirm">
<tm-input name="status" required title="首页文章布局" placeholder="请选择首页文章布局" disabled align="right"
:value="homeLayout.selectLabel" right-icon="icon-angle-right"></tm-input>
</tm-pickers>
<tm-pickers
title="请选择文章卡片样式"
btn-color="light-blue"
:default-value.sync="articleCardStyle.selectDefault"
rang-key="name"
:list="articleCardStyle.list"
@confirm="fnOnArticleCardStyleConfirm"
>
<tm-input
name="status"
required
title="文章卡片样式"
placeholder="请选择文章卡片样式"
disabled
align="right"
:value="articleCardStyle.selectLabel"
right-icon="icon-angle-right"
></tm-input>
<tm-pickers title="请选择文章卡片样式" btn-color="light-blue"
:default-value.sync="articleCardStyle.selectDefault" rang-key="name"
:list="articleCardStyle.list" @confirm="fnOnArticleCardStyleConfirm">
<tm-input name="status" required title="文章卡片样式" placeholder="请选择文章卡片样式" disabled align="right"
:value="articleCardStyle.selectLabel" right-icon="icon-angle-right"></tm-input>
</tm-pickers>
</view>
</tm-sheet>
@@ -73,14 +46,16 @@
</view>
<view class="sheet-content">
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m ">图库瀑布流模式</text>
<tm-switch v-model="appSettings.gallery.useWaterfull" color="light-blue" :text="['是', '否']"></tm-switch>
<text class="text-size-m">图库瀑布流模式</text>
<tm-switch v-model="appSettings.gallery.useWaterfull" color="light-blue"
:text="['是', '否']"></tm-switch>
</view>
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m ">友链简洁模式</text>
<tm-switch v-model="appSettings.links.useSimple" color="light-blue" :text="['是', '否']"></tm-switch>
<text class="text-size-m">友链简洁模式</text>
<tm-switch v-model="appSettings.links.useSimple" color="light-blue"
:text="['是', '否']"></tm-switch>
</view>
<view class="mx-32 mt-24 mb-0 border-b-1 pb-24 flex-between">
<!-- <view class="mx-32 mt-24 mb-0 border-b-1 pb-24 flex-between">
<text class="text-size-m">启用评论弹幕</text>
<tm-switch v-model="appSettings.barrage.use" color="light-blue" :text="['是', '否']"></tm-switch>
</view>
@@ -102,31 +77,27 @@
:value="barrage.selectLabel"
right-icon="icon-angle-right"
></tm-input>
</tm-pickers>
</tm-pickers> -->
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m">是否圆形头像</text>
<tm-switch v-model="appSettings.isAvatarRadius" color="light-blue" :text="['是', '否']"></tm-switch>
<tm-switch v-model="appSettings.isAvatarRadius" color="light-blue"
:text="['是', '否']"></tm-switch>
</view>
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m ">轮播图指示器</text>
<tm-switch v-model="appSettings.banner.useDot" color="light-blue" :text="['是', '否']"></tm-switch>
<tm-switch v-model="appSettings.banner.useDot" color="light-blue"
:text="['是', '否']"></tm-switch>
</view>
<view v-if="appSettings.banner.useDot" class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m ">轮播图指示器位置</text>
<tm-groupradio name="dotPosition" @change="fnOnBannerDotChange">
<tm-radio
:name="item.name"
:size="28"
color="light-blue"
v-for="(item, index) in dotPositionList"
:key="index"
v-model="item.checked"
:label="item.name"
></tm-radio>
<tm-radio :name="item.name" :size="28" color="light-blue"
v-for="(item, index) in dotPositionList" :key="index" v-model="item.checked"
:label="item.name"></tm-radio>
</tm-groupradio>
</view>
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<!-- <view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m">显示完整统计</text>
<tm-switch v-model="appSettings.about.showAllCount" color="light-blue" :text="['是', '否']"></tm-switch>
</view>
@@ -134,10 +105,10 @@
<text class="text-size-m ">链接直接打开</text>
<tm-switch v-model="appSettings.contact.isLinkCopy" color="light-blue" :text="['是', '否']"></tm-switch>
</view>
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
<view v-if="false" class="mx-32 my-24 border-b-1 pb-24 flex-between">
<text class="text-size-m ">显示后台入口</text>
<tm-switch v-model="appSettings.about.showAdmin" color="light-blue" :text="['是', '否']"></tm-switch>
</view>
</view> -->
</view>
</tm-sheet>
</tm-form>
@@ -152,221 +123,261 @@
</template>
<script>
import { _DefaultAppSettings } from '@/utils/app.js';
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
import tmForm from '@/tm-vuetify/components/tm-form/tm-form.vue';
import tmPickers from '@/tm-vuetify/components/tm-pickers/tm-pickers.vue';
import tmInput from '@/tm-vuetify/components/tm-input/tm-input.vue';
import tmSwitch from '@/tm-vuetify/components/tm-switch/tm-switch.vue';
import tmSheet from '@/tm-vuetify/components/tm-sheet/tm-sheet.vue';
import tmGroupradio from '@/tm-vuetify/components/tm-groupradio/tm-groupradio.vue';
import tmRadio from '@/tm-vuetify/components/tm-radio/tm-radio.vue';
import {
_DefaultAppSettings
} from '@/utils/app.js';
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
import tmForm from '@/tm-vuetify/components/tm-form/tm-form.vue';
import tmPickers from '@/tm-vuetify/components/tm-pickers/tm-pickers.vue';
import tmInput from '@/tm-vuetify/components/tm-input/tm-input.vue';
import tmSwitch from '@/tm-vuetify/components/tm-switch/tm-switch.vue';
import tmSheet from '@/tm-vuetify/components/tm-sheet/tm-sheet.vue';
import tmGroupradio from '@/tm-vuetify/components/tm-groupradio/tm-groupradio.vue';
import tmRadio from '@/tm-vuetify/components/tm-radio/tm-radio.vue';
export default {
components: {
tmButton,
tmForm,
tmPickers,
tmInput,
tmSwitch,
tmSheet,
tmGroupradio,
tmRadio
},
data() {
return {
isBlackTheme: false,
loading: true,
appSettings: {},
isSaved: true,
firstLoad: true,
homeLayout: {
list: [{ name: '一行一列', value: 'h_row_col1' }, { name: '一行两列', value: 'h_row_col2' }],
selectDefault: ['一行一列'],
selectLabel: '一行一列',
selectValue: 'h_row_col1'
},
articleCardStyle: {
list: [
{ name: '左图右文', value: 'lr_image_text' },
{ name: '左文右图', value: 'lr_text_image' },
{ name: '上图下文', value: 'tb_image_text' },
{ name: '上文下图', value: 'tb_text_image' },
{ name: '只有文字', value: 'only_text' }
],
selectDefault: ['左图右文'],
selectLabel: '左图右文',
selectValue: 'lr_image_text'
},
dotPositionList: [{ name: '右边', value: 'right', checked: true }, { name: '下边', value: 'bottom', checked: false }],
barrage: {
list: [{ name: '顶部', value: 'rightToLeft' }, { name: '左下', value: 'leftBottom' }],
selectDefault: ['顶部'],
selectLabel: '顶部',
selectValue: 'rightToLeft'
}
};
},
export default {
components: {
tmButton,
tmForm,
tmPickers,
tmInput,
tmSwitch,
tmSheet,
tmGroupradio,
tmRadio
},
data() {
return {
isBlackTheme: false,
loading: true,
appSettings: {},
isSaved: true,
firstLoad: true,
homeLayout: {
list: [{
name: '一行一列',
value: 'h_row_col1'
}, {
name: '一行两列',
value: 'h_row_col2'
}],
selectDefault: ['一行一列'],
selectLabel: '一行一列',
selectValue: 'h_row_col1'
},
articleCardStyle: {
list: [{
name: '左图右文',
value: 'lr_image_text'
},
{
name: '左文右图',
value: 'lr_text_image'
},
{
name: '上图下文',
value: 'tb_image_text'
},
{
name: '上文下图',
value: 'tb_text_image'
},
{
name: '只有文字',
value: 'only_text'
}
],
selectDefault: ['左图右文'],
selectLabel: '左图右文',
selectValue: 'lr_image_text'
},
dotPositionList: [{
name: '右边',
value: 'right',
checked: true
}, {
name: '下边',
value: 'bottom',
checked: false
}],
barrage: {
list: [{
name: '顶部',
value: 'rightToLeft'
}, {
name: '左下',
value: 'leftBottom'
}],
selectDefault: ['顶部'],
selectLabel: '顶部',
selectValue: 'rightToLeft'
}
};
},
watch: {
appSettings: {
deep: true,
handler() {
if (this.firstLoad) {
this.firstLoad = false;
} else {
this.isSaved = false;
watch: {
appSettings: {
deep: true,
handler() {
if (this.firstLoad) {
this.firstLoad = false;
} else {
this.isSaved = false;
}
}
}
}
},
},
onLoad(e) {
this.fnSetPageTitle('应用设置');
},
created() {
this.appSettings = Object.assign({}, _DefaultAppSettings, uni.$tm.vx.getters().getSettings);
this.fnHandleFormatSelect();
uni.showLoading({
title: '加载中...',
mask: true
});
setTimeout(() => {
this.loading = false;
uni.hideLoading();
}, 500);
},
onLoad(e) {
this.fnSetPageTitle('应用设置');
},
created() {
this.appSettings = Object.assign({}, _DefaultAppSettings, uni.$tm.vx.getters().getSettings);
this.fnHandleFormatSelect();
uni.showLoading({
title: '加载中...',
mask: true
});
setTimeout(() => {
this.loading = false;
uni.hideLoading();
}, 500);
},
methods: {
// 统一处理选择框的内容
fnHandleFormatSelect() {
methods: {
// 统一处理选择框的内容
fnHandleFormatSelect() {
// 首页布局
const _homeLayout = this.fnFindObjInList(this.homeLayout.list, 'value', this.appSettings.layout.home);
this.homeLayout.selectDefault = [_homeLayout.name];
this.homeLayout.selectLabel = _homeLayout.name;
this.homeLayout.selectValue = _homeLayout.value;
const _articleCardStyle = this.fnFindObjInList(this.articleCardStyle.list, 'value', this.appSettings.layout
.cardType);
this.articleCardStyle.selectDefault = [_articleCardStyle.name];
this.articleCardStyle.selectLabel = _articleCardStyle.name;
this.articleCardStyle.selectValue = _articleCardStyle.value;
const _barrage = this.fnFindObjInList(this.barrage.list, 'value', this.appSettings.barrage.type);
this.barrage.selectDefault = [_barrage.name];
this.barrage.selectLabel = _barrage.name;
this.barrage.selectValue = _barrage.value;
},
// 在集合中找匹配的对象
fnFindObjInList(list, key, value) {
return list.find(x => x[key] == value);
},
fnOnBannerDotChange(e) {
const _select = e[0];
if (_select.index == 0 && _select.checked) {
this.appSettings.banner.dotPosition = 'right';
}
if (_select.index == 1 && _select.checked) {
this.appSettings.banner.dotPosition = 'bottom';
}
},
// 首页布局
const _homeLayout = this.fnFindObjInList(this.homeLayout.list, 'value', this.appSettings.layout.home);
this.homeLayout.selectDefault = [_homeLayout.name];
this.homeLayout.selectLabel = _homeLayout.name;
this.homeLayout.selectValue = _homeLayout.value;
const _articleCardStyle = this.fnFindObjInList(this.articleCardStyle.list, 'value', this.appSettings.layout.cardType);
this.articleCardStyle.selectDefault = [_articleCardStyle.name];
this.articleCardStyle.selectLabel = _articleCardStyle.name;
this.articleCardStyle.selectValue = _articleCardStyle.value;
const _barrage = this.fnFindObjInList(this.barrage.list, 'value', this.appSettings.barrage.type);
this.barrage.selectDefault = [_barrage.name];
this.barrage.selectLabel = _barrage.name;
this.barrage.selectValue = _barrage.value;
},
// 在集合中找匹配的对象
fnFindObjInList(list, key, value) {
return list.find(x => x[key] == value);
},
fnOnBannerDotChange(e) {
const _select = e[0];
if (_select.index == 0 && _select.checked) {
this.appSettings.banner.dotPosition = 'right';
}
if (_select.index == 1 && _select.checked) {
this.appSettings.banner.dotPosition = 'bottom';
}
},
// 首页布局
fnOnHomeLayoutConfirm(e) {
const _select = e[0].data;
this.homeLayout.selectDefault = [_select.name];
this.homeLayout.selectLabel = _select.name;
this.homeLayout.selectValue = _select.value;
this.appSettings.layout.home = _select.value;
},
// 文章卡片样式
fnOnArticleCardStyleConfirm(e) {
const _select = e[0].data;
this.articleCardStyle.selectDefault = [_select.name];
this.articleCardStyle.selectLabel = _select.name;
this.articleCardStyle.selectValue = _select.value;
this.appSettings.layout.cardType = _select.value;
},
// 弹幕设置
fnOnBarrageConfirm(e) {
const _select = e[0].data;
this.barrage.selectDefault = [_select.name];
this.barrage.selectLabel = _select.name;
this.barrage.selectValue = _select.value;
this.appSettings.barrage.type = _select.value;
},
// 保存
fnOnSave() {
this.isSaved = true;
this.$tm.vx.commit('setting/setSettings', this.appSettings);
uni.$tm.toast('保存成功,部分设置在重启后生效!');
},
// 使用默认配置
fnOnSaveDefault() {
uni.$eShowModal({
title: '提示',
content: '您确定要恢复为默认的设置吗?',
showCancel: true,
cancelText: '否',
cancelColor: '#999999',
confirmText: '是',
confirmColor: '#03a9f4'
})
.then(res => {
this.isSaved = true;
uni.$tm.vx.actions('setting/updateDefaultAppSettings');
uni.$tm.toast('系统设置已恢复为默认配置,部分设置在重启后生效!');
})
.catch(err => {});
},
fnOnBack() {
if (this.isSaved) {
uni.navigateBack();
return;
}
uni.$eShowModal({
title: '提示',
content: '您当前可能有未保存的数据,确定返回吗?',
showCancel: true,
cancelText: '否',
cancelColor: '#999999',
confirmText: '是',
confirmColor: '#03a9f4'
})
.then(res => {
fnOnHomeLayoutConfirm(e) {
const _select = e[0].data;
this.homeLayout.selectDefault = [_select.name];
this.homeLayout.selectLabel = _select.name;
this.homeLayout.selectValue = _select.value;
this.appSettings.layout.home = _select.value;
},
// 文章卡片样式
fnOnArticleCardStyleConfirm(e) {
const _select = e[0].data;
this.articleCardStyle.selectDefault = [_select.name];
this.articleCardStyle.selectLabel = _select.name;
this.articleCardStyle.selectValue = _select.value;
this.appSettings.layout.cardType = _select.value;
},
// 弹幕设置
fnOnBarrageConfirm(e) {
const _select = e[0].data;
this.barrage.selectDefault = [_select.name];
this.barrage.selectLabel = _select.name;
this.barrage.selectValue = _select.value;
this.appSettings.barrage.type = _select.value;
},
// 保存
fnOnSave() {
this.isSaved = true;
this.$tm.vx.commit('setting/setSettings', this.appSettings);
uni.$tm.toast('保存成功,部分设置在重启后生效!');
},
// 使用默认配置
fnOnSaveDefault() {
uni.$eShowModal({
title: '提示',
content: '您确定要恢复为默认的设置吗?',
showCancel: true,
cancelText: '否',
cancelColor: '#999999',
confirmText: '是',
confirmColor: '#03a9f4'
})
.then(res => {
this.isSaved = true;
uni.$tm.vx.actions('setting/updateDefaultAppSettings');
uni.$tm.toast('系统设置已恢复为默认配置,部分设置在重启后生效!');
})
.catch(err => {});
},
fnOnBack() {
if (this.isSaved) {
uni.navigateBack();
this.isSaved = true;
})
.catch(err => {});
return;
}
uni.$eShowModal({
title: '提示',
content: '您当前可能有未保存的数据,确定返回吗?',
showCancel: true,
cancelText: '否',
cancelColor: '#999999',
confirmText: '是',
confirmColor: '#03a9f4'
})
.then(res => {
uni.navigateBack();
this.isSaved = true;
})
.catch(err => {});
}
}
}
};
};
</script>
<style scoped lang="scss">
.app-page {
box-sizing: border-box;
padding-bottom: 120rpx;
.btn-bar {
width: 100vw;
position: fixed;
left: 0;
bottom: 0;
.app-page {
box-sizing: border-box;
padding: 24rpx;
gap: 0 24rpx;
box-shadow: 0rpx -6rpx 24rpx rgba(0, 0, 0, 0.03);
padding-bottom: 120rpx;
.btn-bar {
width: 100vw;
position: fixed;
left: 0;
bottom: 0;
box-sizing: border-box;
padding: 24rpx;
gap: 0 24rpx;
box-shadow: 0rpx -6rpx 24rpx rgba(0, 0, 0, 0.03);
}
}
}
.required {
position: relative;
padding-left: 18rpx;
&:before {
content: '*';
position: absolute;
left: -4rpx;
top: 50%;
transform: translateY(-50%);
font-size: 34rpx;
color: rgba(244, 67, 54, 1);
.required {
position: relative;
padding-left: 18rpx;
&:before {
content: '*';
position: absolute;
left: -4rpx;
top: 50%;
transform: translateY(-50%);
font-size: 34rpx;
color: rgba(244, 67, 54, 1);
}
}
}
</style>
</style>
+19 -15
View File
@@ -7,11 +7,13 @@
<tm-skeleton model="listAvatr"></tm-skeleton>
</view>
<block v-else>
<view class="empty" v-if="dataList.length == 0"><tm-empty icon="icon-shiliangzhinengduixiang-" label="该标签下暂无文章"></tm-empty></view>
<view class="empty" v-if="dataList.length == 0"><tm-empty icon="icon-shiliangzhinengduixiang-"
label="该标签下暂无文章"></tm-empty></view>
<block v-else>
<block v-for="(article, index) in dataList" :key="article.createTime">
<block v-for="(article, index) in dataList" :key="article.metadata.name">
<!-- 文章卡片 -->
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)"><article-card :article="article" @on-click="fnToArticleDetail"></article-card></tm-translate>
<tm-translate animation-name="fadeUp" :wait="calcAniWait(index)">
<article-card :article="article" @on-click="fnToArticleDetail"></article-card></tm-translate>
</block>
<view class="load-text">{{ loadMoreText }}</view>
</block>
@@ -39,10 +41,11 @@
return {
loading: 'loading',
queryParams: {
name: "",
size: 10,
page: 0
},
slug: '',
name: '',
pageTitle: '加载中...',
result: null,
dataList: [],
@@ -52,8 +55,9 @@
},
onLoad(e) {
this.slug = e.slug;
this.pageTitle = e.name;
this.name = e.name;
this.queryParams.name = this.name;
this.pageTitle = e.title;
this.fnGetData();
},
onPullDownRefresh() {
@@ -62,7 +66,7 @@
this.fnGetData();
},
onReachBottom(e) {
if (this.result.hasNext) {
if (this.result && this.result.hasNext) {
this.queryParams.page += 1;
this.isLoadMore = true;
this.fnGetData();
@@ -84,17 +88,17 @@
this.loading = 'loading';
}
this.loadMoreText = '加载中...';
this.$httpApi
.getTagPostsList(this.slug, this.queryParams)
this.$httpApi.v2
.getPostByTagName(this.name, this.queryParams)
.then(res => {
this.fnSetPageTitle(`标签:${this.pageTitle} (共${res.data.total}篇)`);
this.result = res.data;
this.fnSetPageTitle(`${this.pageTitle} (共${res.total}篇)`);
this.result = res;
if (this.isLoadMore) {
this.dataList = this.dataList.concat(res.data.content);
this.dataList = this.dataList.concat(res.items);
} else {
this.dataList = res.data.content;
this.dataList = res.items;
}
this.loadMoreText = res.data.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
this.loadMoreText = res.hasNext ? '上拉加载更多' : '呜呜,没有更多数据啦~';
setTimeout(() => {
this.loading = 'success';
}, 500);
@@ -114,7 +118,7 @@
//跳转文章详情
fnToArticleDetail(article) {
uni.navigateTo({
url: '/pagesA/article-detail/article-detail?articleId=' + article.id,
url: '/pagesA/article-detail/article-detail?name=' + article.metadata.name,
animationType: 'slide-in-right'
});
}