feat(穿搭详情): 支持社区公开穿搭只读访问单品

非属主查看社区公开穿搭时携带 outfit_uuid 凭证请求单品详情,
放行后端只读读取,避免名称退化为「未命名」;单品详情页同步
支持 outfit_uuid 只读凭证。点赞增加防连点,来源胶囊与状态
胶囊文案重复时只保留一个。
This commit is contained in:
2026-09-16 02:28:58 +08:00
parent ac271493c0
commit fb92782c92
3 changed files with 49 additions and 32 deletions
@@ -227,27 +227,30 @@ Page({
statePill: outfitStatusPill(outfit),
})
// 封面与衣物缩略图直接使用穿搭明细里的抠图(processed_image),
// 避免非属主逐件请求 /clothes/:uuid 被拒(50005)导致图片与名称全部丢失。
// 封面与衣物缩略图先直接使用穿搭明细里的抠图(processed_image),
// 即使后续单品详情拉取失败,图片也不会丢。
const baseClothes = (outfit.items || []).map(
(it) => ({ clothes_uuid: it.clothes_uuid, processed_image: it.processed_image }) as ClothesItem,
)
this.setData({ clothes: baseClothes })
// 属主可进一步拉取衣物详情补充名称;非属主无权限,跳过。
if (this.data.isOwner) {
const clothes = await Promise.all(
(outfit.items || []).map(async (it) => {
try {
return await request<ClothesItem>({ url: `/clothes/${it.clothes_uuid}`, showError: false })
} catch (e: any) {
logger.warn(LOG, '单品详情拉取失败, uuid=', it.clothes_uuid, 'code=', e && e.code)
return { clothes_uuid: it.clothes_uuid, processed_image: it.processed_image } as ClothesItem
}
})
)
this.setData({ clothes })
}
// 拉取单品详情补充名称与属性:属主直接读;非属主(社区公开穿搭 / 他人分享)携带本穿搭 uuid,
// 由后端只读放行,避免被拒(50005)导致名称全部退化成「未命名」。
const clothesQuery = this.data.isOwner ? '' : `?outfit_uuid=${this.data.uuid}`
const clothes = await Promise.all(
(outfit.items || []).map(async (it) => {
try {
return await request<ClothesItem>({
url: `/clothes/${it.clothes_uuid}${clothesQuery}`,
showError: false,
})
} catch (e: any) {
logger.warn(LOG, '单品详情拉取失败, uuid=', it.clothes_uuid, 'code=', e && e.code)
return { clothes_uuid: it.clothes_uuid, processed_image: it.processed_image } as ClothesItem
}
})
)
this.setData({ clothes })
// 点赞状态:失败静默保持默认,不影响详情展示
request<{ is_liked: boolean; like_count: number }>({
@@ -267,6 +270,12 @@ Page({
},
onLike() {
// 防连点:请求进行中忽略后续点击,避免误触/连点并发发出多条点赞、取消请求
if ((this as any).liking) {
logger.debug(LOG, '点赞请求进行中,忽略重复点击')
return
}
;(this as any).liking = true
const action = this.data.isLiked ? 2 : 1
request({ url: '/like', method: 'POST', data: { target_uuid: this.data.uuid, action } })
.then(() => {
@@ -277,6 +286,9 @@ Page({
})
})
.catch((e: any) => logger.warn(LOG, '点赞操作失败, action=', action, 'code=', e && e.code))
.finally(() => {
;(this as any).liking = false
})
},
onCollect() {
@@ -416,14 +428,12 @@ Page({
onItemTap(e: WechatMiniprogram.TouchEvent) {
const uuid = e.currentTarget.dataset.uuid as string
// 非属主无权读取衣物详情(50005),点击仅提示;属主正常跳转。
if (!this.data.isOwner) {
logger.debug(LOG, '非属主点击衣物,仅可查看穿搭, uuid=', uuid)
wx.showToast({ title: '仅可查看穿搭', icon: 'none' })
return
}
// 非属主(社区公开穿搭 / 他人分享)携带本穿搭 uuid 进入只读详情,
// 后端据此放行;不携带时后端会按无权限拒绝(50005)。
const query = this.data.isOwner ? '' : `&outfit_uuid=${this.data.uuid}`
logger.debug(LOG, '点击单品, uuid=', uuid, 'isOwner=', this.data.isOwner)
wx.navigateTo({
url: `/pages/clothes-detail/clothes-detail?uuid=${uuid}`,
url: `/pages/clothes-detail/clothes-detail?uuid=${uuid}${query}`,
fail: (err) => logger.warn(LOG, 'navigateTo 单品详情失败, err=', err && err.errMsg),
})
},