feat(order): 对齐退款流程并支持状态 6 申请退款中

This commit is contained in:
2026-09-16 03:53:45 +08:00
parent 98c45f2c1e
commit 567d05fa9d
8 changed files with 267 additions and 9 deletions
+85 -6
View File
@@ -12,21 +12,35 @@ const STATUS_FILTERS = [
{ name: '全部', value: 0 },
{ name: '待支付', value: 1 },
{ name: '已支付', value: 2 },
{ name: '申请退款中', value: 6 },
{ name: '已取消', value: 3 },
{ name: '已过期', value: 4 },
{ name: '已退款', value: 5 },
]
const STATUS_TEXT: Record<number, string> = { 1: '待支付', 2: '已支付', 3: '已取消', 4: '已过期', 5: '已退款' }
// 零彩色状态语义:待支付 = 实心黑;已支付/已退款 = 描边;已取消/已过期 = 降透明
const STATUS_TEXT: Record<number, string> = { 1: '待支付', 2: '已支付', 3: '已取消', 4: '已过期', 5: '已退款', 6: '申请退款中' }
// 零彩色状态语义:待支付/申请退款中 = 实心黑(进行中);已支付/已退款 = 描边;已取消/已过期 = 降透明
const STATUS_CLS: Record<number, string> = {
1: 'pill--ink',
2: 'pill--line',
3: 'pill--dim',
4: 'pill--dim',
5: 'pill--line pill--dim',
6: 'pill--ink',
}
// 退款结果轮询间隔:仅在列表存在「申请退款中」订单时才发请求
const REFUND_POLL_MS = 10 * 1000
// 设备是否 iOS:iOS 虚拟支付订单退款需走 App Store(后端返回 71004),前端不展示退款入口
const IS_IOS = (() => {
try {
return wx.getSystemInfoSync().platform === 'ios'
} catch (e) {
return false
}
})()
Page({
data: {
filters: STATUS_FILTERS,
@@ -62,19 +76,22 @@ Page({
onShow() {
this.refresh()
this.startCountdown()
this.startRefundWatch()
},
onHide() {
this.stopCountdown()
this.stopRefundWatch()
},
onUnload() {
this.stopCountdown()
this.stopRefundWatch()
},
refresh() {
refresh(): Promise<void> {
this.setData({ page: 1, hasMore: true, loading: this.data.list.length === 0 })
this.fetchList(1)
return this.fetchList(1)
},
onReachBottom() {
@@ -112,7 +129,67 @@ Page({
if (changed) this.setData({ list: next })
},
fetchList(page: number) {
// ===== 退款结果跟踪:申请退款中的订单只等待结果(不可再次发起退款),定期核对是否已出结果 =====
startRefundWatch() {
this.stopRefundWatch()
;(this as any).refundTimer = setInterval(() => this.pollRefunding(), REFUND_POLL_MS)
},
stopRefundWatch() {
const timer = (this as any).refundTimer
if (timer) {
clearInterval(timer)
;(this as any).refundTimer = null
}
},
// 仅当列表存在「申请退款中」订单时才发请求:命中说明仍未出结果,缺失即视为状态已流转
pollRefunding() {
const tracked = this.data.list.filter((it) => it.order_status === 6).map((it) => it.order_no)
if (!tracked.length) return
request<PagedResult<OrderItem>>({
url: '/order',
data: { status: 6, page: 1, page_size: 50 },
showError: false,
})
.then((res) => {
const still = new Set(normalizePaged<OrderItem>(res).list.map((it) => it.order_no))
const changed = tracked.filter((no) => !still.has(no))
if (changed.length) this.settleRefundResult(changed)
})
.catch((e: any) => logger.warn(LOG, '退款结果轮询失败(静默降级), code=', e && e.code))
},
// 核对流转后的最新状态并刷新列表:5=退款成功(终态)、2=退款未通过可重新申请;仍为 6 则继续等待
settleRefundResult(orderNos: string[]) {
request<PagedResult<OrderItem>>({ url: '/order', data: { page: 1, page_size: 50 }, showError: false })
.then((res) => {
const list = normalizePaged<OrderItem>(res).list
orderNos.forEach((no) => {
const latest = list.find((it) => it.order_no === no)
if (!latest) {
logger.warn(LOG, '退款结果核对:未定位到订单最新状态,仅刷新列表, orderNo=', no)
return
}
if (latest.order_status === 6) return
if (latest.order_status === 5) {
logger.info(LOG, '退款成功, orderNo=', no)
wx.showToast({ title: '退款成功', icon: 'success' })
} else if (latest.order_status === 2) {
logger.info(LOG, '退款未通过,可重新申请, orderNo=', no)
wx.showToast({ title: '退款未通过,可重新申请', icon: 'none' })
} else {
logger.info(LOG, '退款状态已更新, orderNo=', no, 'status=', latest.order_status)
wx.showToast({ title: '退款状态已更新', icon: 'none' })
}
})
this.refresh()
})
.catch((e: any) => logger.warn(LOG, '退款结果核对失败(静默降级), code=', e && e.code))
},
// 返回列表请求的 Promise:退款结果核对后需要等列表刷新完成
fetchList(page: number): Promise<void> {
const params: Record<string, any> = { page, page_size: this.data.pageSize }
const filter = this.data.activeFilter
if (filter > 0) params.status = filter
@@ -122,7 +199,7 @@ Page({
;(this as any).reqSeq = seq
if (page > 1) this.setData({ loadingMore: true })
request<PagedResult<OrderItem>>({ url: '/order', data: params })
return request<PagedResult<OrderItem>>({ url: '/order', data: params })
.then((res) => {
if ((this as any).reqSeq !== seq) return
const { list: raw, total } = normalizePaged<OrderItem>(res)
@@ -138,6 +215,8 @@ Page({
_countdown: it.order_status === 1 && it.expire_time > now ? formatCountdown(it.expire_time - now) : '',
_benefit: it.member_days > 0 ? `${it.member_days} 天会员` : '',
_canCancel: it.order_status === 1 && it.pay_channel !== 2,
// 退款入口:仅「已支付」可申请;iOS 虚拟支付订单需走 App Store(后端 71004),不展示入口
_canRefund: it.order_status === 2 && !(it.pay_channel === 2 && IS_IOS),
_payChannelText: it.pay_channel === 2 ? '虚拟支付' : '',
}))
const merged = mergePaged(this.data.list, list, page === 1)