Files
food-hub-ui/src/components/Moment/MomentCard.vue
2025-07-18 17:25:29 +08:00

154 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="moment-card card-item">
<el-avatar :src="avatarUrl" :size="35" fit="contain" @click="viewProfileClick"/>
<div class="moment-content">
<span class="username">{{ props.item.username }}</span>
<p>{{ props.item.content }}</p>
<div class="moment-image-list">
<el-image v-for="(item, index) in props.item.imageList" :key="index"
:src="serviceFileRootPath + item" fit="cover"
:initial-index="index"
:preview-src-list=previewList />
</div>
<p>{{ formatTimeAgo(props.item.date) }}</p>
<div class="button-container">
<el-button v-if="isCurrentUser"
:icon="Edit" circle size="small" @click="editClick()"/>
<el-badge :value="props.item.likeList.length" :max="9">
<el-button :type="isLike ? 'danger' : 'default'"
circle size="small" @click="handleLikeClick()">
<i class="fa-regular fa-thumbs-up"></i>
</el-button>
</el-badge>
<el-badge :value="props.item.commentList.length" :max="9">
<el-button circle size="small"
@click="momentInfo.isShowComment = !momentInfo.isShowComment">
<i class="fa-regular fa-comment"></i>
</el-button>
</el-badge>
</div>
<div v-if="momentInfo.isShowComment" class="moment-comment">
<el-input
v-model="momentInfo.comment"
maxlength="100" placeholder="平等表达 友善交流"
show-word-limit type="textarea" :rows="3"
/>
<el-popover ref="emojiPopoverRef" placement="bottom" :width="300" trigger="click">
<template #default>
<div class="emoji-panel">
<EmojiPicker :native="true" @select="onSelectEmoji" />
</div>
</template>
<template #reference>
<el-button circle>
<i class="fa-regular fa-face-smile"></i>
</el-button>
</template>
</el-popover>
<el-button type="primary"
:disabled="momentInfo.comment.length === 0"
@click="sendCommentClick()"
class="send-button">发送</el-button>
</div>
<div v-if="props.item.commentList.length > 0" class="moment-comment-list">
<div v-for="(comment, index) in props.item.commentList" :key="index"
class="moment-comment-item">
<span class="name">{{ comment.username }}</span>
<span>{{ comment.content }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import EmojiPicker from 'vue3-emoji-picker'
import 'vue3-emoji-picker/css'
import { Edit } from '@element-plus/icons-vue'
import { computed, defineProps, reactive } from 'vue'
import type { PropType } from 'vue'
import type { IMoment } from '@/types/food'
import { serviceFileRootPath } from '@/utils'
import { formatTimeAgo } from '@/utils/dateUtils'
import { useFoodStore } from '@/store/food'
import { useUserStore } from '@/store/user'
import { useAppStore } from '@/store/app'
import { useRouter } from 'vue-router'
const router = useRouter()
const userStore = useUserStore()
const appStore = useAppStore()
const props = defineProps({
item: {
required: true,
type: Object as PropType<IMoment>
}
})
const foodStore = useFoodStore()
const momentInfo = reactive({
isShowComment: false,
isLike: false,
comment: ''
})
const avatarUrl = computed(() => {
if (props.item?.avatar) {
return serviceFileRootPath + props.item.avatar
} else {
return 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
}
})
const isCurrentUser = computed(() => props.item?.userId === userStore.getUserId())
const isLike = computed(() => props.item?.likeList.includes(userStore.getUserId()))
const previewList = computed(() => {
return props.item?.imageList.map((item) => serviceFileRootPath + item)
})
const editClick = () => {
foodStore.momentApiType = 'UPDATE'
foodStore.currentMoment = props.item as IMoment
router.push('/moment/form')
}
const handleLikeClick = () => {
if (isLike.value) {
foodStore.deleteMomentLike(props.item?.id as number)
} else {
foodStore.addMomentLike(props.item?.id as number)
}
}
const onSelectEmoji = (emoji) => {
momentInfo.comment += emoji.i
}
const sendCommentClick = async () => {
await foodStore.addMomentComment(props.item?.id as number, momentInfo.comment)
momentInfo.comment = ''
momentInfo.isShowComment = false
}
const viewProfileClick = async () => {
if (!isCurrentUser.value) {
appStore.isShowMobileBack = true
foodStore.currentMomentUserId = props.item?.userId as number
await userStore.queryUser(foodStore.currentMomentUserId)
await router.push('/moment/profile')
}
}
</script>