Files
AIProd/pages/ToolDetail/components/ThumbBtn.vue
2025-10-31 15:58:11 +08:00

135 lines
2.7 KiB
Vue

<script>
export default {
props: {
likeCount: {
type: Number,
default: 0
},
id: {
type: Number,
default: 0,
},
type: {
type: String,
default: 'tool',
},
},
data() {
return {
isActive: false,
throttleTimer: null,
isHovered: false,
}
},
computed: {
// 根据状态返回不同的图片路径
getImageSrc() {
// 如果已经点赞,显示选中的图片
if (this.isActive) {
return '/ToolDetail/icon_thumb_selected.png';
}
// 如果鼠标悬停或点击,显示高亮的图片
if (this.isHovered) {
return '/ToolDetail/icon_thumb_selected.png';
}
// 默认显示普通图片
return '/ToolDetail/icon_thumb.png';
}
},
methods: {
// 添加点赞
async addLike() {
// 节流控制 - 如果已有定时器则阻止执行
if (this.throttleTimer) {
return false;
}
// 设置节流定时器
this.throttleTimer = setTimeout(() => {
this.throttleTimer = null;
}, 3000);
if (!this.id) {
// 清除定时器
clearTimeout(this.throttleTimer);
this.throttleTimer = null;
return false;
}
if (this.type === 'tool') {
const {data: res} = await this.$api.tool.clickToolLike(this.id);
const {code} = res;
if (code === 0) {
this.$message.success('Like successful');
this.$emit('like-success');
} else {
// 请求失败时清除定时器,允许重新点击
clearTimeout(this.throttleTimer);
this.throttleTimer = null;
}
} else {
const {data: res} = await this.$api.article.clickArticleLike(this.id);
const {code} = res;
if (code === 0) {
this.$message.success('Like successful');
this.$emit('like-success');
} else {
// 请求失败时清除定时器,允许重新点击
clearTimeout(this.throttleTimer);
this.throttleTimer = null;
}
}
},
// 鼠标悬停
onMouseEnter() {
this.isHovered = true;
},
// 鼠标离开
onMouseLeave() {
this.isHovered = false;
}
}
}
</script>
<template>
<div class="box flex flex-col items-center" @click="addLike" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
<img :src="getImageSrc" alt="" />
<span>{{ likeCount }}</span>
</div>
</template>
<style scoped lang="scss">
.box {
width: 48px;
height: 48px;
border-radius: 12px;
box-shadow: 0 4px 6px 0 #0000000d;
background: #fff;
padding: 5px;
font-family: 'Poppins-Regular', serif;
font-size: 12px;
cursor: pointer;
img {
width: 20px;
height: 20px;
}
span {
color: #64748b;
}
&:hover {
background: linear-gradient(90deg, #2563EB 22%, #7B61FF 73%);
span {
color: #ffffffcc;
}
}
&:active {
background: linear-gradient(90deg, #2563EB 22%, #7B61FF 73%);
opacity: 0.8;
span {
color: #ffffffcc;
}
}
}
</style>