feat: 支持退出后补告衣物处理结果

This commit is contained in:
2026-09-16 02:01:26 +08:00
parent a9f2659c42
commit 7be561500b
12 changed files with 539 additions and 22 deletions
@@ -1,6 +1,8 @@
import { request } from '../../utils/request'
import { ClothesItem } from '../../types/models'
import { ProcessStatus } from '../../utils/config'
import { isProcessTerminal } from '../../utils/clothes-status'
import { removePendingClothes } from '../../utils/pending-clothes'
import { navScroll } from '../../utils/nav'
import { logger } from '../../utils/logger'
@@ -152,9 +154,13 @@ Page({
this.setData({ loading: false, notFound: true })
return
}
this.fetchDetail()
// 只读(来自穿搭分享)场景无需轮询 AI 处理状态
if (!readonly) this.pollStatus()
this.fetchDetail().then(() => {
// 只读(来自穿搭分享)场景无需轮询 AI 处理状态
if (readonly) return
// 详情响应已带处理状态:成功/失败等终态直接定态,仅处理中才轮询
if (isProcessTerminal(this.data.detail)) return
this.pollStatus()
})
},
onBackWardrobe() {
@@ -172,7 +178,19 @@ Page({
return request<ClothesItem>({ url })
.then((detail) => {
logger.debug(LOG, '详情加载成功, name=', detail && detail.name)
this.setData({ detail, loading: false })
const patch: Record<string, any> = { detail, loading: false }
const status = Number(detail && detail.image_process_status)
if (!this.data.readonly && status) {
// 详情响应带处理状态:进入页面即渲染正确视图,避免先闪正常详情再切回处理中
patch.imageStatus = status
patch.step = statusToStep(status)
if (status === ProcessStatus.FAILED) {
patch.failReason = (detail && detail.fail_reason) || '识别失败'
}
// 终态即可清掉待核对记录(幂等,未登记时为空操作)
if (isProcessTerminal(detail)) removePendingClothes(this.data.uuid)
}
this.setData(patch)
})
.catch((e: any) => {
logger.warn(LOG, '详情加载失败, code=', e && e.code)
@@ -181,22 +199,27 @@ Page({
},
pollStatus() {
// 先清旧定时器,避免重复进入时叠加成多份轮询
this.clearTimer()
let count = 0
;(this as any).pollTimer = setInterval(() => {
count++
request<{ image_process_status: number; fail_reason?: string }>({
url: `/clothes/${this.data.uuid}/status`,
showError: false,
silentAuth: true,
})
.then((res) => {
const status = res.image_process_status
if (status === ProcessStatus.SUCCESS) {
// 成功:先拉最新详情,再切换为详情视图,避免空属性闪烁
this.clearTimer()
removePendingClothes(this.data.uuid)
logger.info(LOG, 'AI 处理完成')
this.fetchDetail().then(() => this.setData({ imageStatus: status, step: 2 }))
} else if (status === ProcessStatus.FAILED) {
this.clearTimer()
removePendingClothes(this.data.uuid)
logger.warn(LOG, 'AI 识别失败, 原因=', res.fail_reason)
this.setData({ imageStatus: status, failReason: res.fail_reason || '识别失败' })
} else {
@@ -205,8 +228,9 @@ Page({
})
.catch((e: any) => logger.warn(LOG, '状态轮询失败, code=', e && e.code))
if (count >= 120) {
// 只停轮询,保持处理中视图(后端有恢复调度器兜底),不误报失败
this.clearTimer()
logger.warn(LOG, '状态轮询超时(240s),停止轮询')
logger.warn(LOG, '状态轮询超时(240s),保持处理中视图并停止轮询')
}
}, 2000)
},
@@ -70,7 +70,7 @@ module.exports = { hex: hex, tags: tags }
<view class="head">
<view class="eyebrow">Processing</view>
<view class="display">AI 正在识别你的衣物…</view>
<view class="cd-note">通常需要 10 秒左右,请稍候</view>
<view class="cd-note">通常需要 10 秒左右;处理较慢时可先返回,稍后再来查看</view>
</view>
<view class="up-preview">
<view class="ph icon icon-hanger"></view>