Files
hejiu/components/FeedCard.vue
T
cg 49ef6eedb8 feat(game): 新增酒桌小游戏功能并优化图标显示
- 添加了完整的酒桌小游戏页面,包含数字炸弹、猜拳大战、骰子大话和命运转盘四个游戏
- 实现了成就徽章组件的图标路径判断逻辑,支持图片和文字图标的动态切换
- 更新了饮酒分类常量中的白酒图标为酒杯样式,并修改成就图标为SVG路径
- 重构了动态卡片组件中的分类表情符号显示方式,支持SVG图标渲染
- 添加了游戏页面的路由配置和完整的交互功能实现
2026-07-20 23:25:55 +08:00

247 lines
5.2 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>
<view class="feed-card" @click="$emit('tap', feed)">
<!-- 头部头像+昵称+时间 -->
<view class="feed-header">
<view class="feed-avatar-wrap">
<image v-if="feed.avatar" class="feed-avatar" :src="feed.avatar" mode="aspectFill"></image>
<view v-else class="feed-avatar feed-avatar-ph">
<text class="feed-avatar-text">{{ feed.nickname ? feed.nickname[0] : '酒' }}</text>
</view>
</view>
<view class="feed-meta">
<text class="feed-name">{{ feed.nickname }}</text>
<text class="feed-time">{{ feed.time }}</text>
</view>
</view>
<!-- 正文 -->
<text class="feed-text">{{ feed.text }}</text>
<!-- 饮酒标签 -->
<view class="feed-drinks" v-if="feed.drinks && feed.drinks.length">
<view class="feed-drink-tag" v-for="(d, i) in feed.drinks" :key="i">
<image v-if="isIconPath(getCatIcon(d.category))" :src="getCatIcon(d.category)" class="feed-drink-icon-img" mode="aspectFit"></image>
<text v-else class="feed-drink-emoji">{{ getCatIcon(d.category) }}</text>
<text class="feed-drink-name">{{ d.name }} {{ d.amount }}</text>
</view>
</view>
<!-- 感受标签 -->
<view class="feed-feeling" v-if="feed.feeling">
<text class="feed-feeling-text">{{ feelingLabel(feed.feeling) }}</text>
</view>
<!-- 图片 -->
<view class="feed-images" v-if="feed.images && feed.images.length">
<image
v-for="(img, i) in feed.images"
:key="i"
class="feed-img"
:class="'feed-img-' + Math.min(feed.images.length, 3)"
:src="img"
mode="aspectFill"
></image>
</view>
<!-- 操作栏 -->
<view class="feed-actions">
<view class="feed-action" :class="{ active: feed.liked }" @click.stop="$emit('like', feed)">
<text class="feed-action-icon">{{ feed.liked ? '❤️' : '🤍' }}</text>
<text class="feed-action-num">{{ feed.likes || '' }}</text>
</view>
<view class="feed-action" @click.stop="$emit('comment', feed)">
<text class="feed-action-icon">💬</text>
<text class="feed-action-num">{{ feed.comments || '' }}</text>
</view>
<view class="feed-action" @click.stop="$emit('share', feed)">
<text class="feed-action-icon"></text>
</view>
</view>
</view>
</template>
<script>
import { getCatIcon, isIconPath } from '../common/utils'
export default {
name: 'FeedCard',
props: {
feed: { type: Object, default: () => ({}) }
},
methods: {
getCatIcon,
isIconPath,
feelingLabel(f) {
const map = { sober: '😌 清醒', buzzed: '😊 微醺', tipsy: '😄 小醉', drunk: '🥴 喝多了' }
return map[f] || '🍻 喝了点'
}
}
}
</script>
<style lang="scss" scoped>
.feed-card {
background: $bg-card;
border-radius: $radius-xl;
border: 1rpx solid var(--border-faint, rgba(255,255,255,0.08));
padding: $sp-xl;
margin-bottom: $sp-md;
}
.feed-header {
display: flex;
align-items: center;
gap: $sp-md;
margin-bottom: $sp-lg;
}
.feed-avatar-wrap {
flex-shrink: 0;
}
.feed-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.feed-avatar-ph {
background: linear-gradient(135deg, rgba(232,168,56,0.2), rgba(139,133,184,0.2));
display: flex;
align-items: center;
justify-content: center;
}
.feed-avatar-text {
font-size: $fs-lg;
font-weight: $fw-bold;
color: $amber;
}
.feed-meta {
display: flex;
flex-direction: column;
gap: 4rpx;
}
.feed-name {
font-size: $fs-base;
font-weight: $fw-bold;
color: $text-primary;
}
.feed-time {
font-size: $fs-xs;
color: $text-tertiary;
}
.feed-text {
display: block;
font-size: $fs-base;
color: $text-primary;
line-height: $lh-loose;
margin-bottom: $sp-md;
}
.feed-drinks {
display: flex;
flex-wrap: wrap;
gap: $sp-sm;
margin-bottom: $sp-md;
}
.feed-drink-tag {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 20rpx;
background: $bg-elevated;
border-radius: $radius-full;
border: 1rpx solid var(--border-micro, rgba(255,255,255,0.05));
}
.feed-drink-emoji {
font-size: $fs-sm;
}
.feed-drink-icon-img {
width: 32rpx;
height: 32rpx;
flex-shrink: 0;
}
.feed-drink-name {
font-size: $fs-xs;
color: $text-secondary;
}
.feed-feeling {
margin-bottom: $sp-md;
}
.feed-feeling-text {
font-size: $fs-xs;
color: $text-tertiary;
padding: 6rpx 16rpx;
background: rgba(232,168,56,0.06);
border-radius: $radius-full;
}
.feed-images {
display: flex;
flex-wrap: wrap;
gap: $sp-sm;
margin-bottom: $sp-md;
}
.feed-img {
border-radius: $radius-md;
height: 200rpx;
}
.feed-img-1 {
width: 100%;
height: 320rpx;
}
.feed-img-2 {
width: calc(50% - 8rpx);
}
.feed-img-3 {
width: calc(33.33% - 11rpx);
}
.feed-actions {
display: flex;
align-items: center;
gap: $sp-xl;
padding-top: $sp-md;
border-top: 1rpx solid var(--divider-color, rgba(255,255,255,0.08));
}
.feed-action {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 0;
&.active .feed-action-num {
color: $coral;
}
&:active {
opacity: 0.7;
}
}
.feed-action-icon {
font-size: $fs-base;
}
.feed-action-num {
font-size: $fs-sm;
color: $text-tertiary;
}
</style>