import { request } from '../../utils/request' import { OutfitItem, ClothesItem } from '../../types/models' import { IsPublic } from '../../utils/config' import { logger } from '../../utils/logger' // 日志模块名 const LOG = 'outfit-detail' Page({ data: { uuid: '', isOwner: true, outfit: {} as OutfitItem, clothes: [] as ClothesItem[], isLiked: false, likeCount: 0, isCollected: false, loading: true, }, onLoad(query: Record) { const uuid = query.uuid || '' const isOwner = query.owner !== '0' logger.debug(LOG, 'onLoad, uuid=', uuid, 'isOwner=', isOwner) this.setData({ uuid, isOwner }) if (uuid) this.fetchDetail() else logger.warn(LOG, 'onLoad 缺少 uuid 参数') }, async fetchDetail() { try { const outfit = await request({ url: `/outfit/${this.data.uuid}` }) logger.debug(LOG, '穿搭详情加载成功, 单品数=', outfit.items && outfit.items.length) this.setData({ outfit }) const clothes = await Promise.all( outfit.items.map(async (it) => { try { return await request({ 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 } as ClothesItem } }) ) this.setData({ clothes }) const like = await request<{ is_liked: boolean; like_count: number }>({ url: `/like/${this.data.uuid}`, showError: false, }) this.setData({ isLiked: like.is_liked, likeCount: like.like_count, loading: false }) // 收藏状态:调用后端 /collect/:targetUUID 初始化,失败静默保持未收藏 request<{ is_collected: boolean; collect_count: number }>({ url: `/collect/${this.data.uuid}`, showError: false, }) .then((collect) => this.setData({ isCollected: collect.is_collected })) .catch((e: any) => logger.warn(LOG, '收藏状态拉取失败(保持未收藏), code=', e && e.code)) } catch (e: any) { logger.warn(LOG, '穿搭详情加载失败, code=', e && e.code) this.setData({ loading: false }) } }, onLike() { const action = this.data.isLiked ? 2 : 1 request({ url: '/like', method: 'POST', data: { target_uuid: this.data.uuid, action } }) .then(() => { logger.debug(LOG, '点赞操作成功, action=', action) this.setData({ isLiked: action === 1, likeCount: this.data.likeCount + (action === 1 ? 1 : -1), }) }) .catch((e: any) => logger.warn(LOG, '点赞操作失败, action=', action, 'code=', e && e.code)) }, onCollect() { const action = this.data.isCollected ? 2 : 1 request({ url: '/collect', method: 'POST', data: { target_uuid: this.data.uuid, action } }) .then(() => this.setData({ isCollected: action === 1 })) .catch((e: any) => logger.warn(LOG, '收藏操作失败, action=', action, 'code=', e && e.code)) }, onTogglePublic() { const isPublic = this.data.outfit.is_public === IsPublic.PUBLIC if (isPublic) { this.doPublic(IsPublic.PRIVATE) } else { wx.showModal({ title: '公开到社区', content: '公开后将展示在社区供他人点赞收藏,并消耗 1 次社区分享额度', confirmText: '确认公开', success: (res) => { if (res.confirm) this.doPublic(IsPublic.PUBLIC) }, fail: (e) => logger.warn(LOG, '公开弹窗失败, err=', e && e.errMsg), }) } }, doPublic(isPublic: number) { // 后端 OutfitPublicRequest.OutfitUUID 为必填(binding required),请求体需携带 request({ url: `/outfit/${this.data.uuid}/public`, method: 'PUT', data: { outfit_uuid: this.data.uuid, is_public: isPublic }, }) .then(() => { logger.info(LOG, '公开状态变更成功, isPublic=', isPublic) this.setData({ 'outfit.is_public': isPublic }) wx.showToast({ title: isPublic === IsPublic.PUBLIC ? '已公开' : '已取消公开', icon: 'none' }) }) .catch((e: any) => logger.warn(LOG, '公开状态变更失败, code=', e && e.code)) }, onMore() { wx.showActionSheet({ itemList: ['编辑穿搭', '删除穿搭'], success: (res) => { if (res.tapIndex === 0) this.onEdit() else this.onDelete() }, fail: (e) => logger.debug(LOG, '取消更多操作, err=', e && e.errMsg), }) }, onEdit() { wx.navigateTo({ url: `/pages/outfit-edit/outfit-edit?uuid=${this.data.uuid}`, fail: (e) => logger.warn(LOG, 'navigateTo 编辑穿搭失败, err=', e && e.errMsg), }) }, onDelete() { wx.showModal({ title: '确认删除这套穿搭?', content: '删除后不可恢复,但不会影响衣橱内的单品。', confirmText: '确认删除', confirmColor: '#FF3B30', success: (res) => { if (!res.confirm) return request({ url: `/outfit/${this.data.uuid}`, method: 'DELETE' }) .then(() => { logger.info(LOG, '穿搭删除成功') wx.showToast({ title: '已删除', icon: 'success' }) setTimeout( () => wx.navigateBack({ fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg), }), 500, ) }) .catch((e: any) => logger.warn(LOG, '穿搭删除失败, code=', e && e.code)) }, fail: (e) => logger.warn(LOG, '删除弹窗失败, err=', e && e.errMsg), }) }, onItemTap(e: WechatMiniprogram.TouchEvent) { const uuid = e.currentTarget.dataset.uuid as string wx.navigateTo({ url: `/pages/clothes-detail/clothes-detail?uuid=${uuid}`, fail: (err) => logger.warn(LOG, 'navigateTo 单品详情失败, err=', err && err.errMsg), }) }, onShareAppMessage() { return { title: this.data.outfit.outfit_name || '我的穿搭', path: `/pages/outfit-detail/outfit-detail?uuid=${this.data.uuid}&owner=0`, } }, })