import { request } from '../../utils/request' import { AiRecommendResult, ClothesItem } from '../../types/models' import { logger } from '../../utils/logger' // 日志模块名 const LOG = 'ai-recommend' Page({ data: { state: 'scene' as 'scene' | 'generating' | 'result' | 'empty', showSceneSheet: true, sceneType: 1, scene: '', result: null as AiRecommendResult | null, clothes: [] as ClothesItem[], generating: false, }, noop() {}, selectDaily() { this.setData({ sceneType: 1 }) }, selectCustom() { this.setData({ sceneType: 2 }) }, onSceneInput(e: WechatMiniprogram.Input) { this.setData({ scene: e.detail.value }) }, onSkipScene() { this.setData({ showSceneSheet: false }) this.startGenerate(1, '') }, onStartGenerate() { this.setData({ showSceneSheet: false }) this.startGenerate(this.data.sceneType, this.data.scene) }, startGenerate(sceneType: number, scene: string) { if (this.data.generating) return wx.showModal({ title: 'AI 穿搭推荐', content: '本次将消耗 1 次 AI 推荐额度,生成后可保存到我的穿搭', confirmText: '开始生成', cancelText: '取消', success: (res) => { if (res.confirm) this.doGenerate(sceneType, scene) }, fail: (e) => logger.debug(LOG, '取消生成确认, err=', e && e.errMsg), }) }, doGenerate(sceneType: number, scene: string) { if (this.data.generating) return this.setData({ state: 'generating', generating: true }) const body: Record = { scene_type: sceneType } if (sceneType === 2 && scene) body.scene = scene request({ url: '/ai-recommend', method: 'POST', data: body, showError: false }) .then(async (res) => { logger.info(LOG, 'AI 推荐生成成功, 单品数=', res.outfit_item && res.outfit_item.length) const clothes = await Promise.all( res.outfit_item.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({ result: res, clothes, state: 'result', generating: false }) }) .catch((e: any) => { this.setData({ generating: false }) const code = e && e.code logger.warn(LOG, 'AI 推荐生成失败, code=', code) if (code === 90400) { this.setData({ state: 'empty' }) } else if (code === 90401) { this.setData({ state: 'scene', showSceneSheet: true }) this.showLimitModal() } else if (code === 10003) { wx.showToast({ title: '正在生成中,请稍候', icon: 'none' }) this.setData({ state: 'scene', showSceneSheet: true }) } else { this.setData({ state: 'scene', showSceneSheet: true }) } }) }, showLimitModal() { wx.showModal({ title: 'AI 推荐额度不足', content: '购买额度包后可继续生成 AI 穿搭推荐', confirmText: '去购买', cancelText: '取消', success: (res) => { if (res.confirm) { wx.navigateTo({ url: '/pages/mall/mall', fail: (e) => logger.warn(LOG, 'navigateTo 商城失败, err=', e && e.errMsg), }) } }, fail: (e) => logger.warn(LOG, '额度弹窗失败, err=', e && e.errMsg), }) }, onSave() { if (!this.data.result) return request({ url: '/ai-recommend/save', method: 'POST', data: { outfit_uuid: this.data.result.outfit_uuid }, }) .then(() => { logger.info(LOG, 'AI 穿搭保存成功') wx.showToast({ title: '已保存到我的穿搭', icon: 'success' }) setTimeout(() => { wx.redirectTo({ url: `/pages/outfit-detail/outfit-detail?uuid=${this.data.result!.outfit_uuid}&owner=1`, fail: (e) => logger.warn(LOG, 'redirectTo 穿搭详情失败, err=', e && e.errMsg), }) }, 500) }) .catch((e: any) => logger.warn(LOG, 'AI 穿搭保存失败, code=', e && e.code)) }, onReroll() { this.startGenerate(this.data.sceneType, this.data.scene) }, onGoUpload() { wx.navigateTo({ url: '/pages/upload/upload', fail: (e) => logger.warn(LOG, 'navigateTo 上传页失败, err=', e && e.errMsg), }) }, })