feat(event): 添加酒局报名审核功能并优化前端组件

- 新增 ApproveEvent API 接口用于审核报名用户
- 在 EventCard 组件中显示待审核状态(⏳ 待审核)
- 实现酒局发起人审核报名用户的完整流程
- 添加用户协议和隐私政策页面
- 优化 FeedCard 组件中的图片展示逻辑
- 修复连续打卡天数计算问题
- 更新 HaveADrink SDK 至 1.0.15 版本
This commit is contained in:
cg
2026-08-16 14:50:50 +08:00
parent 527b0e8a8d
commit 81e7a3afa5
20 changed files with 1470 additions and 249 deletions
+73 -50
View File
@@ -9,7 +9,7 @@
</view>
<!-- 右上角分享按钮(避让胶囊) -->
<button class="hero-share-btn" open-type="share" :style="shareBtnStyle">
<text class="hero-share-icon">↗</text>
<text class="hero-share-icon">分享</text>
</button>
<view class="hero-content">
<view class="avatar-ring">
@@ -71,25 +71,33 @@
</view>
</view>
<!-- 连续打卡卡片(含连续戒酒状态,暂时注释隐藏)
<view class="streak-section">
<view class="streak-card" :class="stats.streakType === 'drank' ? 'streak-drank' : 'streak-abstain'">
<view class="streak-left">
<view class="streak-badge">
<text class="streak-badge-emoji">{{ stats.streakType === 'drank' ? '🔥' : '💪' }}</text>
<view class="streak-row">
<view class="streak-card streak-drank">
<view class="streak-card-top">
<text class="streak-badge-emoji">🔥</text>
<text class="streak-title">连续饮酒</text>
</view>
<view class="streak-info">
<text class="streak-title">{{ stats.streakType === 'drank' ? '连续饮酒' : '连续戒酒' }}</text>
<text class="streak-sub">{{ stats.streakType === 'drank' ? '保持记录,理性饮酒' : '自律即自由,继续坚持' }}</text>
<text class="streak-sub">保持记录,理性饮酒</text>
<view class="streak-num-row">
<text class="streak-days text-num">{{ stats.drankStreak || 0 }}</text>
<text class="streak-days-unit">天</text>
</view>
</view>
<view class="streak-right">
<text class="streak-days text-num">{{ stats.streak }}</text>
<text class="streak-days-unit">天</text>
<view class="streak-card streak-abstain">
<view class="streak-card-top">
<text class="streak-badge-emoji">💪</text>
<text class="streak-title">连续戒酒</text>
</view>
<text class="streak-sub">自律即自由,继续坚持</text>
<view class="streak-num-row">
<text class="streak-days text-num">{{ stats.abstainStreak || 0 }}</text>
<text class="streak-days-unit">天</text>
</view>
</view>
</view>
</view>
-->
<!-- 饮酒人格卡片 -->
<view class="persona-card">
@@ -166,7 +174,7 @@
<script>
import AchievementBadge from '../../components/AchievementBadge.vue'
import client, { clearAuth } from '../../common/api'
import { checkAchievements, getCatIcon, isIconPath } from '../../common/utils'
import { checkAchievements, getCatIcon, isIconPath, calcLocalStreak } from '../../common/utils'
import { ACHIEVEMENTS, DRINK_CATEGORIES } from '../../common/constants'
import themeMixin from '../../common/theme-mixin'
@@ -309,6 +317,8 @@ export default {
favCategory: s.favCategory ? String(s.favCategory) : null,
categoryVariety: s.categoryVariety || 0
}
// 后端 streak 不区分饮酒/戒酒模式,拉取记录本地重算修正
this.refreshLocalStreak()
}
// 成就列表
@@ -346,6 +356,22 @@ export default {
this.detailAchievement = a
this.showDetail = true
},
/** 后端 streak 不区分饮酒/戒酒模式,拉取全部记录后本地重算连续天数 */
async refreshLocalStreak() {
try {
const resp = await client.GetRecords({ page: 1, pageSize: 100 })
const payload = resp.data || resp
const list = payload.list || []
if (!list.length) return
const { streak, streakType, drankStreak, abstainStreak } = calcLocalStreak(list)
this.stats.streak = streak
this.stats.streakType = streakType
this.stats.drankStreak = drankStreak
this.stats.abstainStreak = abstainStreak
} catch (e) {
console.warn('本地计算连续天数失败:', e)
}
},
// 后端返回的 icon 是无效图片路径,按索引复用本地成就的 emoji 图标(超出后循环取)
resolveAchievementIcon(index) {
if (!ACHIEVEMENTS.length) return '🏅'
@@ -417,30 +443,36 @@ export default {
.hero-share-btn {
position: absolute;
z-index: 10;
width: 64rpx;
height: 64rpx;
padding: 0 32rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255,255,255,0.06);
border: 1rpx solid rgba(255,255,255,0.10);
border-radius: 50%;
backdrop-filter: blur(10px);
/* 玻璃模态效果:半透明白 + 强模糊 + 高光描边 */
background: rgba(255,255,255,0.14);
border: 1rpx solid rgba(255,255,255,0.30);
border-radius: $radius-full;
backdrop-filter: blur(20px) saturate(160%);
box-shadow: inset 0 1rpx 0 rgba(255,255,255,0.35), 0 8rpx 24rpx rgba(0,0,0,0.18);
&::after {
border: none;
}
&:active {
background: rgba(255,255,255,0.12);
transform: scale(0.9);
background: rgba(255,255,255,0.22);
transform: scale(0.94);
}
}
/* 分享胶囊按钮文字:与微信胶囊同构 */
.hero-share-icon {
font-size: $fs-base;
color: $text-secondary;
font-size: $fs-sm;
color: $amber;
font-weight: $fw-bold;
line-height: 1;
letter-spacing: 4rpx;
text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.15);
}
.hero-bg {
@@ -610,12 +642,17 @@ export default {
padding: $sp-lg $sp-lg 0;
}
.streak-card {
.streak-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: $sp-xl;
border-radius: $radius-xl;
gap: $sp-md;
}
.streak-card {
flex: 1;
display: flex;
flex-direction: column;
padding: $sp-lg;
border-radius: $radius-lg;
position: relative;
overflow: hidden;
@@ -630,34 +667,19 @@ export default {
}
}
.streak-left {
.streak-card-top {
display: flex;
align-items: center;
gap: $sp-md;
}
.streak-badge {
width: 88rpx; height: 88rpx;
border-radius: 50%;
background: $bg-card;
display: flex;
align-items: center;
justify-content: center;
box-shadow: $shadow-sm;
gap: $sp-xs;
margin-bottom: 6rpx;
}
.streak-badge-emoji {
font-size: 44rpx;
}
.streak-info {
display: flex;
flex-direction: column;
gap: 4rpx;
font-size: 32rpx;
}
.streak-title {
font-size: $fs-base;
font-size: $fs-sm;
font-weight: $fw-bold;
color: $text-primary;
}
@@ -665,16 +687,17 @@ export default {
.streak-sub {
font-size: $fs-xs;
color: $text-tertiary;
margin-bottom: $sp-md;
}
.streak-right {
.streak-num-row {
display: flex;
align-items: baseline;
gap: 4rpx;
}
.streak-days {
font-size: $fs-hero;
font-size: $fs-3xl;
font-weight: $fw-black;
color: $amber;
line-height: 1;