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
+86 -16
View File
@@ -31,15 +31,16 @@
<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"
:style="imgStyle(i)"
@click.stop="previewImage(i)"
></image>
</view>
@@ -76,9 +77,87 @@ export default {
canDelete: { type: Boolean, default: false }
},
emits: ['item-click', 'like', 'comment', 'share', 'delete'],
data() {
return {
// 图片宽高比缓存:url -> width/height
imgRatios: {}
}
},
watch: {
'feed.images': {
handler(list) { this.loadImgMeta(list) },
immediate: true
}
},
methods: {
getCatIcon,
isIconPath,
/** 拉取图片真实尺寸,用于按比例计算展示高度 */
loadImgMeta(list) {
if (!list || !list.length) return
list.forEach(url => {
if (!url || this.imgRatios[url] !== undefined) return
uni.getImageInfo({
src: url,
success: res => {
if (res.width && res.height) {
this.imgRatios[url] = res.width / res.height
}
}
})
})
},
/** 每行图片数量:4张用2x2,其余每行最多3张 */
perRow() {
const n = (this.feed.images || []).length
return n === 4 ? 2 : Math.min(n || 1, 3)
},
/** 列宽(rpx):750 - 页面边距64 - 卡片内边距96 - 行间gap */
colWidth() {
const gap = 16
const total = 750 - 64 - 96
const cols = this.perRow()
return (total - gap * (cols - 1)) / cols
},
/** 单张图片的目标高度:按真实比例,夹在上下限内 */
targetHeight(ratio, colW, minH, maxH) {
const r = ratio && ratio > 0 ? ratio : 1
return Math.max(minH, Math.min(colW / r, maxH))
},
/** 同行图片统一高度(取同行目标高度的均值) */
rowHeight(rowIdx) {
const list = this.feed.images || []
const cols = this.perRow()
const colW = this.colWidth()
const single = cols === 1
const minH = single ? 300 : 180
const maxH = single ? 720 : 400
const start = rowIdx * cols
const items = list.slice(start, start + cols)
let sum = 0
items.forEach(url => {
sum += this.targetHeight(this.imgRatios[url], colW, minH, maxH)
})
return Math.round(sum / items.length)
},
/** 点击图片预览大图(支持左右滑动切换) */
previewImage(i) {
const urls = this.feed.images || []
if (!urls.length) return
uni.previewImage({
urls,
current: urls[i]
})
},
imgStyle(i) {
const cols = this.perRow()
const gap = 16
const width = cols === 1 ? '100%' : `calc(${(100 / cols).toFixed(4)}% - ${((gap * (cols - 1)) / cols).toFixed(2)}rpx)`
return {
width,
height: this.rowHeight(Math.floor(i / cols)) + 'rpx'
}
},
feelingLabel(f) {
const val = String(f).toLowerCase()
const map = {
@@ -211,20 +290,11 @@ export default {
.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);
display: block;
/* 比例未获取前的占位尺寸,避免布局跳动 */
width: 33%;
height: 220rpx;
background: $bg-elevated;
}
.feed-actions {