feat: reply upvote, like, dislike
This commit is contained in:
parent
d1d6a77cb9
commit
69b964be7f
|
@ -1,4 +1,4 @@
|
||||||
import { fetchGet, fetchPost } from '@/utils/request'
|
import { fetchGet, fetchPost, fetchPut } from '@/utils/request'
|
||||||
// 将对象转为请求参数的函数
|
// 将对象转为请求参数的函数
|
||||||
import objectToQueryParams from '@/utils/objectToQueryParams'
|
import objectToQueryParams from '@/utils/objectToQueryParams'
|
||||||
import * as Reply from './types/reply'
|
import * as Reply from './types/reply'
|
||||||
|
@ -7,34 +7,60 @@ import * as Reply from './types/reply'
|
||||||
export async function getRepliesByPidApi(
|
export async function getRepliesByPidApi(
|
||||||
request: Reply.TopicReplyRequestData
|
request: Reply.TopicReplyRequestData
|
||||||
): Promise<Reply.TopicReplyResponseData> {
|
): Promise<Reply.TopicReplyResponseData> {
|
||||||
try {
|
const queryParams = objectToQueryParams(request, 'tid')
|
||||||
const queryParams = objectToQueryParams(request, 'tid')
|
const url = `/topics/${request.tid}/replies?${queryParams}`
|
||||||
const url = `/topics/${request.tid}/replies?${queryParams}`
|
|
||||||
|
|
||||||
const response = await fetchGet<Reply.TopicReplyResponseData>(url)
|
const response = await fetchGet<Reply.TopicReplyResponseData>(url)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
throw new Error('Failed to fetch replies')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 tid 创建一个回复
|
// 根据 tid 创建一个回复
|
||||||
export async function postReplyByPidApi(
|
export async function postReplyByPidApi(
|
||||||
request: Reply.TopicCreateReplyRequestData
|
request: Reply.TopicCreateReplyRequestData
|
||||||
): Promise<Reply.TopicCreateReplyResponseData> {
|
): Promise<Reply.TopicCreateReplyResponseData> {
|
||||||
try {
|
const url = `/topics/${request.tid}/reply`
|
||||||
const url = `/topics/${request.tid}/reply`
|
|
||||||
|
|
||||||
const response = await fetchPost<Reply.TopicCreateReplyResponseData>(
|
const response = await fetchPost<Reply.TopicCreateReplyResponseData>(
|
||||||
url,
|
url,
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
}
|
||||||
console.log(error)
|
|
||||||
throw new Error('Failed to create reply')
|
// 推
|
||||||
}
|
export async function updateReplyUpvoteApi(
|
||||||
|
request: Reply.TopicUpvoteReplyRequestData
|
||||||
|
): Promise<Reply.TopicUpvoteReplyResponseData> {
|
||||||
|
const queryParams = objectToQueryParams(request, 'tid')
|
||||||
|
const url = `/topics/${request.tid}/reply/upvote?${queryParams}`
|
||||||
|
|
||||||
|
const response = fetchPut<Reply.TopicUpvoteReplyResponseData>(url)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点赞
|
||||||
|
export async function updateReplyLikeApi(
|
||||||
|
request: Reply.TopicLikeReplyRequestData
|
||||||
|
): Promise<Reply.TopicLikeReplyResponseData> {
|
||||||
|
const queryParams = objectToQueryParams(request, 'tid')
|
||||||
|
const url = `/topics/${request.tid}/reply/like?${queryParams}`
|
||||||
|
|
||||||
|
const response = fetchPut<Reply.TopicLikeReplyResponseData>(url)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点踩
|
||||||
|
export async function updateReplyDislikeApi(
|
||||||
|
request: Reply.TopicDislikeReplyRequestData
|
||||||
|
): Promise<Reply.TopicDislikeReplyResponseData> {
|
||||||
|
const queryParams = objectToQueryParams(request, 'tid')
|
||||||
|
const url = `/topics/${request.tid}/reply/dislike?${queryParams}`
|
||||||
|
|
||||||
|
const response = fetchPut<Reply.TopicDislikeReplyResponseData>(url)
|
||||||
|
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export interface TopicReply {
|
||||||
to_user: TopicToUserInfo
|
to_user: TopicToUserInfo
|
||||||
edited: number
|
edited: number
|
||||||
content: string
|
content: string
|
||||||
upvote: number[]
|
upvotes: number[]
|
||||||
likes: number[]
|
likes: number[]
|
||||||
dislikes: number[]
|
dislikes: number[]
|
||||||
tags: string[]
|
tags: string[]
|
||||||
|
|
|
@ -3,23 +3,21 @@ import { defineStore } from 'pinia'
|
||||||
// 话题
|
// 话题
|
||||||
import {
|
import {
|
||||||
getTopicByTidApi,
|
getTopicByTidApi,
|
||||||
|
getRelatedTopicsByTagsApi,
|
||||||
|
getPopularTopicsByUserUidApi,
|
||||||
|
updateTopicUpvoteApi,
|
||||||
|
updateTopicLikeApi,
|
||||||
|
updateTopicDislikeApi,
|
||||||
|
} from '@/api'
|
||||||
|
import type {
|
||||||
TopicDetailResponseData,
|
TopicDetailResponseData,
|
||||||
TopicAsideOtherTagRequestData,
|
TopicAsideOtherTagRequestData,
|
||||||
getRelatedTopicsByTagsApi,
|
|
||||||
TopicAsideMasterRequestData,
|
TopicAsideMasterRequestData,
|
||||||
getPopularTopicsByUserUidApi,
|
|
||||||
TopicAsideResponseData,
|
TopicAsideResponseData,
|
||||||
} from '@/api'
|
|
||||||
|
|
||||||
// 点赞等动作
|
|
||||||
import {
|
|
||||||
updateTopicUpvoteApi,
|
|
||||||
TopicUpvoteTopicRequestData,
|
TopicUpvoteTopicRequestData,
|
||||||
TopicUpvoteTopicResponseData,
|
TopicUpvoteTopicResponseData,
|
||||||
updateTopicLikeApi,
|
|
||||||
TopicLikeTopicRequestData,
|
TopicLikeTopicRequestData,
|
||||||
TopicLikeTopicResponseData,
|
TopicLikeTopicResponseData,
|
||||||
updateTopicDislikeApi,
|
|
||||||
TopicDislikeTopicRequestData,
|
TopicDislikeTopicRequestData,
|
||||||
TopicDislikeTopicResponseData,
|
TopicDislikeTopicResponseData,
|
||||||
} from '@/api'
|
} from '@/api'
|
||||||
|
@ -28,10 +26,22 @@ import {
|
||||||
import {
|
import {
|
||||||
getRepliesByPidApi,
|
getRepliesByPidApi,
|
||||||
postReplyByPidApi,
|
postReplyByPidApi,
|
||||||
|
updateReplyUpvoteApi,
|
||||||
|
updateReplyLikeApi,
|
||||||
|
updateReplyDislikeApi,
|
||||||
|
} from '@/api'
|
||||||
|
|
||||||
|
import type {
|
||||||
TopicReplyRequestData,
|
TopicReplyRequestData,
|
||||||
TopicReplyResponseData,
|
TopicReplyResponseData,
|
||||||
TopicCreateReplyRequestData,
|
TopicCreateReplyRequestData,
|
||||||
TopicCreateReplyResponseData,
|
TopicCreateReplyResponseData,
|
||||||
|
TopicUpvoteReplyRequestData,
|
||||||
|
TopicUpvoteReplyResponseData,
|
||||||
|
TopicLikeReplyRequestData,
|
||||||
|
TopicLikeReplyResponseData,
|
||||||
|
TopicDislikeReplyRequestData,
|
||||||
|
TopicDislikeReplyResponseData,
|
||||||
} from '@/api'
|
} from '@/api'
|
||||||
|
|
||||||
// 评论
|
// 评论
|
||||||
|
@ -154,7 +164,7 @@ export const useKUNGalgameTopicStore = defineStore({
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取回复
|
// 获取回复
|
||||||
async getReplies(tid: number): Promise<TopicDislikeTopicResponseData> {
|
async getReplies(tid: number): Promise<TopicReplyResponseData> {
|
||||||
// 这里的默认值用于初始化
|
// 这里的默认值用于初始化
|
||||||
const requestData: TopicReplyRequestData = {
|
const requestData: TopicReplyRequestData = {
|
||||||
tid: tid,
|
tid: tid,
|
||||||
|
@ -179,6 +189,52 @@ export const useKUNGalgameTopicStore = defineStore({
|
||||||
return await postReplyByPidApi(requestData)
|
return await postReplyByPidApi(requestData)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 推回复
|
||||||
|
async updateReplyUpvote(
|
||||||
|
tid: number,
|
||||||
|
toUid: number,
|
||||||
|
rid: number
|
||||||
|
): Promise<TopicUpvoteReplyResponseData> {
|
||||||
|
const requestData: TopicUpvoteReplyRequestData = {
|
||||||
|
tid: tid,
|
||||||
|
to_uid: toUid,
|
||||||
|
rid: rid,
|
||||||
|
}
|
||||||
|
return await updateReplyUpvoteApi(requestData)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 点赞回复
|
||||||
|
async updateReplyLike(
|
||||||
|
tid: number,
|
||||||
|
toUid: number,
|
||||||
|
rid: number,
|
||||||
|
isPush: boolean
|
||||||
|
): Promise<TopicLikeReplyResponseData> {
|
||||||
|
const requestData: TopicLikeReplyRequestData = {
|
||||||
|
tid: tid,
|
||||||
|
to_uid: toUid,
|
||||||
|
rid: rid,
|
||||||
|
isPush: isPush,
|
||||||
|
}
|
||||||
|
return await updateReplyLikeApi(requestData)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 点踩回复
|
||||||
|
async updateReplyDislike(
|
||||||
|
tid: number,
|
||||||
|
toUid: number,
|
||||||
|
rid: number,
|
||||||
|
isPush: boolean
|
||||||
|
): Promise<TopicDislikeReplyResponseData> {
|
||||||
|
const requestData: TopicDislikeReplyRequestData = {
|
||||||
|
tid: tid,
|
||||||
|
to_uid: toUid,
|
||||||
|
rid: rid,
|
||||||
|
isPush: isPush,
|
||||||
|
}
|
||||||
|
return await updateReplyDislikeApi(requestData)
|
||||||
|
},
|
||||||
|
|
||||||
// 获取评论
|
// 获取评论
|
||||||
async getComments(
|
async getComments(
|
||||||
tid: number,
|
tid: number,
|
||||||
|
|
|
@ -98,16 +98,17 @@ const handleClickComment = (rid: number) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 其它人回复的底部 -->
|
<!-- 其它人回复的底部 -->
|
||||||
<!-- info 代表 footer 的点赞等信息,rUser 表示当前的回复用户信息 -->
|
<!-- info 代表 footer 的点赞等信息,master 表示当前的回复用户信息 -->
|
||||||
<!-- 这里传入了回复的插槽,因为只有回复可以被评论 -->
|
<!-- 这里传入了回复的插槽,因为只有回复可以被评论 -->
|
||||||
<ReplyFooter
|
<ReplyFooter
|
||||||
:info="{
|
:info="{
|
||||||
|
rid: reply.rid,
|
||||||
likes: reply.likes,
|
likes: reply.likes,
|
||||||
dislikes: reply.dislikes,
|
dislikes: reply.dislikes,
|
||||||
upvotes: reply.upvote,
|
upvotes: reply.upvotes,
|
||||||
to_floor: reply.floor,
|
to_floor: reply.floor,
|
||||||
}"
|
}"
|
||||||
:rUser="reply.r_user"
|
:master="reply.r_user"
|
||||||
>
|
>
|
||||||
<template #comment>
|
<template #comment>
|
||||||
<span @click="handleClickComment(reply.rid)" class="icon">
|
<span @click="handleClickComment(reply.rid)" class="icon">
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
<!-- 话题的底部区域,推话题,回复,点赞等 -->
|
<!-- 话题的底部区域,推话题,回复,点赞等 -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
|
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
// 全局消息组件(底部)
|
||||||
|
import { useKUNGalgameMessageStore } from '@/store/modules/message'
|
||||||
|
// 全局消息组件(顶部)
|
||||||
|
import message from '@/components/alert/Message'
|
||||||
|
// throttle 函数
|
||||||
|
import { throttle } from '@/utils/throttle'
|
||||||
|
|
||||||
import { TopicUserInfo } from '@/api'
|
import { TopicUserInfo } from '@/api'
|
||||||
|
|
||||||
|
// 导入编辑界面的 store
|
||||||
|
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||||
// 导入话题页面 store
|
// 导入话题页面 store
|
||||||
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||||
|
// 导入用户的 store
|
||||||
|
import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
// 当前的话题 tid
|
// 当前的话题 tid
|
||||||
|
@ -20,31 +32,206 @@ const { isEdit, replyDraft } = storeToRefs(topicStore)
|
||||||
// 接受父组件的传值
|
// 接受父组件的传值
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
info: {
|
info: {
|
||||||
views?: number
|
rid: number
|
||||||
likes: number[]
|
likes: number[]
|
||||||
dislikes: number[]
|
dislikes: number[]
|
||||||
upvotes: number[]
|
upvotes: number[]
|
||||||
// 被回复人的 floor
|
// 被回复人的 floor
|
||||||
to_floor: number
|
to_floor: number
|
||||||
}
|
}
|
||||||
rUser: TopicUserInfo
|
master: TopicUserInfo
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这里只是简单起见,不显示重新编辑
|
||||||
|
* 实际上如果用户自己修改了 localStorage 中保存的信息,这个验证就失效了
|
||||||
|
* 但是修改了也没有用,验证逻辑位于后端
|
||||||
|
*/
|
||||||
|
// 当前登录用户的 uid
|
||||||
|
const currUserUid = useKUNGalgameUserStore().uid
|
||||||
|
// 话题发布者的 uid
|
||||||
|
const masterUid = props.master.uid
|
||||||
|
// 是否具有重新编辑的权限
|
||||||
|
const isShowRewrite = currUserUid === masterUid
|
||||||
|
|
||||||
|
// footer 左侧的动作,点赞等
|
||||||
|
const actions = reactive({
|
||||||
|
upvotes: props.info.upvotes,
|
||||||
|
likes: props.info.likes,
|
||||||
|
dislikes: props.info.dislikes,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 是否已经点过赞,点过踩
|
||||||
|
const isActive = reactive({
|
||||||
|
isUpvote: false,
|
||||||
|
isLiked: false,
|
||||||
|
isDisliked: false,
|
||||||
|
isShared: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
// throttle 回调函数
|
||||||
|
const throttleCallback = () => {
|
||||||
|
message(
|
||||||
|
'You can only perform one operation within 1007 milliseconds',
|
||||||
|
'您在 1007 毫秒内只能进行一次操作',
|
||||||
|
'warn'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// throttle 函数,1007 毫秒仅会触发一次点赞
|
||||||
|
const handleClickLikeThrottled = throttle(
|
||||||
|
async () => {
|
||||||
|
// 当前用户不可以给自己点赞
|
||||||
|
if (currUserUid === masterUid) {
|
||||||
|
message(
|
||||||
|
'You cannot like your own reply',
|
||||||
|
'您不可以给自己的回复点赞',
|
||||||
|
'warn'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换点赞激活状态
|
||||||
|
isActive.isLiked = !isActive.isLiked
|
||||||
|
|
||||||
|
const res = await useKUNGalgameTopicStore().updateReplyLike(
|
||||||
|
tid,
|
||||||
|
masterUid,
|
||||||
|
props.info.rid,
|
||||||
|
isActive.isLiked
|
||||||
|
)
|
||||||
|
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 更新点赞数
|
||||||
|
actions.likes.length = isActive.isLiked
|
||||||
|
? actions.likes.length + 1
|
||||||
|
: actions.likes.length - 1
|
||||||
|
} else {
|
||||||
|
message('Reply like failed!', '点赞回复失败', 'error')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1007,
|
||||||
|
throttleCallback
|
||||||
|
)
|
||||||
|
|
||||||
|
// throttle 函数,1007 毫秒仅会触发一次点踩
|
||||||
|
const handleClickDislikeThrottled = throttle(
|
||||||
|
async () => {
|
||||||
|
if (currUserUid === masterUid) {
|
||||||
|
message(
|
||||||
|
'You cannot dislike your own reply',
|
||||||
|
'您不可以给自己的回复点踩',
|
||||||
|
'warn'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isActive.isDisliked = !isActive.isDisliked
|
||||||
|
const res = await useKUNGalgameTopicStore().updateReplyDislike(
|
||||||
|
tid,
|
||||||
|
masterUid,
|
||||||
|
props.info.rid,
|
||||||
|
isActive.isDisliked
|
||||||
|
)
|
||||||
|
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 更新点赞数
|
||||||
|
actions.dislikes.length = isActive.isDisliked
|
||||||
|
? actions.dislikes.length + 1
|
||||||
|
: actions.dislikes.length - 1
|
||||||
|
} else {
|
||||||
|
message('Reply dislike failed!', '点踩回复失败', 'error')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1007,
|
||||||
|
throttleCallback
|
||||||
|
)
|
||||||
|
|
||||||
|
// 推话题
|
||||||
|
const handleClickUpvote = async () => {
|
||||||
|
// 当前用户不可以推自己的话题
|
||||||
|
if (currUserUid === masterUid) {
|
||||||
|
message('You cannot upvote your own reply', '您不可以推自己的回复', 'warn')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 该功能必须有错误处理
|
||||||
|
// if (useKUNGalgameUserStore().moemoepoint < 1100) {
|
||||||
|
// message(
|
||||||
|
// 'Your Moe Moe Points are less than 1100, and you cannot use the upvote feature',
|
||||||
|
// '您的萌萌点小于 1100,无法使用推功能',
|
||||||
|
// 'warn'
|
||||||
|
// )
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 调用弹窗确认
|
||||||
|
const res = await useKUNGalgameMessageStore().alert(
|
||||||
|
'AlertInfo.edit.upvote',
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
// 这里实现用户的点击确认取消逻辑
|
||||||
|
if (res) {
|
||||||
|
// 请求推话题的接口
|
||||||
|
const res = await useKUNGalgameTopicStore().updateReplyUpvote(
|
||||||
|
tid,
|
||||||
|
masterUid,
|
||||||
|
props.info.rid
|
||||||
|
)
|
||||||
|
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 更新推数
|
||||||
|
actions.upvotes.length++
|
||||||
|
|
||||||
|
message('Topic upvote successfully', '推话题成功', 'success')
|
||||||
|
} else {
|
||||||
|
message('Topic upvote failed!', '推话题失败', 'error')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点赞
|
||||||
|
const handleClickLike = () => {
|
||||||
|
handleClickLikeThrottled()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点踩
|
||||||
|
const handleClickDislike = () => {
|
||||||
|
handleClickDislikeThrottled()
|
||||||
|
}
|
||||||
|
|
||||||
// 点击回复打开回复面板
|
// 点击回复打开回复面板
|
||||||
const handelReply = async () => {
|
const handelReply = async () => {
|
||||||
// 保存必要信息,以便发表回复
|
// 保存必要信息,以便发表回复
|
||||||
replyDraft.value.tid = tid
|
replyDraft.value.tid = tid
|
||||||
replyDraft.value.replyUserName = props.rUser.name
|
replyDraft.value.replyUserName = props.master.name
|
||||||
replyDraft.value.to_uid = props.rUser.uid
|
replyDraft.value.to_uid = props.master.uid
|
||||||
replyDraft.value.to_floor = props.info.to_floor
|
replyDraft.value.to_floor = props.info.to_floor
|
||||||
|
|
||||||
// 打开回复面板
|
|
||||||
await nextTick()
|
|
||||||
isEdit.value = true
|
isEdit.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新编辑
|
// 重新编辑
|
||||||
const handleClickEdit = () => {}
|
const handleClickEdit = () => {}
|
||||||
|
|
||||||
|
// 初始化按钮的状态,是否已点赞等
|
||||||
|
onMounted(() => {
|
||||||
|
// 已经推过
|
||||||
|
if (props.info.upvotes.includes(currUserUid)) {
|
||||||
|
isActive.isUpvote = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已经点赞
|
||||||
|
if (props.info.likes.includes(currUserUid)) {
|
||||||
|
isActive.isLiked = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已经点踩
|
||||||
|
if (props.info.dislikes.includes(currUserUid)) {
|
||||||
|
isActive.isDisliked = true
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -55,23 +242,36 @@ const handleClickEdit = () => {}
|
||||||
<ul>
|
<ul>
|
||||||
<!-- 推话题 -->
|
<!-- 推话题 -->
|
||||||
<li>
|
<li>
|
||||||
<span class="icon"><Icon icon="bi:rocket" /></span>
|
<span
|
||||||
{{ info?.upvotes?.length }}
|
class="icon"
|
||||||
</li>
|
:class="isActive.isUpvote ? 'active' : ''"
|
||||||
<!-- 查看数量 -->
|
@click="handleClickUpvote"
|
||||||
<li v-if="info.views">
|
>
|
||||||
<span class="icon"><Icon icon="ic:outline-remove-red-eye" /></span>
|
<Icon icon="bi:rocket" />
|
||||||
{{ info.views }}
|
</span>
|
||||||
|
{{ actions.upvotes.length }}
|
||||||
</li>
|
</li>
|
||||||
<!-- 点赞 -->
|
<!-- 点赞 -->
|
||||||
<li>
|
<li>
|
||||||
<span class="icon"><Icon icon="line-md:thumbs-up-twotone" /></span>
|
<span
|
||||||
{{ info?.likes?.length }}
|
class="icon"
|
||||||
|
:class="isActive.isLiked ? 'active' : ''"
|
||||||
|
@click="handleClickLike"
|
||||||
|
>
|
||||||
|
<Icon icon="line-md:thumbs-up-twotone" />
|
||||||
|
</span>
|
||||||
|
{{ actions.likes.length }}
|
||||||
</li>
|
</li>
|
||||||
<!-- 踩 -->
|
<!-- 踩 -->
|
||||||
<li>
|
<li>
|
||||||
<span class="icon"><Icon icon="line-md:thumbs-down-twotone" /></span>
|
<span
|
||||||
{{ info?.dislikes?.length }}
|
class="icon"
|
||||||
|
:class="isActive.isDisliked ? 'active' : ''"
|
||||||
|
@click="handleClickDislike"
|
||||||
|
>
|
||||||
|
<Icon icon="line-md:thumbs-down-twotone" />
|
||||||
|
</span>
|
||||||
|
{{ actions.dislikes.length }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -204,6 +404,11 @@ const handleClickEdit = () => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 激活后的样式 */
|
||||||
|
.active {
|
||||||
|
color: var(--kungalgame-blue-4);
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.footer {
|
.footer {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
Loading…
Reference in a new issue