feat(circle): 添加酒友圈社交模块

- 新增酒友圈、圈子详情、发布动态、好友列表、活动创建等页面配置
- 添加酒友圈相关API接口,包括动态、评论、好友、活动等功能
- 实现模拟数据用于前端开发和测试
- 创建评论项、空状态、活动卡片、动态卡片、好友项等组件
- 编写酒友圈模块详细的接口文档,定义数据结构和业务规则
This commit is contained in:
cg
2026-07-20 22:53:04 +08:00
parent 9f5c69e1e5
commit fabbb167cf
18 changed files with 3992 additions and 18 deletions
+179
View File
@@ -0,0 +1,179 @@
<template>
<view class="event-card" @click="$emit('tap', event)">
<!-- 状态标签 -->
<view class="event-status" :class="'status-' + event.status">
<text class="event-status-text">{{ statusLabel }}</text>
</view>
<!-- 标题 -->
<text class="event-title">{{ event.title }}</text>
<!-- 信息行 -->
<view class="event-info">
<view class="event-info-row">
<text class="event-info-icon">🕐</text>
<text class="event-info-text">{{ event.time }}</text>
</view>
<view class="event-info-row">
<text class="event-info-icon">📍</text>
<text class="event-info-text">{{ event.location }}</text>
</view>
<view class="event-info-row">
<text class="event-info-icon">👥</text>
<text class="event-info-text">{{ event.joined }}/{{ event.maxPeople }} 人已报名</text>
</view>
</view>
<!-- 底部发起人 + 操作 -->
<view class="event-footer">
<view class="event-organizer">
<view class="event-org-avatar">
<text class="event-org-text">{{ event.organizer ? event.organizer.nickname[0] : '酒' }}</text>
</view>
<text class="event-org-name">{{ event.organizer ? event.organizer.nickname : '' }}</text>
</view>
<view class="event-action" v-if="event.status === 'open'">
<text class="event-action-text" v-if="event.isJoined"> 已报名</text>
<text class="event-action-text event-action-join" v-else>报名</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'EventCard',
props: {
event: { type: Object, default: () => ({}) }
},
computed: {
statusLabel() {
const map = { open: '报名中', ongoing: '进行中', ended: '已结束' }
return map[this.event.status] || '报名中'
}
}
}
</script>
<style lang="scss" scoped>
.event-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;
position: relative;
overflow: hidden;
&:active {
background: $bg-card-alt;
}
}
.event-status {
display: inline-flex;
padding: 6rpx 16rpx;
border-radius: $radius-full;
margin-bottom: $sp-md;
&.status-open {
background: rgba(94,198,160,0.12);
}
&.status-ongoing {
background: rgba(232,168,56,0.12);
}
&.status-ended {
background: $bg-elevated;
}
}
.event-status-text {
font-size: $fs-xs;
font-weight: $fw-medium;
.status-open & { color: $mint; }
.status-ongoing & { color: $amber; }
.status-ended & { color: $text-tertiary; }
}
.event-title {
display: block;
font-size: $fs-lg;
font-weight: $fw-bold;
color: $text-primary;
margin-bottom: $sp-lg;
}
.event-info {
display: flex;
flex-direction: column;
gap: $sp-sm;
margin-bottom: $sp-lg;
}
.event-info-row {
display: flex;
align-items: center;
gap: $sp-sm;
}
.event-info-icon {
font-size: $fs-sm;
width: 36rpx;
text-align: center;
}
.event-info-text {
font-size: $fs-sm;
color: $text-secondary;
}
.event-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: $sp-md;
border-top: 1rpx solid var(--divider-color, rgba(255,255,255,0.08));
}
.event-organizer {
display: flex;
align-items: center;
gap: $sp-sm;
}
.event-org-avatar {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: $bg-elevated;
display: flex;
align-items: center;
justify-content: center;
}
.event-org-text {
font-size: $fs-xs;
font-weight: $fw-bold;
color: $lavender;
}
.event-org-name {
font-size: $fs-sm;
color: $text-tertiary;
}
.event-action-text {
font-size: $fs-sm;
color: $text-tertiary;
padding: 8rpx 24rpx;
border-radius: $radius-full;
background: $bg-elevated;
}
.event-action-join {
color: $text-on-amber;
background: linear-gradient(135deg, $amber, $amber-deep);
font-weight: $fw-bold;
}
</style>