mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2025-05-19 10:00:13 +09:00
feat: 新增文章点赞功能
This commit is contained in:
parent
7c15c84dba
commit
e19b107ed0
@ -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, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
19
utils/upvote.js
Normal 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]))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user