bugfix
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { request } from '../../utils/request'
|
||||
import { AiRecommendResult, ClothesItem } from '../../types/models'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'ai-recommend'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -46,6 +50,7 @@ Page({
|
||||
success: (res) => {
|
||||
if (res.confirm) this.doGenerate(sceneType, scene)
|
||||
},
|
||||
fail: (e) => logger.debug(LOG, '取消生成确认, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -58,11 +63,13 @@ Page({
|
||||
|
||||
request<AiRecommendResult>({ 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<ClothesItem>({ url: `/clothes/${it.clothes_uuid}`, showError: false })
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '单品详情拉取失败, uuid=', it.clothes_uuid, 'code=', e && e.code)
|
||||
return { clothes_uuid: it.clothes_uuid } as ClothesItem
|
||||
}
|
||||
})
|
||||
@@ -72,6 +79,7 @@ Page({
|
||||
.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) {
|
||||
@@ -93,8 +101,14 @@ Page({
|
||||
confirmText: '去购买',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) wx.navigateTo({ url: '/pages/mall/mall' })
|
||||
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),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -106,14 +120,16 @@ Page({
|
||||
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(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, 'AI 穿搭保存失败, code=', e && e.code))
|
||||
},
|
||||
|
||||
onReroll() {
|
||||
@@ -121,6 +137,9 @@ Page({
|
||||
},
|
||||
|
||||
onGoUpload() {
|
||||
wx.navigateTo({ url: '/pages/upload/upload' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/upload/upload',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 上传页失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -2,6 +2,10 @@ import { request } from '../../utils/request'
|
||||
import { ClothesItem, PagedResult, UserInfo } from '../../types/models'
|
||||
import { STORAGE_KEYS } from '../../utils/config'
|
||||
import { normalizePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'closet-share-create'
|
||||
|
||||
const CATEGORIES = [
|
||||
{ name: '全部', value: '' },
|
||||
@@ -55,10 +59,11 @@ Page({
|
||||
// 头像为带时间戳的签名 URL,缓存可能过期,实时刷新并回写缓存。
|
||||
request<UserInfo>({ url: '/user/info', showError: false })
|
||||
.then((user) => {
|
||||
logger.debug(LOG, '用户信息加载成功')
|
||||
wx.setStorageSync(STORAGE_KEYS.USER_INFO, user)
|
||||
this.setData({ nickname: user.username || '微信用户', avatar: user.avatar || '' })
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '用户信息加载失败(用缓存兜底), code=', e && e.code))
|
||||
},
|
||||
|
||||
selectPartial() {
|
||||
@@ -91,6 +96,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<ClothesItem>(res)
|
||||
logger.debug(LOG, '衣物列表加载成功, 分类=', cat || '全部', 'page=', page, '条数=', raw && raw.length)
|
||||
const list = raw.map((it) => ({
|
||||
...it,
|
||||
_selected: this.data.selectedUuids.indexOf(it.clothes_uuid) >= 0,
|
||||
@@ -104,8 +110,9 @@ Page({
|
||||
hasMore: hasMorePaged(merged, total, PAGE_SIZE),
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '衣物列表加载失败, page=', page, 'code=', e && e.code)
|
||||
this.setData({ selectLoading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -168,15 +175,26 @@ Page({
|
||||
// 提交加锁:连点会重复创建分享、重复扣额度
|
||||
this.setData({ submitting: true })
|
||||
request<{ share_uuid: string }>({ url: '/closet-share', method: 'POST', data: body })
|
||||
.then((res) => this.setData({ shareUuid: res.share_uuid, view: 'success', submitting: false }))
|
||||
.catch(() => this.setData({ submitting: false }))
|
||||
.then((res) => {
|
||||
logger.info(LOG, '分享创建成功, uuid=', res.share_uuid)
|
||||
this.setData({ shareUuid: res.share_uuid, view: 'success', submitting: false })
|
||||
})
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '分享创建失败, code=', e && e.code)
|
||||
this.setData({ submitting: false })
|
||||
})
|
||||
},
|
||||
|
||||
onViewShare() {
|
||||
wx.redirectTo({ url: `/pages/closet-share-detail/closet-share-detail?uuid=${this.data.shareUuid}` })
|
||||
wx.redirectTo({
|
||||
url: `/pages/closet-share-detail/closet-share-detail?uuid=${this.data.shareUuid}`,
|
||||
fail: (e) => logger.warn(LOG, 'redirectTo 分享详情失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onDone() {
|
||||
wx.navigateBack()
|
||||
wx.navigateBack({
|
||||
fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -2,6 +2,10 @@ import { request, AUTH_EXPIRED_CODES } from '../../utils/request'
|
||||
import { ClosetShareDetail } from '../../types/models'
|
||||
import { ShareStatus } from '../../utils/config'
|
||||
import { formatDateTime } from '../../utils/format'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'closet-share-detail'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -17,9 +21,11 @@ Page({
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
const uuid = query.uuid || ''
|
||||
logger.debug(LOG, 'onLoad, uuid=', uuid)
|
||||
this.setData({ uuid })
|
||||
if (!uuid) {
|
||||
// uuid 缺失时若不兜底,loading 会永久为 true,页面白屏且无法退出
|
||||
logger.warn(LOG, 'onLoad 缺少 uuid 参数')
|
||||
this.setInvalid('链接不完整', '缺少分享标识,无法打开')
|
||||
return
|
||||
}
|
||||
@@ -30,6 +36,7 @@ Page({
|
||||
request<ClosetShareDetail>({ url: `/closet-share/${this.data.uuid}`, showError: false })
|
||||
.then((detail) => {
|
||||
// 后端可能惰性过期:本地再校验一次状态与有效期,避免展示已失效内容
|
||||
logger.debug(LOG, '详情加载成功, status=', detail && detail.status)
|
||||
if (this.checkInvalid(detail)) return
|
||||
|
||||
const expireText =
|
||||
@@ -38,6 +45,7 @@ Page({
|
||||
})
|
||||
.catch((e: any) => {
|
||||
const code = e && e.code
|
||||
logger.warn(LOG, '详情加载失败, code=', code)
|
||||
if (AUTH_EXPIRED_CODES.indexOf(code) >= 0) {
|
||||
// 查看分享需登录:给「去登录」出口,登录成功后回到本页
|
||||
this.setData({
|
||||
@@ -100,16 +108,27 @@ Page({
|
||||
if (!res.confirm) return
|
||||
request({ url: `/closet-share/${this.data.uuid}/cancel`, method: 'POST' })
|
||||
.then(() => {
|
||||
logger.info(LOG, '取消分享成功')
|
||||
wx.showToast({ title: '已取消', icon: 'success' })
|
||||
;(this as any).backTimer = setTimeout(() => wx.navigateBack(), 500)
|
||||
;(this as any).backTimer = setTimeout(
|
||||
() =>
|
||||
wx.navigateBack({
|
||||
fail: (e: any) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
}),
|
||||
500,
|
||||
)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '取消分享失败, code=', e && e.code))
|
||||
},
|
||||
fail: (e: any) => logger.warn(LOG, '取消分享弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onBackHome() {
|
||||
wx.switchTab({ url: '/pages/wardrobe/wardrobe' })
|
||||
wx.switchTab({
|
||||
url: '/pages/wardrobe/wardrobe',
|
||||
fail: (e: any) => logger.warn(LOG, 'switchTab 衣橱失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onGoLogin() {
|
||||
@@ -120,12 +139,15 @@ Page({
|
||||
fail: (e) => {
|
||||
// 页面栈满(10 层)时 navigateTo 失败:改用 redirectTo 仍跳登录页,
|
||||
// 且保留 redirect 参数(原先跳 profile 会丢失来源,登录后回不到分享页)
|
||||
console.log('[share-detail] navigateTo 登录页失败,改用 redirectTo, err=', e && e.errMsg)
|
||||
logger.warn(LOG, 'navigateTo 登录页失败,改用 redirectTo, err=', e && e.errMsg)
|
||||
wx.redirectTo({
|
||||
url: loginUrl,
|
||||
fail: (e2) => {
|
||||
console.log('[share-detail] redirectTo 登录页也失败, err=', e2 && e2.errMsg)
|
||||
wx.switchTab({ url: '/pages/profile/profile' })
|
||||
logger.warn(LOG, 'redirectTo 登录页也失败,退回首页, err=', e2 && e2.errMsg)
|
||||
wx.switchTab({
|
||||
url: '/pages/profile/profile',
|
||||
fail: (e3: any) => logger.warn(LOG, 'switchTab 我的失败, err=', e3 && e3.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -134,6 +156,7 @@ Page({
|
||||
|
||||
onShareAppMessage() {
|
||||
const name = (this.data.detail && this.data.detail.owner_name) || '好友'
|
||||
logger.debug(LOG, '转发分享, uuid=', this.data.uuid)
|
||||
return {
|
||||
title: `${name} 向你分享了 TA 的衣柜`,
|
||||
path: `/pages/closet-share-detail/closet-share-detail?uuid=${this.data.uuid}`,
|
||||
|
||||
@@ -3,6 +3,11 @@ import * as auth from '../../utils/auth'
|
||||
import { PagedResult, ClosetShareItem } from '../../types/models'
|
||||
import { ShareStatus, ShareType } from '../../utils/config'
|
||||
import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { setTabBarSelected } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'closet-share'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -30,8 +35,7 @@ Page({
|
||||
},
|
||||
|
||||
syncTabBar() {
|
||||
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
||||
if (tabBar) tabBar.setData({ selected: 3 })
|
||||
setTabBarSelected(3)
|
||||
},
|
||||
|
||||
onTabTap(e: WechatMiniprogram.TouchEvent) {
|
||||
@@ -63,6 +67,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<ClosetShareItem>(res)
|
||||
logger.debug(LOG, '列表加载成功, tab=', this.data.activeTab, 'page=', page, '条数=', raw && raw.length)
|
||||
const list = raw.map((it) => this.decorate(it))
|
||||
const merged = mergePaged(this.data.list, list, page === 1)
|
||||
this.setData({
|
||||
@@ -73,8 +78,9 @@ Page({
|
||||
page,
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '列表加载失败, tab=', this.data.activeTab, 'page=', page, 'code=', e && e.code)
|
||||
this.setData({ loading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -108,11 +114,18 @@ Page({
|
||||
},
|
||||
|
||||
onCreate() {
|
||||
wx.navigateTo({ url: '/pages/closet-share-create/closet-share-create' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/closet-share-create/closet-share-create',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 创建分享失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onItemTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const uuid = e.currentTarget.dataset.uuid as string
|
||||
wx.navigateTo({ url: `/pages/closet-share-detail/closet-share-detail?uuid=${uuid}` })
|
||||
logger.debug(LOG, '点击分享项, uuid=', uuid)
|
||||
wx.navigateTo({
|
||||
url: `/pages/closet-share-detail/closet-share-detail?uuid=${uuid}`,
|
||||
fail: (err) => logger.warn(LOG, 'navigateTo 分享详情失败, err=', err && err.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { request } from '../../utils/request'
|
||||
import { ClothesItem } from '../../types/models'
|
||||
import { ProcessStatus } from '../../utils/config'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'clothes-detail'
|
||||
|
||||
const ATTRS = [
|
||||
{ key: 'category_main', label: '大类', type: 'text' },
|
||||
@@ -44,9 +48,11 @@ Page({
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
const uuid = query.uuid || ''
|
||||
logger.debug(LOG, 'onLoad, uuid=', uuid)
|
||||
this.setData({ uuid })
|
||||
if (!uuid) {
|
||||
// uuid 缺失时不请求不轮询,否则会停在空白页且无法退出
|
||||
logger.warn(LOG, 'onLoad 缺少 uuid 参数')
|
||||
this.setData({ loading: false, notFound: true })
|
||||
return
|
||||
}
|
||||
@@ -55,13 +61,22 @@ Page({
|
||||
},
|
||||
|
||||
onBackWardrobe() {
|
||||
wx.switchTab({ url: '/pages/wardrobe/wardrobe' })
|
||||
wx.switchTab({
|
||||
url: '/pages/wardrobe/wardrobe',
|
||||
fail: (e) => logger.warn(LOG, 'switchTab 衣橱失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
fetchDetail(): Promise<void> {
|
||||
return request<ClothesItem>({ url: `/clothes/${this.data.uuid}` })
|
||||
.then((detail) => this.setData({ detail, loading: false }))
|
||||
.catch(() => this.setData({ loading: false }))
|
||||
.then((detail) => {
|
||||
logger.debug(LOG, '详情加载成功, 处理状态=', detail && detail.image_process_status)
|
||||
this.setData({ detail, loading: false })
|
||||
})
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '详情加载失败, code=', e && e.code)
|
||||
this.setData({ loading: false })
|
||||
})
|
||||
},
|
||||
|
||||
pollStatus() {
|
||||
@@ -77,17 +92,20 @@ Page({
|
||||
if (status === ProcessStatus.SUCCESS) {
|
||||
// 成功:先拉最新详情,再切换为详情视图,避免空属性闪烁
|
||||
this.clearTimer()
|
||||
logger.info(LOG, 'AI 处理完成')
|
||||
this.fetchDetail().then(() => this.setData({ imageStatus: status, step: 2 }))
|
||||
} else if (status === ProcessStatus.FAILED) {
|
||||
this.clearTimer()
|
||||
logger.warn(LOG, 'AI 识别失败, 原因=', res.fail_reason)
|
||||
this.setData({ imageStatus: status, failReason: res.fail_reason || '识别失败' })
|
||||
} else {
|
||||
this.setData({ imageStatus: status, step: statusToStep(status) })
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '状态轮询失败, code=', e && e.code))
|
||||
if (count >= 120) {
|
||||
this.clearTimer()
|
||||
logger.warn(LOG, '状态轮询超时(240s),停止轮询')
|
||||
}
|
||||
}, 2000)
|
||||
},
|
||||
@@ -178,11 +196,12 @@ Page({
|
||||
|
||||
request({ url: `/clothes/${this.data.uuid}`, method: 'PUT', data: body })
|
||||
.then(() => {
|
||||
logger.info(LOG, '衣物信息保存成功')
|
||||
wx.showToast({ title: '已保存', icon: 'success' })
|
||||
this.setData({ editMode: false })
|
||||
this.fetchDetail()
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '衣物信息保存失败, code=', e && e.code))
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
@@ -197,11 +216,19 @@ Page({
|
||||
if (!res.confirm) return
|
||||
request({ url: `/clothes/${this.data.uuid}`, method: 'DELETE' })
|
||||
.then(() => {
|
||||
logger.info(LOG, '衣物删除成功')
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
setTimeout(() => wx.navigateBack(), 500)
|
||||
setTimeout(
|
||||
() =>
|
||||
wx.navigateBack({
|
||||
fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
}),
|
||||
500,
|
||||
)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '衣物删除失败, code=', e && e.code))
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '删除弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { request, redirectToLogin } from '../../utils/request'
|
||||
import * as auth from '../../utils/auth'
|
||||
import { HoroscopeData } from '../../types/models'
|
||||
import { setTabBarSelected } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'horoscope'
|
||||
|
||||
const COLOR_MAP: Record<string, string> = {
|
||||
红色: '#FF3B30',
|
||||
@@ -47,8 +52,7 @@ Page({
|
||||
},
|
||||
|
||||
syncTabBar() {
|
||||
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
||||
if (tabBar) tabBar.setData({ selected: 2 })
|
||||
setTabBarSelected(2)
|
||||
},
|
||||
|
||||
fetchHoroscope(retry: number) {
|
||||
@@ -56,6 +60,7 @@ Page({
|
||||
this.setData({ loading: true, error: false, errorText: '' })
|
||||
request<HoroscopeData>({ url: '/horoscope/today', showError: false })
|
||||
.then((res) => {
|
||||
logger.debug(LOG, '运势加载成功, statDate=', res && res.stat_date)
|
||||
this.setData({
|
||||
horoscope: res,
|
||||
statDate: this.formatStatDate(res.stat_date),
|
||||
@@ -67,6 +72,7 @@ Page({
|
||||
})
|
||||
.catch((e: any) => {
|
||||
const code = e && e.code
|
||||
logger.warn(LOG, '运势加载失败, code=', code, 'retry=', retry)
|
||||
const details = (e && e.details) || []
|
||||
const noBirth = details.some((d: string) => d.indexOf('生日') >= 0)
|
||||
if (code === 10000 && noBirth) {
|
||||
@@ -104,11 +110,17 @@ Page({
|
||||
},
|
||||
|
||||
onGoProfile() {
|
||||
wx.switchTab({ url: '/pages/profile/profile' })
|
||||
wx.switchTab({
|
||||
url: '/pages/profile/profile',
|
||||
fail: (e) => logger.warn(LOG, 'switchTab 个人资料失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onGenerate() {
|
||||
wx.navigateTo({ url: '/pages/ai-recommend/ai-recommend' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/ai-recommend/ai-recommend',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo AI 推荐失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { request } from '../../utils/request'
|
||||
import * as auth from '../../utils/auth'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'login'
|
||||
import { STORAGE_KEYS, QuotaType } from '../../utils/config'
|
||||
import { LoginResult, UserInfo, QuotaItem } from '../../types/models'
|
||||
import { formatDate } from '../../utils/format'
|
||||
@@ -20,7 +24,7 @@ Page({
|
||||
},
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
console.log('[login] onLoad, query=', JSON.stringify(query), 'isLoggedIn=', auth.isLoggedIn())
|
||||
logger.debug(LOG, 'onLoad, query=', JSON.stringify(query), 'isLoggedIn=', auth.isLoggedIn())
|
||||
if (query.redirect) this.setData({ redirect: query.redirect })
|
||||
if (auth.isLoggedIn()) {
|
||||
this.goAfterLogin()
|
||||
@@ -30,12 +34,12 @@ Page({
|
||||
// 登录完成后的落地页:带 redirect 时回跳来源页(分享详情等),否则进衣橱
|
||||
goAfterLogin(fallback = false) {
|
||||
const redirect = this.data.redirect
|
||||
console.log('[login] goAfterLogin, redirect=', redirect, 'fallback=', fallback)
|
||||
logger.debug(LOG, 'goAfterLogin, redirect=', redirect, 'fallback=', fallback)
|
||||
if (redirect && !fallback) {
|
||||
wx.redirectTo({
|
||||
url: redirect,
|
||||
fail: (e) => {
|
||||
console.log('[login] redirect 失败,回退衣橱, err=', e && e.errMsg)
|
||||
logger.warn(LOG, 'redirect 回跳失败,回退衣橱, err=', e && e.errMsg)
|
||||
this.goAfterLogin(true)
|
||||
},
|
||||
})
|
||||
@@ -43,16 +47,16 @@ Page({
|
||||
}
|
||||
wx.switchTab({
|
||||
url: '/pages/wardrobe/wardrobe',
|
||||
fail: (e) => console.log('[login] switchTab 衣橱失败, err=', e && e.errMsg),
|
||||
fail: (e) => logger.warn(LOG, 'switchTab 衣橱失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onLogin() {
|
||||
if (this.data.loading) {
|
||||
console.log('[login] 登录中,忽略重复点击')
|
||||
logger.debug(LOG, '登录中,忽略重复点击')
|
||||
return
|
||||
}
|
||||
console.log('[login] 点击登录, redirect=', this.data.redirect)
|
||||
logger.debug(LOG, '点击登录, redirect=', this.data.redirect)
|
||||
this.setData({ loading: true })
|
||||
|
||||
// 超时兜底:wx.login / wx.request 异常挂起时复位按钮,避免永久 loading 点不动
|
||||
@@ -60,7 +64,7 @@ Page({
|
||||
;(this as any).loginTimer = setTimeout(() => {
|
||||
;(this as any).loginTimer = null
|
||||
if (!this.data.loading) return
|
||||
console.log('[login] 登录超时(30s),复位按钮')
|
||||
logger.warn(LOG, '登录超时(30s),复位按钮')
|
||||
this.setData({ loading: false })
|
||||
wx.showToast({ title: '登录超时,请重试', icon: 'none' })
|
||||
}, 30000)
|
||||
@@ -68,12 +72,12 @@ Page({
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (!res.code) {
|
||||
console.log('[login] wx.login 返回空 code')
|
||||
logger.error(LOG, 'wx.login 返回空 code')
|
||||
this.finishLogin()
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
console.log('[login] wx.login 成功, codeLen=', res.code.length)
|
||||
logger.debug(LOG, 'wx.login 成功, codeLen=', res.code.length)
|
||||
request<LoginResult>({
|
||||
url: '/user/wxlogin',
|
||||
method: 'POST',
|
||||
@@ -81,8 +85,9 @@ Page({
|
||||
auth: false,
|
||||
})
|
||||
.then((data) => {
|
||||
console.log(
|
||||
'[login] wxlogin 成功, isNew=',
|
||||
logger.info(
|
||||
LOG,
|
||||
'wxlogin 成功, isNew=',
|
||||
data.user_info && data.user_info.is_new_user,
|
||||
'expireTime=',
|
||||
data.expire_time,
|
||||
@@ -105,7 +110,7 @@ Page({
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log('[login] wxlogin 失败, code=', e && e.code, 'msg=', e && e.message)
|
||||
logger.error(LOG, 'wxlogin 失败, code=', e && e.code, 'msg=', e && e.message)
|
||||
})
|
||||
.then(() => {
|
||||
// 无论成功还是失败都复位:分支走向礼包/生日引导时若不复位,登录按钮会永久点不动
|
||||
@@ -113,7 +118,7 @@ Page({
|
||||
})
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log('[login] wx.login 失败, errMsg=', e && e.errMsg)
|
||||
logger.error(LOG, 'wx.login 失败, errMsg=', e && e.errMsg)
|
||||
this.finishLogin()
|
||||
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
|
||||
},
|
||||
@@ -142,7 +147,11 @@ Page({
|
||||
// 额度只用于礼包展示:失败静默降级,绝不能触发登出/清 token
|
||||
request<{ quotas: QuotaItem[] }>({ url: '/quota/info', showError: false, silentAuth: true })
|
||||
.then((res) => this.setData({ giftItems: this.buildGift(userInfo, res.quotas), giftVisible: true }))
|
||||
.catch(() => this.setData({ giftItems: this.buildGift(userInfo, []), giftVisible: true }))
|
||||
.catch((e) => {
|
||||
// 额度拉取失败不阻塞礼包展示,降级为空额度;绝不能触发登出/清 token
|
||||
logger.warn(LOG, '礼包额度拉取失败,降级展示, code=', e && e.code)
|
||||
this.setData({ giftItems: this.buildGift(userInfo, []), giftVisible: true })
|
||||
})
|
||||
},
|
||||
|
||||
buildGift(userInfo: UserInfo, quotas: QuotaItem[]): GiftItem[] {
|
||||
@@ -177,9 +186,16 @@ Page({
|
||||
confirmText: '去完善',
|
||||
cancelText: '稍后再说',
|
||||
success: (res) => {
|
||||
if (res.confirm) wx.switchTab({ url: '/pages/profile/profile' })
|
||||
else this.goAfterLogin()
|
||||
if (res.confirm) {
|
||||
wx.switchTab({
|
||||
url: '/pages/profile/profile',
|
||||
fail: (e) => logger.warn(LOG, 'switchTab 个人资料失败, err=', e && e.errMsg),
|
||||
})
|
||||
} else {
|
||||
this.goAfterLogin()
|
||||
}
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '生日引导弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@ import { QuotaItem, UserInfo, GoodsItem, QuotaFlowItem, PagedResult, VirtualPayR
|
||||
import { QUOTA_NAMES, GoodsType, GOODS_TYPE_NAMES } from '../../utils/config'
|
||||
import { fenToYuan, formatDate, formatDateTime } from '../../utils/format'
|
||||
import { normalizePaged } from '../../utils/paged'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'mall'
|
||||
|
||||
const GOODS_ICONS: Record<number, string> = {
|
||||
[GoodsType.MEMBER]: 'icon-crown',
|
||||
@@ -54,6 +58,7 @@ Page({
|
||||
},
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
logger.debug(LOG, 'onLoad, query=', JSON.stringify(query))
|
||||
if (query.tab === 'flow') this.setData({ view: 'flow' })
|
||||
},
|
||||
|
||||
@@ -67,6 +72,7 @@ Page({
|
||||
fetchUser() {
|
||||
request<UserInfo>({ url: '/user/info', showError: false })
|
||||
.then((user) => {
|
||||
logger.debug(LOG, '用户信息加载成功, vipType=', user.vip_type)
|
||||
const isVip = user.vip_type !== 1
|
||||
this.setData({
|
||||
userInfo: user,
|
||||
@@ -74,7 +80,7 @@ Page({
|
||||
vipExpireText: isVip && user.vip_expire ? `有效期至 ${formatDate(user.vip_expire)}` : '',
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '用户信息加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
fetchQuota() {
|
||||
@@ -87,7 +93,7 @@ Page({
|
||||
}))
|
||||
this.setData({ quotas })
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '额度加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
fetchGoods() {
|
||||
@@ -103,9 +109,13 @@ Page({
|
||||
_priceText: fenToYuan(g.discount_price),
|
||||
_originText: fenToYuan(g.price),
|
||||
}))
|
||||
logger.debug(LOG, '商品列表加载成功, 条数=', goods.length)
|
||||
this.setData({ goods, loading: false })
|
||||
})
|
||||
.catch(() => this.setData({ loading: false }))
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '商品列表加载失败, code=', e && e.code)
|
||||
this.setData({ loading: false })
|
||||
})
|
||||
},
|
||||
|
||||
fetchFlow() {
|
||||
@@ -119,7 +129,7 @@ Page({
|
||||
}))
|
||||
this.setData({ flowList: list })
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '额度流水加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
onGoodsFilter(e: WechatMiniprogram.TouchEvent) {
|
||||
@@ -166,13 +176,18 @@ Page({
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
logger.info(LOG, '下单成功, orderNo=', res.order_no)
|
||||
this.setData({ orderVisible: false, submitting: false })
|
||||
this.doPayment(res)
|
||||
})
|
||||
.catch(() => this.setData({ submitting: false }))
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '下单失败, code=', e && e.code)
|
||||
this.setData({ submitting: false })
|
||||
})
|
||||
},
|
||||
|
||||
doPayment(res: VirtualPayResult) {
|
||||
logger.debug(LOG, '拉起虚拟支付, orderNo=', res.order_no)
|
||||
wx.requestVirtualPayment({
|
||||
signData: res.sign_data,
|
||||
paySig: res.pay_sig,
|
||||
@@ -180,9 +195,12 @@ Page({
|
||||
mode: 'short_series_goods',
|
||||
success: () => {
|
||||
// 拉起成功仅代表进入支付页,最终到账以后端发货推送为准,轮询订单确认
|
||||
logger.info(LOG, '支付页拉起成功, orderNo=', res.order_no)
|
||||
this.pollOrder(res.order_no)
|
||||
},
|
||||
fail: () => {},
|
||||
fail: (e: any) => {
|
||||
logger.error(LOG, '拉起支付失败, orderNo=', res.order_no, 'err=', e && e.errMsg)
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
@@ -196,18 +214,22 @@ Page({
|
||||
const order = normalizePaged<OrderItem>(res).list.find((it) => it.order_no === orderNo)
|
||||
if (order && order.order_status === 2) {
|
||||
this.clearPayTimer()
|
||||
logger.info(LOG, '支付成功, orderNo=', orderNo)
|
||||
wx.showToast({ title: '支付成功', icon: 'success' })
|
||||
this.fetchQuota()
|
||||
this.fetchUser()
|
||||
} else if (order && (order.order_status === 3 || order.order_status === 4 || order.order_status === 5)) {
|
||||
this.clearPayTimer()
|
||||
logger.warn(LOG, '订单未成功支付, orderNo=', orderNo, 'status=', order.order_status)
|
||||
const msg = order.order_status === 5 ? '订单已退款' : '订单未支付成功'
|
||||
wx.showToast({ title: msg, icon: 'none' })
|
||||
} else if (count >= 10) {
|
||||
logger.warn(LOG, '支付轮询超时, orderNo=', orderNo)
|
||||
this.finishPayTimeout()
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '支付轮询请求失败, orderNo=', orderNo, 'code=', e && e.code)
|
||||
if (count >= 10) this.finishPayTimeout()
|
||||
})
|
||||
}, 1500)
|
||||
|
||||
@@ -2,6 +2,10 @@ import { request } from '../../utils/request'
|
||||
import { NotificationItem } from '../../types/models'
|
||||
import { formatDateTime } from '../../utils/format'
|
||||
import { syncTabBarUnread } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'notification-detail'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -12,21 +16,28 @@ Page({
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
const uuid = query.uuid || ''
|
||||
logger.debug(LOG, 'onLoad, uuid=', uuid)
|
||||
this.setData({ uuid })
|
||||
if (uuid) {
|
||||
this.fetchDetail()
|
||||
request({ url: `/notification/${uuid}/read`, method: 'POST', showError: false })
|
||||
.then(() => {
|
||||
// 标记已读后同步红点:本页不是 tab 页,红点不会自动刷新
|
||||
syncTabBarUnread(true)
|
||||
})
|
||||
.catch(() => {})
|
||||
if (!uuid) {
|
||||
logger.warn(LOG, 'onLoad 缺少 uuid 参数')
|
||||
return
|
||||
}
|
||||
this.fetchDetail()
|
||||
request({ url: `/notification/${uuid}/read`, method: 'POST', showError: false })
|
||||
.then(() => {
|
||||
logger.debug(LOG, '标记已读成功')
|
||||
// 标记已读后同步红点:本页不是 tab 页,红点不会自动刷新
|
||||
syncTabBarUnread(true)
|
||||
})
|
||||
.catch((e: any) => logger.warn(LOG, '标记已读失败, code=', e && e.code))
|
||||
},
|
||||
|
||||
fetchDetail() {
|
||||
request<NotificationItem>({ url: `/notification/${this.data.uuid}` })
|
||||
.then((item) => this.setData({ item, time: formatDateTime(item.created_at) }))
|
||||
.catch(() => {})
|
||||
.then((item) => {
|
||||
logger.debug(LOG, '详情加载成功')
|
||||
this.setData({ item, time: formatDateTime(item.created_at) })
|
||||
})
|
||||
.catch((e: any) => logger.warn(LOG, '详情加载失败, code=', e && e.code))
|
||||
},
|
||||
})
|
||||
|
||||
@@ -5,6 +5,10 @@ import { STORAGE_KEYS } from '../../utils/config'
|
||||
import { formatRelativeTime } from '../../utils/format'
|
||||
import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { getTabBarInstance } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'notification'
|
||||
|
||||
const FILTERS = [
|
||||
{ name: '全部', value: 0 },
|
||||
@@ -28,6 +32,7 @@ Page({
|
||||
onShow() {
|
||||
// 未登录直接回登录页(幂等跳转),不再发出必然 401 的请求
|
||||
if (!auth.isLoggedIn()) {
|
||||
logger.debug(LOG, '未登录,跳转登录页')
|
||||
redirectToLogin()
|
||||
return
|
||||
}
|
||||
@@ -42,6 +47,7 @@ Page({
|
||||
silentAuth: true,
|
||||
})
|
||||
.then((res) => {
|
||||
logger.debug(LOG, '未读数加载成功, unread=', res.unread_count)
|
||||
const unread = res.unread_count || 0
|
||||
wx.setStorageSync(STORAGE_KEYS.UNREAD, unread)
|
||||
// 本页不是 tab 页,getTabBar() 恒为 undefined,需从页面栈里取 tab 页的 tabBar
|
||||
@@ -49,7 +55,7 @@ Page({
|
||||
// 直接更新红点,避免 tabBar 内部再发一次请求
|
||||
if (tabBar && tabBar.setUnread) tabBar.setUnread(unread)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '未读数加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
refresh() {
|
||||
@@ -76,6 +82,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<NotificationItem>(res)
|
||||
logger.debug(LOG, '通知加载成功, 筛选=', filter, 'page=', page, '条数=', raw && raw.length)
|
||||
const list = raw.map((it) => ({ ...it, _time: formatRelativeTime(it.created_at) }))
|
||||
const merged = mergePaged(this.data.list, list, page === 1)
|
||||
this.setData({
|
||||
@@ -86,8 +93,9 @@ Page({
|
||||
page,
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '通知加载失败, page=', page, 'code=', e && e.code)
|
||||
this.setData({ loading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -101,6 +109,9 @@ Page({
|
||||
|
||||
onItemTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const uuid = e.currentTarget.dataset.uuid as string
|
||||
wx.navigateTo({ url: `/pages/notification-detail/notification-detail?uuid=${uuid}` })
|
||||
wx.navigateTo({
|
||||
url: `/pages/notification-detail/notification-detail?uuid=${uuid}`,
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 通知详情失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -2,6 +2,10 @@ import { request } from '../../utils/request'
|
||||
import { PagedResult, OrderItem } from '../../types/models'
|
||||
import { fenToYuan, formatDateTime, formatCountdown } from '../../utils/format'
|
||||
import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'order'
|
||||
|
||||
const STATUS_FILTERS = [
|
||||
{ name: '全部', value: 0 },
|
||||
@@ -94,6 +98,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<OrderItem>(res)
|
||||
logger.debug(LOG, '订单加载成功, 筛选=', filter, 'page=', page, '条数=', raw && raw.length)
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const list = raw.map((it) => ({
|
||||
...it,
|
||||
@@ -116,8 +121,9 @@ Page({
|
||||
page,
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '订单加载失败, page=', page, 'code=', e && e.code)
|
||||
this.setData({ loading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -138,11 +144,13 @@ Page({
|
||||
if (!res.confirm) return
|
||||
request({ url: `/order/${orderNo}/cancel`, method: 'POST' })
|
||||
.then(() => {
|
||||
logger.info(LOG, '取消订单成功, orderNo=', orderNo)
|
||||
wx.showToast({ title: '已取消', icon: 'success' })
|
||||
this.refresh()
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '取消订单失败, orderNo=', orderNo, 'code=', e && e.code))
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '取消订单弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -165,15 +173,20 @@ Page({
|
||||
}
|
||||
request({ url: '/order/refund', method: 'POST', data: { order_no: orderNo, reason } })
|
||||
.then(() => {
|
||||
logger.info(LOG, '退款申请提交成功, orderNo=', orderNo)
|
||||
wx.showToast({ title: '退款申请已提交,等待审核', icon: 'none' })
|
||||
this.refresh()
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '退款申请失败, orderNo=', orderNo, 'code=', e && e.code))
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '退款弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onGoMall() {
|
||||
wx.navigateTo({ url: '/pages/mall/mall' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/mall/mall',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 商城失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
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: {
|
||||
@@ -17,20 +21,24 @@ Page({
|
||||
onLoad(query: Record<string, string>) {
|
||||
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<OutfitItem>({ 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<ClothesItem>({ url: `/clothes/${it.clothes_uuid}`, showError: false })
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '单品详情拉取失败, uuid=', it.clothes_uuid, 'code=', e && e.code)
|
||||
return { clothes_uuid: it.clothes_uuid } as ClothesItem
|
||||
}
|
||||
})
|
||||
@@ -49,8 +57,9 @@ Page({
|
||||
showError: false,
|
||||
})
|
||||
.then((collect) => this.setData({ isCollected: collect.is_collected }))
|
||||
.catch(() => {})
|
||||
} catch (e) {
|
||||
.catch((e: any) => logger.warn(LOG, '收藏状态拉取失败(保持未收藏), code=', e && e.code))
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '穿搭详情加载失败, code=', e && e.code)
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
},
|
||||
@@ -59,19 +68,20 @@ Page({
|
||||
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(() => {})
|
||||
.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(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '收藏操作失败, action=', action, 'code=', e && e.code))
|
||||
},
|
||||
|
||||
onTogglePublic() {
|
||||
@@ -86,6 +96,7 @@ Page({
|
||||
success: (res) => {
|
||||
if (res.confirm) this.doPublic(IsPublic.PUBLIC)
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '公开弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -93,10 +104,11 @@ Page({
|
||||
doPublic(isPublic: number) {
|
||||
request({ url: `/outfit/${this.data.uuid}/public`, method: 'PUT', data: { is_public: isPublic } })
|
||||
.then(() => {
|
||||
logger.info(LOG, '公开状态变更成功, isPublic=', isPublic)
|
||||
this.setData({ 'outfit.is_public': isPublic })
|
||||
wx.showToast({ title: isPublic === IsPublic.PUBLIC ? '已公开' : '已取消公开', icon: 'none' })
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '公开状态变更失败, code=', e && e.code))
|
||||
},
|
||||
|
||||
onMore() {
|
||||
@@ -106,11 +118,15 @@ Page({
|
||||
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}` })
|
||||
wx.navigateTo({
|
||||
url: `/pages/outfit-edit/outfit-edit?uuid=${this.data.uuid}`,
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 编辑穿搭失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
@@ -123,17 +139,28 @@ Page({
|
||||
if (!res.confirm) return
|
||||
request({ url: `/outfit/${this.data.uuid}`, method: 'DELETE' })
|
||||
.then(() => {
|
||||
logger.info(LOG, '穿搭删除成功')
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
setTimeout(() => wx.navigateBack(), 500)
|
||||
setTimeout(
|
||||
() =>
|
||||
wx.navigateBack({
|
||||
fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
}),
|
||||
500,
|
||||
)
|
||||
})
|
||||
.catch(() => {})
|
||||
.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}` })
|
||||
wx.navigateTo({
|
||||
url: `/pages/clothes-detail/clothes-detail?uuid=${uuid}`,
|
||||
fail: (err) => logger.warn(LOG, 'navigateTo 单品详情失败, err=', err && err.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { request } from '../../utils/request'
|
||||
import { OutfitItem, ClothesItem, PagedResult } from '../../types/models'
|
||||
import { normalizePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'outfit-edit'
|
||||
|
||||
const CATEGORIES = [
|
||||
{ name: '全部', value: '' },
|
||||
@@ -36,6 +40,7 @@ Page({
|
||||
|
||||
onLoad(query: Record<string, string>) {
|
||||
const uuid = query.uuid || ''
|
||||
logger.debug(LOG, 'onLoad, uuid=', uuid, '编辑态=', !!uuid)
|
||||
if (uuid) {
|
||||
this.setData({ uuid, isEdit: true })
|
||||
this.fetchOutfit(uuid)
|
||||
@@ -50,7 +55,8 @@ Page({
|
||||
uuids.map(async (id) => {
|
||||
try {
|
||||
return await request<ClothesItem>({ url: `/clothes/${id}`, showError: false })
|
||||
} catch (e) {
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '单品详情拉取失败, uuid=', id, 'code=', e && e.code)
|
||||
return { clothes_uuid: id } as ClothesItem
|
||||
}
|
||||
})
|
||||
@@ -67,7 +73,9 @@ Page({
|
||||
selectedUuids: uuids,
|
||||
selectedItems: clothes,
|
||||
})
|
||||
} catch (e) {}
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '穿搭详情加载失败, code=', e && e.code)
|
||||
}
|
||||
},
|
||||
|
||||
// 已选衣物快照:跨分类切换时列表只保留当前分类,快照保留全部已选项
|
||||
@@ -109,6 +117,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<ClothesItem>(res)
|
||||
logger.debug(LOG, '衣物列表加载成功, 分类=', cat || '全部', 'page=', page, '条数=', raw && raw.length)
|
||||
const list = raw.map((it) => ({
|
||||
...it,
|
||||
_selected: this.data.selectedUuids.indexOf(it.clothes_uuid) >= 0,
|
||||
@@ -122,8 +131,9 @@ Page({
|
||||
hasMore: hasMorePaged(merged, total, PAGE_SIZE),
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '衣物列表加载失败, page=', page, 'code=', e && e.code)
|
||||
this.setData({ selectLoading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -151,6 +161,7 @@ Page({
|
||||
return
|
||||
}
|
||||
if (uuids.length >= 10) {
|
||||
logger.debug(LOG, '已选 10 件,达到上限')
|
||||
wx.showToast({ title: '最多选择 10 件衣物', icon: 'none' })
|
||||
return
|
||||
}
|
||||
@@ -202,11 +213,21 @@ Page({
|
||||
: request({ url: '/outfit', method: 'POST', data: body })
|
||||
req
|
||||
.then(() => {
|
||||
logger.info(LOG, '穿搭保存成功, 编辑态=', this.data.isEdit, '件数=', body.items.length)
|
||||
this.setData({ saving: false })
|
||||
wx.showToast({ title: '已保存', icon: 'success' })
|
||||
setTimeout(() => wx.navigateBack(), 500)
|
||||
setTimeout(
|
||||
() =>
|
||||
wx.navigateBack({
|
||||
fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
}),
|
||||
500,
|
||||
)
|
||||
})
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '穿搭保存失败, code=', e && e.code)
|
||||
this.setData({ saving: false })
|
||||
})
|
||||
.catch(() => this.setData({ saving: false }))
|
||||
},
|
||||
|
||||
onDelete() {
|
||||
@@ -219,11 +240,19 @@ Page({
|
||||
if (!res.confirm) return
|
||||
request({ url: `/outfit/${this.data.uuid}`, method: 'DELETE' })
|
||||
.then(() => {
|
||||
logger.info(LOG, '穿搭删除成功')
|
||||
wx.showToast({ title: '已删除', icon: 'success' })
|
||||
setTimeout(() => wx.navigateBack(), 500)
|
||||
setTimeout(
|
||||
() =>
|
||||
wx.navigateBack({
|
||||
fail: (e) => logger.warn(LOG, 'navigateBack 失败, err=', e && e.errMsg),
|
||||
}),
|
||||
500,
|
||||
)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '穿搭删除失败, code=', e && e.code))
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '删除弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -3,6 +3,11 @@ import * as auth from '../../utils/auth'
|
||||
import { PagedResult, OutfitItem } from '../../types/models'
|
||||
import { OutfitSource, IsPublic, STORAGE_KEYS } from '../../utils/config'
|
||||
import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { setTabBarSelected } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'outfit'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -25,6 +30,7 @@ Page({
|
||||
}
|
||||
const openCollect = wx.getStorageSync(STORAGE_KEYS.OPEN_COLLECT)
|
||||
if (openCollect) {
|
||||
logger.debug(LOG, '命中打开收藏夹标记,切换到收藏 tab')
|
||||
wx.removeStorageSync(STORAGE_KEYS.OPEN_COLLECT)
|
||||
if (this.data.activeTab !== 1) {
|
||||
this.setData({ activeTab: 1, list: [], loading: true })
|
||||
@@ -34,8 +40,7 @@ Page({
|
||||
},
|
||||
|
||||
syncTabBar() {
|
||||
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
||||
if (tabBar) tabBar.setData({ selected: 1 })
|
||||
setTabBarSelected(1)
|
||||
},
|
||||
|
||||
onTabChange(e: WechatMiniprogram.TouchEvent) {
|
||||
@@ -71,6 +76,7 @@ Page({
|
||||
return request<PagedResult<OutfitItem>>({ url, data: { page, page_size: this.data.pageSize } })
|
||||
.then(async (res) => {
|
||||
const { list: raw, total } = normalizePaged<OutfitItem>(res)
|
||||
logger.debug(LOG, '列表加载成功, url=', url, 'page=', page, '条数=', raw && raw.length)
|
||||
const items = await this.decorateList(raw)
|
||||
// decorateList 是异步的,期间可能已切换 tab:序号不匹配则丢弃
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
@@ -83,8 +89,9 @@ Page({
|
||||
page,
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '列表加载失败, url=', url, 'page=', page, 'code=', e && e.code)
|
||||
this.setData({ loading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -99,7 +106,9 @@ Page({
|
||||
showError: false,
|
||||
})
|
||||
likeCount = like.like_count
|
||||
} catch (e) {}
|
||||
} catch (e: any) {
|
||||
logger.warn(LOG, '点赞数拉取失败, uuid=', it.outfit_uuid, 'code=', e && e.code)
|
||||
}
|
||||
return { ...it, _likeCount: likeCount, _status: this.getStatusText(it) }
|
||||
})
|
||||
)
|
||||
@@ -112,16 +121,26 @@ Page({
|
||||
},
|
||||
|
||||
onCreate() {
|
||||
wx.navigateTo({ url: '/pages/outfit-edit/outfit-edit' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/outfit-edit/outfit-edit',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 新建穿搭失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onAiRecommend() {
|
||||
wx.navigateTo({ url: '/pages/ai-recommend/ai-recommend' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/ai-recommend/ai-recommend',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo AI 推荐失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onOutfitTap(e: WechatMiniprogram.TouchEvent) {
|
||||
const uuid = e.currentTarget.dataset.uuid as string
|
||||
const owner = this.data.activeTab === 0 ? '1' : '0'
|
||||
wx.navigateTo({ url: `/pages/outfit-detail/outfit-detail?uuid=${uuid}&owner=${owner}` })
|
||||
logger.debug(LOG, '点击穿搭, uuid=', uuid, 'owner=', owner)
|
||||
wx.navigateTo({
|
||||
url: `/pages/outfit-detail/outfit-detail?uuid=${uuid}&owner=${owner}`,
|
||||
fail: (err) => logger.warn(LOG, 'navigateTo 穿搭详情失败, err=', err && err.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -3,6 +3,11 @@ import * as auth from '../../utils/auth'
|
||||
import { UserInfo, QuotaItem } from '../../types/models'
|
||||
import { QuotaType, STORAGE_KEYS } from '../../utils/config'
|
||||
import { formatDate } from '../../utils/format'
|
||||
import { setTabBarSelected } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'profile'
|
||||
|
||||
function getZodiac(birthDay: number): string {
|
||||
if (!birthDay) return ''
|
||||
@@ -64,18 +69,18 @@ Page({
|
||||
},
|
||||
|
||||
syncTabBar() {
|
||||
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
||||
// 红点由 tabBar 自身在登录态下同步,这里只更新选中态
|
||||
if (tabBar) tabBar.setData({ selected: 4 })
|
||||
setTabBarSelected(4)
|
||||
},
|
||||
|
||||
fetchUser() {
|
||||
request<UserInfo>({ url: '/user/info', showError: false })
|
||||
.then((user) => {
|
||||
logger.debug(LOG, '用户信息加载成功')
|
||||
wx.setStorageSync(STORAGE_KEYS.USER_INFO, user)
|
||||
this.setData({ userInfo: user, zodiac: getZodiac(user.birth_day) })
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '用户信息加载失败, code=', e && e.code))
|
||||
},
|
||||
|
||||
fetchQuota() {
|
||||
@@ -83,8 +88,9 @@ Page({
|
||||
.then((res) => {
|
||||
const upload = res.quotas.find((q) => q.quota_type === QuotaType.UPLOAD)
|
||||
if (upload) this.setData({ uploadRemain: upload.remain })
|
||||
logger.debug(LOG, '额度加载成功, 上传剩余=', upload ? upload.remain : 0)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '额度加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
onEdit() {
|
||||
@@ -120,7 +126,7 @@ Page({
|
||||
wx.showActionSheet({
|
||||
itemList: ['男', '女'],
|
||||
success: (res) => this.setData({ 'editForm.sex': res.tapIndex + 1 }),
|
||||
fail: () => {}, // 取消选择属正常操作,不必抛错日志
|
||||
fail: (e) => logger.debug(LOG, '取消性别选择, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -164,39 +170,65 @@ Page({
|
||||
}
|
||||
|
||||
this.setData({ saving: true })
|
||||
logger.debug(LOG, '提交资料变更, 字段=', Object.keys(body).join(','))
|
||||
request({ url: '/user/profile', method: 'PUT', data: body })
|
||||
.then(() => {
|
||||
logger.info(LOG, '资料保存成功')
|
||||
wx.showToast({ title: '已保存', icon: 'success' })
|
||||
finish()
|
||||
})
|
||||
.catch(() => this.setData({ avatarUploading: false, saving: false }))
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '资料保存失败, code=', e && e.code)
|
||||
this.setData({ avatarUploading: false, saving: false })
|
||||
})
|
||||
}
|
||||
|
||||
if (this.data.avatarChanged && avatar) {
|
||||
this.setData({ avatarUploading: true })
|
||||
uploadFile<{ avatar: string }>(avatar, 'file', '/user/avatar/upload')
|
||||
.then(() => saveProfile())
|
||||
.catch(() => this.setData({ avatarUploading: false, saving: false }))
|
||||
.then(() => {
|
||||
logger.info(LOG, '头像上传成功')
|
||||
saveProfile()
|
||||
})
|
||||
.catch((e: any) => {
|
||||
logger.warn(LOG, '头像上传失败, code=', e && e.code)
|
||||
this.setData({ avatarUploading: false, saving: false })
|
||||
})
|
||||
} else {
|
||||
saveProfile()
|
||||
}
|
||||
},
|
||||
|
||||
onTapMall() {
|
||||
wx.navigateTo({ url: '/pages/mall/mall' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/mall/mall',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 商城失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
onTapOrder() {
|
||||
wx.navigateTo({ url: '/pages/order/order' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/order/order',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 订单失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
onTapNotification() {
|
||||
wx.navigateTo({ url: '/pages/notification/notification' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/notification/notification',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 通知失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
onTapCollect() {
|
||||
wx.setStorageSync(STORAGE_KEYS.OPEN_COLLECT, 1)
|
||||
wx.switchTab({ url: '/pages/outfit/outfit' })
|
||||
wx.switchTab({
|
||||
url: '/pages/outfit/outfit',
|
||||
fail: (e) => logger.warn(LOG, 'switchTab 穿搭失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
onTapFlow() {
|
||||
wx.navigateTo({ url: '/pages/mall/mall?tab=flow' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/mall/mall?tab=flow',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 流水失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
onTapService() {
|
||||
wx.showToast({ title: '客服与反馈敬请期待', icon: 'none' })
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { request, uploadFile, NOT_LOGIN_CODE } from '../../utils/request'
|
||||
import { ProcessStatus } from '../../utils/config'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'upload'
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -17,7 +21,7 @@ Page({
|
||||
const sourceType: Array<'camera' | 'album'> = res.tapIndex === 0 ? ['camera'] : ['album']
|
||||
this.chooseImage(sourceType)
|
||||
},
|
||||
fail: () => {}, // 取消选择属正常操作,不必抛错日志
|
||||
fail: (e) => logger.debug(LOG, '取消选择图片, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -28,8 +32,10 @@ Page({
|
||||
sourceType,
|
||||
success: (res) => {
|
||||
const file = res.tempFiles[0]
|
||||
logger.debug(LOG, '已选择图片, 来源=', sourceType.join(','))
|
||||
this.startUpload(file.tempFilePath)
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '选择图片失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -38,11 +44,13 @@ Page({
|
||||
|
||||
uploadFile<{ clothes_uuid: string; image_process_status: number }>(filePath)
|
||||
.then((res) => {
|
||||
logger.info(LOG, '衣物上传成功, uuid=', res.clothes_uuid)
|
||||
this.setData({ clothesUuid: res.clothes_uuid })
|
||||
this.askNextAction()
|
||||
})
|
||||
.catch((e: any) => {
|
||||
this.setData({ state: 'idle' })
|
||||
logger.warn(LOG, '衣物上传失败, code=', e && e.code)
|
||||
if (e && e.code === 80000) {
|
||||
this.showQuotaModal()
|
||||
return
|
||||
@@ -66,14 +74,22 @@ Page({
|
||||
success: (res) => {
|
||||
this.clearTimer()
|
||||
if (res.confirm) {
|
||||
logger.debug(LOG, '选择继续上传,重置状态')
|
||||
this.setData({ state: 'idle', imagePath: '', clothesUuid: '', step: 0, failReason: '' })
|
||||
} else {
|
||||
wx.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => wx.switchTab({ url: '/pages/wardrobe/wardrobe' }),
|
||||
fail: (e) => {
|
||||
logger.warn(LOG, 'navigateBack 失败,改跳衣橱, err=', e && e.errMsg)
|
||||
wx.switchTab({
|
||||
url: '/pages/wardrobe/wardrobe',
|
||||
fail: (e2) => logger.warn(LOG, 'switchTab 衣橱失败, err=', e2 && e2.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: (e) => logger.warn(LOG, '上传完成弹窗失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -96,13 +112,15 @@ Page({
|
||||
this.clearTimer()
|
||||
} else if (status === ProcessStatus.FAILED) {
|
||||
this.clearTimer()
|
||||
logger.warn(LOG, 'AI 识别失败, 原因=', res.fail_reason)
|
||||
this.setData({ state: 'failed', failReason: res.fail_reason || '识别失败' })
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '状态轮询失败, code=', e && e.code))
|
||||
|
||||
if (count >= 60) {
|
||||
this.clearTimer()
|
||||
logger.warn(LOG, 'AI 处理超时(90s)')
|
||||
this.setData({ state: 'failed', failReason: '处理超时,请重试' })
|
||||
}
|
||||
}, 1500)
|
||||
@@ -127,8 +145,14 @@ Page({
|
||||
confirmText: '去购买',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) wx.navigateTo({ url: '/pages/mall/mall' })
|
||||
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),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -138,6 +162,9 @@ Page({
|
||||
|
||||
onManualEdit() {
|
||||
if (!this.data.clothesUuid) return
|
||||
wx.redirectTo({ url: `/pages/clothes-detail/clothes-detail?uuid=${this.data.clothesUuid}` })
|
||||
wx.redirectTo({
|
||||
url: `/pages/clothes-detail/clothes-detail?uuid=${this.data.clothesUuid}`,
|
||||
fail: (e) => logger.warn(LOG, 'redirectTo 衣物详情失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -3,6 +3,11 @@ import * as auth from '../../utils/auth'
|
||||
import { PagedResult, ClothesItem, QuotaItem } from '../../types/models'
|
||||
import { QuotaType } from '../../utils/config'
|
||||
import { normalizePaged, mergePaged, hasMorePaged } from '../../utils/paged'
|
||||
import { setTabBarSelected } from '../../utils/tabbar'
|
||||
import { logger } from '../../utils/logger'
|
||||
|
||||
// 日志模块名
|
||||
const LOG = 'wardrobe'
|
||||
|
||||
const CATEGORIES = [
|
||||
{ name: '全部', value: '' },
|
||||
@@ -40,8 +45,7 @@ Page({
|
||||
},
|
||||
|
||||
syncTabBar() {
|
||||
const tabBar = (this as any).getTabBar && (this as any).getTabBar()
|
||||
if (tabBar) tabBar.setData({ selected: 0 })
|
||||
setTabBarSelected(0)
|
||||
},
|
||||
|
||||
refresh() {
|
||||
@@ -76,6 +80,7 @@ Page({
|
||||
.then((res) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
const { list: raw, total } = normalizePaged<ClothesItem>(res)
|
||||
logger.debug(LOG, '列表加载成功, 分类=', cat || '全部', 'page=', page, '条数=', raw && raw.length)
|
||||
const list = raw.map((it) => ({
|
||||
...it,
|
||||
_statusText: !it.category_main && !it.processed_image ? 'AI 处理中' : '',
|
||||
@@ -91,8 +96,9 @@ Page({
|
||||
page,
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
.catch((e: any) => {
|
||||
if ((this as any).reqSeq !== seq) return
|
||||
logger.warn(LOG, '列表加载失败, page=', page, 'code=', e && e.code)
|
||||
this.setData({ loading: false, loadingMore: false })
|
||||
})
|
||||
},
|
||||
@@ -102,8 +108,9 @@ Page({
|
||||
.then((res) => {
|
||||
const upload = res.quotas.find((q) => q.quota_type === QuotaType.UPLOAD)
|
||||
if (upload) this.setData({ uploadRemain: upload.remain })
|
||||
logger.debug(LOG, '额度加载成功, 上传剩余=', upload ? upload.remain : 0)
|
||||
})
|
||||
.catch(() => {})
|
||||
.catch((e: any) => logger.warn(LOG, '额度加载失败(静默降级), code=', e && e.code))
|
||||
},
|
||||
|
||||
onCategoryTap(e: WechatMiniprogram.TouchEvent) {
|
||||
@@ -115,10 +122,17 @@ Page({
|
||||
|
||||
onClothesTap(e: WechatMiniprogram.CustomEvent) {
|
||||
const item = e.detail.item as ClothesItem
|
||||
wx.navigateTo({ url: `/pages/clothes-detail/clothes-detail?uuid=${item.clothes_uuid}` })
|
||||
logger.debug(LOG, '点击衣物, uuid=', item && item.clothes_uuid)
|
||||
wx.navigateTo({
|
||||
url: `/pages/clothes-detail/clothes-detail?uuid=${item.clothes_uuid}`,
|
||||
fail: (err) => logger.warn(LOG, 'navigateTo 衣物详情失败, err=', err && err.errMsg),
|
||||
})
|
||||
},
|
||||
|
||||
onUpload() {
|
||||
wx.navigateTo({ url: '/pages/upload/upload' })
|
||||
wx.navigateTo({
|
||||
url: '/pages/upload/upload',
|
||||
fail: (e) => logger.warn(LOG, 'navigateTo 上传页失败, err=', e && e.errMsg),
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user