Files
AIProd/pages/Launches/components/ListItem.vue

225 lines
4.6 KiB
Vue

<template>
<div class="item-content flex justify-between" @click="handleClick">
<div class="left-content flex flex-1 items-center">
<div class="order-num">{{ sortIndex }}</div>
<div class="preview-box">
<img :src="config.coverImage || ''" alt="" />
</div>
<div class="tool-content flex flex-1 flex-col justify-between">
<div class="content-top flex items-start">
<div class="icon">
<img src="/" alt="" />
</div>
<div class="flex-1">
<div class="title">{{ config.title || '' }}</div>
<div class="sub-title pr-30">{{ config.summary || '' }}</div>
</div>
</div>
<div class="content-bottom flex items-center">
<img src="/launches/item/icon_clock.png" alt="" />
<div class="time-style">{{ formatPublishTime(config.publishTime) }}</div>
</div>
</div>
</div>
<div class="right-content flex items-center">
<div class="flex items-center btn">
<img :src="hovered ? '/launches/item/icon_thumb_grey.png' : '/launches/item/icon_thumb.png'" alt="" />
<div :class="{ 'hover-text': hovered }">{{ config.likeCount || 0 }}</div>
</div>
<div class="flex items-center btn">
<img :src="hovered ? '/launches/item/icon_star_grey.png' : '/launches/item/icon_star.png'" alt="" />
<div :class="{ 'hover-text': hovered }">
{{ (config.rating || 0).toFixed(1) }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
hovered: false
}
},
props: {
sortIndex: {
type: Number,
default: 1,
},
config: {
type: Object,
default: () => {
return {}
},
},
},
methods: {
formatPublishTime(timeString) {
if (!timeString) return '';
const date = new Date(timeString);
const months = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
];
const month = months[date.getMonth()];
const day = String(date.getDate()).padStart(2, '0');
const year = date.getFullYear();
return `${month} ${day} Released in ${year}`;
},
handleMouseEnter() {
this.hovered = true;
},
handleMouseLeave() {
this.hovered = false;
},
// 跳转详情页
handleClick() {
if (!this.config.slug) {
return false;
}
this.articleClick(this.config.id);
this.$router.push({
path: '/launches/detail',
query: {
news_slug: this.config.slug || '',
}
});
},
// 记录文章点击数
async articleClick(id) {
if (id) {
await this.$api.article.recordArticleClick(id);
}
},
},
mounted() {
const itemContent = this.$el;
itemContent.addEventListener('mouseenter', this.handleMouseEnter);
itemContent.addEventListener('mouseleave', this.handleMouseLeave);
},
beforeDestroy() {
const itemContent = this.$el;
itemContent.removeEventListener('mouseenter', this.handleMouseEnter);
itemContent.removeEventListener('mouseleave', this.handleMouseLeave);
}
}
</script>
<style scoped lang="scss">
.pr-30 {
padding-right: 30px;
}
.item-content {
border-radius: 12px;
padding: 25px 20px;
transition: background-color 0.3s ease;
cursor: pointer;
&:hover {
background-color: #F5F4FF;
.order-num {
background: #fff !important;
}
}
&:active {
opacity: 0.8;
}
.left-content {
gap: 30px;
.order-num {
width: 36px;
height: 36px;
border-radius: 12px;
background: #F5F4FF;
margin-right: 10px;
text-align: center;
line-height: 36px;
font-size: 18px;
font-family: 'Poppins-Regular';
transition: background-color 0.3s ease;
color: #506179;
}
.preview-box {
width: 228px;
height: 110px;
border-radius: 6px;
background-color: #FFFFFF;
img {
width: 100%;
height: 100%;
}
}
.tool-content {
height: 100%;
.content-top {
.icon {
width: 46px;
height: 46px;
margin-right: 10px;
img {
width: 100%;
height: 100%;
}
}
.title {
font-size: 20px;
font-family: 'Poppins-SemiBold';
font-weight: 600;
line-height: 24px;
color: #3A4A65;
}
.sub-title {
color: #64748B;
font-family: 'Poppins-Regular';
margin-top: 10px;
max-width: 420px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.content-bottom {
gap: 12px;
img {
width: 24px;
height: 24px;
}
.time-style {
color: #64748B;
font-family: 'Poppins-Regular';
}
}
}
}
.right-content {
padding-right: 23px;
gap: 33px;
font-family: 'Poppins-Regular';
color: #E2E8F0;
max-width: 192px;
.btn {
cursor: pointer;
&:active {
opacity: 0.8;
}
}
img {
width: 24px;
height: 24px;
margin-right: 12px;
}
.hover-text {
color: #64748B;
}
}
}
</style>