feat: 新增文章点赞功能

This commit is contained in:
小莫唐尼 2024-11-06 19:23:13 +08:00
parent 7c15c84dba
commit e19b107ed0
3 changed files with 1367 additions and 1336 deletions

View File

@ -143,7 +143,7 @@ export default {
* 获取友链分组 * 获取友链分组
*/ */
getFriendLinkGroupList: (params) => { getFriendLinkGroupList: (params) => {
return HttpHandler.Get(`/apis/core.halo.run/v1alpha1/linkgroups`, params,{ return HttpHandler.Get(`/apis/core.halo.run/v1alpha1/linkgroups`, params, {
custom: { custom: {
systemToken: HaloTokenConfig.systemToken systemToken: HaloTokenConfig.systemToken
} }
@ -205,12 +205,22 @@ export default {
* 获取二维码信息 * 获取二维码信息
*/ */
getQRCodeInfo: (key) => { getQRCodeInfo: (key) => {
return HttpHandler.Get(`/apis/api.uni.uhalo.pro/v1alpha1/plugins/plugin-uni-halo/getQRCodeInfo/${key}`, null,) return HttpHandler.Get(`/apis/api.uni.uhalo.pro/v1alpha1/plugins/plugin-uni-halo/getQRCodeInfo/${key}`,
null, {})
}, },
/** /**
* 获取二维码图片 * 获取二维码图片
*/ */
getQRCodeImg: (postId) => { getQRCodeImg: (postId) => {
return HttpHandler.Get(`/apis/api.uni.uhalo.pro/v1alpha1/plugins/plugin-uni-halo/getQRCodeImg/${postId}`, null,) return HttpHandler.Get(`/apis/api.uni.uhalo.pro/v1alpha1/plugins/plugin-uni-halo/getQRCodeImg/${postId}`,
null, {})
},
/**
* 点赞
* @param {*} data ={group, plural, name}
*/
submitUpvote(data) {
return HttpHandler.Post(`/apis/api.halo.run/v1alpha1/trackers/upvote`, data, {})
} }
} }

View File

@ -81,7 +81,7 @@
:loading-img="markdownConfig.loadingGif" :scroll-table="true" :selectable="true" :loading-img="markdownConfig.loadingGif" :scroll-table="true" :selectable="true"
:tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle" :tag-style="markdownConfig.tagStyle" :container-style="markdownConfig.containStyle"
:content="result.content.raw" :markdown="true" :showLineNumber="true" :showLanguageName="true" :content="result.content.raw" :markdown="true" :showLineNumber="true" :showLanguageName="true"
:copyByLongPress="true" /> :copyByLongPress="true"/>
<tm-more v-if="showValidVisitMore" :disabled="true" :maxHeight="1" :isRemovBar="true" <tm-more v-if="showValidVisitMore" :disabled="true" :maxHeight="1" :isRemovBar="true"
@click="showValidVisitMorePop()"> @click="showValidVisitMorePop()">
<view class="text-size-n pa-24"> <view class="text-size-n pa-24">
@ -131,7 +131,7 @@
<!-- 返回顶部 --> <!-- 返回顶部 -->
<tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent" <tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent"
@click="fnToTopPage()"></tm-flotbutton> @click="fnToTopPage()"></tm-flotbutton>
<tm-flotbutton :actions="flotButtonActions" actions-pos="left" :show-text="true" <tm-flotbutton :actions="flotButtonActions" :click-actions-hiden="false" actions-pos="left" :show-text="true"
color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton> color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton>
</block> </block>
@ -215,28 +215,27 @@
</template> </template>
<script> <script>
import MarkdownConfig from '@/common/markdown/markdown.config.js'; import MarkdownConfig from '@/common/markdown/markdown.config.js';
import tmSkeleton from '@/tm-vuetify/components/tm-skeleton/tm-skeleton.vue'; import tmSkeleton from '@/tm-vuetify/components/tm-skeleton/tm-skeleton.vue';
import tmPoup from '@/tm-vuetify/components/tm-poup/tm-poup.vue'; import tmPoup from '@/tm-vuetify/components/tm-poup/tm-poup.vue';
import tmFlotbutton from '@/tm-vuetify/components/tm-flotbutton/tm-flotbutton.vue'; import tmFlotbutton from '@/tm-vuetify/components/tm-flotbutton/tm-flotbutton.vue';
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue'; import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue'; import tmEmpty from '@/tm-vuetify/components/tm-empty/tm-empty.vue';
import tmDialog from '@/tm-vuetify/components/tm-dialog/tm-dialog.vue'; import tmDialog from '@/tm-vuetify/components/tm-dialog/tm-dialog.vue';
import tmMore from '@/tm-vuetify/components/tm-more/tm-more.vue'; import tmMore from '@/tm-vuetify/components/tm-more/tm-more.vue';
import mpHtml from '@/components/mp-html/components/mp-html/mp-html.vue'; import mpHtml from '@/components/mp-html/components/mp-html/mp-html.vue';
import commentList from '@/components/comment-list/comment-list.vue'; import commentList from '@/components/comment-list/comment-list.vue';
import commentItem from '@/components/comment-item/comment-item.vue'; import commentItem from '@/components/comment-item/comment-item.vue';
import commentModal from '@/components/comment-modal/comment-modal.vue'; import commentModal from '@/components/comment-modal/comment-modal.vue';
import rCanvas from '@/components/r-canvas/r-canvas.vue'; import rCanvas from '@/components/r-canvas/r-canvas.vue';
import barrage from '@/components/barrage/barrage.vue'; import barrage from '@/components/barrage/barrage.vue';
import { import {getAppConfigs} from '@/config/index.js'
getAppConfigs import {upvote} from '@/utils/upvote.js'
} from '@/config/index.js'
export default { export default {
components: { components: {
tmSkeleton, tmSkeleton,
tmPoup, tmPoup,
@ -325,13 +324,16 @@
calcIsShowComment() { calcIsShowComment() {
return this.postDetailConfig.showComment return this.postDetailConfig.showComment
},
calcUpvoted() {
return upvote.has("post", this.result?.metadata?.name)
} }
}, },
watch: { watch: {
haloConfigs: { haloConfigs: {
deep: true, deep: true,
immediate: true, immediate: true,
handler: function(newVal) { handler: function (newVal) {
if (!newVal) return; if (!newVal) return;
this.fnHandleSetFlotButtonItems(newVal); this.fnHandleSetFlotButtonItems(newVal);
} }
@ -410,6 +412,7 @@
this.fnSetPageTitle('文章详情'); this.fnSetPageTitle('文章详情');
this.loading = 'success'; this.loading = 'success';
this.fnHandleSetFlotButtonItems(this.haloConfigs);
}) })
.catch(err => { .catch(err => {
console.log("错误", err) console.log("错误", err)
@ -427,9 +430,9 @@
use: true, use: true,
}, },
{ {
icon: 'icon-like', icon: upvote.has("post", this.result?.metadata?.name) ? 'icon-heart-fill' : 'icon-like',
color: 'bg-gradient-orange-accent', color: upvote.has("post", this.result?.metadata?.name) ? 'bg-gradient-red-accent' : 'bg-gradient-orange-accent',
use: false, use: true,
}, },
{ {
icon: 'icon-commentdots-fill', icon: 'icon-commentdots-fill',
@ -443,13 +446,13 @@
// //
fnOnFlotButtonChange(index) { fnOnFlotButtonChange(index) {
switch (index) { switch (index) {
// case 0:
// this.fnDoLikes();
// break;
case 0: case 0:
this.fnShowShare(); this.fnShowShare();
break; break;
case 1: case 1:
this.fnDoLikes();
break;
case 2:
this.fnToComment(); this.fnToComment();
break; break;
} }
@ -483,24 +486,22 @@
this.commentModal.title = ""; this.commentModal.title = "";
}, },
fnDoLikes() { fnDoLikes() {
this.$httpApi if (upvote.has("post", this.result?.metadata?.name)) {
.postLikePost(this.result.id) uni.$tm.toast('已经点过赞啦!');
.then(res => { return;
if (res.status == 200) {
this.result.likes += 1;
uni.$tm.toast('\(^o^)/~点赞成功!');
} else {
uni.showToast({
icon: 'none',
title: res.message
});
} }
this.$httpApi.v2.submitUpvote({
group: "content.halo.run",
plural: "posts",
name: this.result?.metadata?.name
})
.then(res => {
uni.$tm.toast('点赞成功!');
upvote.set("post", this.result?.metadata?.name)
this.fnHandleSetFlotButtonItems(this.haloConfigs);
}) })
.catch(err => { .catch(err => {
uni.showToast({ uni.$tm.toast('点赞失败');
icon: 'none',
title: err.message
});
}); });
}, },
fnShowShare() { fnShowShare() {
@ -860,7 +861,7 @@
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
success: function(loginRes) { success: function (loginRes) {
try { try {
// todo openid使code // todo openid使code
uni.setStorageSync('openid', loginRes.code) uni.setStorageSync('openid', loginRes.code)
@ -959,11 +960,11 @@
} }
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-page { .app-page {
width: 100vw; width: 100vw;
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
@ -971,9 +972,9 @@
box-sizing: border-box; box-sizing: border-box;
background-color: #fafafd; background-color: #fafafd;
padding-bottom: 24rpx; padding-bottom: 24rpx;
} }
.bg-image { .bg-image {
position: fixed; position: fixed;
left: 0; left: 0;
top: 0; top: 0;
@ -982,15 +983,15 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
z-index: 0; z-index: 0;
} }
.loading-wrap { .loading-wrap {
padding: 0 24rpx; padding: 0 24rpx;
height: inherit; height: inherit;
background-color: #fff; background-color: #fff;
} }
.head { .head {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -1017,7 +1018,8 @@
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;
&-name {} &-name {
}
&-time { &-time {
margin-left: 36rpx; margin-left: 36rpx;
@ -1084,9 +1086,9 @@
} }
} }
} }
} }
.category { .category {
margin: 0 24rpx; margin: 0 24rpx;
padding: 24rpx; padding: 24rpx;
background-color: #ffffff; background-color: #ffffff;
@ -1111,30 +1113,30 @@
background-color: #607d8b; background-color: #607d8b;
} }
} }
} }
.category-tag+.category-tag { .category-tag + .category-tag {
margin-left: 12rpx; margin-left: 12rpx;
} }
.content { .content {
margin-top: 24rpx; margin-top: 24rpx;
} }
.markdown-wrap, .markdown-wrap,
.evan-markdown, .evan-markdown,
.ad-wrap, .ad-wrap,
.copyright-wrap, .copyright-wrap,
.comment-wrap { .comment-wrap {
box-shadow: 0rpx 0rpx 24rpx rgba(0, 0, 0, 0.03); box-shadow: 0rpx 0rpx 24rpx rgba(0, 0, 0, 0.03);
} }
.markdown-wrap { .markdown-wrap {
overflow: hidden; overflow: hidden;
border-radius: 12rpx; border-radius: 12rpx;
} }
.copyright-title { .copyright-title {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
padding-left: 24rpx; padding-left: 24rpx;
@ -1150,41 +1152,41 @@
background-color: rgb(3, 174, 252); background-color: rgb(3, 174, 252);
border-radius: 6rpx; border-radius: 6rpx;
} }
} }
.poup-head { .poup-head {
border-bottom: 2rpx solid #f5f5f5; border-bottom: 2rpx solid #f5f5f5;
} }
.poup-body { .poup-body {
height: 50vh; height: 50vh;
} }
.poup-empty { .poup-empty {
width: 100%; width: 100%;
height: 40vh; height: 40vh;
} }
.poup-loading-wrap { .poup-loading-wrap {
width: 100%; width: 100%;
height: 40vh; height: 40vh;
.e-loading-icon { .e-loading-icon {
font-size: 80rpx; font-size: 80rpx;
} }
} }
.poster-content { .poster-content {
width: 100%; width: 100%;
min-height: 60vh; min-height: 60vh;
overflow: hidden; overflow: hidden;
} }
.copyright-text { .copyright-text {
line-height: 1.7; line-height: 1.7;
} }
.poster-loading { .poster-loading {
width: 100%; width: 100%;
position: absolute; position: absolute;
left: 0; left: 0;
@ -1193,14 +1195,14 @@
bottom: 0; bottom: 0;
// background-color: rgba(0, 0, 0, 0.1); // background-color: rgba(0, 0, 0, 0.1);
z-index: 666; z-index: 666;
} }
.poster-save { .poster-save {
box-sizing: border-box; box-sizing: border-box;
border-top: 2rpx dashed #eee; border-top: 2rpx dashed #eee;
} }
.original-url { .original-url {
display: flex; display: flex;
&_left { &_left {
@ -1228,5 +1230,5 @@
text-align: right; text-align: right;
} }
} }
} }
</style> </style>

19
utils/upvote.js Normal file
View File

@ -0,0 +1,19 @@
export const upvote = {
get(key) {
const data = uni.getStorageSync(`upvote.${key}.halo.run`)
if (data) {
return JSON.parse(data)
} else {
return []
}
},
has(key, name) {
const list = this.get(key)
if (list.length == 0) return false;
return list.includes(name)
},
set(key, name) {
const list = this.get(key)
uni.setStorageSync(`upvote.${key}.halo.run`, JSON.stringify([...list, name]))
}
}