/** * Soul创业派对 - 订单与代付(消费流水 + 我发起的代付,按时间合并) */ const app = getApp() const { cleanSingleLineField } = require('../../utils/contentParser.js') const PAID_STATUSES = new Set(['paid', 'completed', 'success']) function parseOrderTimeMs(o) { const raw = o.created_at || o.createdAt || o.pay_time || 0 const t = new Date(raw).getTime() return Number.isFinite(t) ? t : 0 } function formatShortDate(ms) { if (!ms) return '--' const d = new Date(ms) const m = (d.getMonth() + 1).toString().padStart(2, '0') const day = d.getDate().toString().padStart(2, '0') return `${m}-${day}` } function midForSection(sectionId, bookFlat) { const row = bookFlat.find((s) => s.id === sectionId) return row?.mid ?? row?.MID ?? 0 } function giftPayStatusLabel(status) { const s = String(status || '').toLowerCase() if (s === 'pending' || s === 'pending_pay') return '待支付' if (s === 'paid') return '已支付' if (s === 'refunded') return '已退款' if (s === 'cancelled') return '已取消' if (s === 'expired') return '已过期' return String(status || '').trim() || '--' } function parseIsoMs(iso) { const t = new Date(iso || 0).getTime() return Number.isFinite(t) ? t : 0 } function mapGiftPayToRow(item) { const requestSn = String(item.requestSn || '').trim() if (!requestSn) return null const t = parseIsoMs(item.createdAt) const amt = Number(item.amount) const amountStr = Number.isFinite(amt) ? amt.toFixed(2) : '--' const titleRaw = cleanSingleLineField(String(item.description || '').trim()) const title = titleRaw || '代付' const st = String(item.status || '').toLowerCase() const stLabel = giftPayStatusLabel(item.status) const gpPending = st === 'pending' || st === 'pending_pay' const gpPaid = st === 'paid' return { rowKey: `gp_${requestSn}`, kind: 'giftPay', requestSn, title, subLine: `¥${amountStr} · ${stLabel} · ${formatShortDate(t)}`, actionLabel: '查看', gpPending, gpPaid, _sortMs: t, } } function classifyNav(productType, productId, mid) { const pt = String(productType || '').toLowerCase() if (pt === 'section' && productId) { return { kind: 'read', id: productId, mid: mid || 0, label: '阅读' } } if (pt === 'fullbook') { return { kind: 'switchTab', path: '/pages/chapters/chapters', label: '去目录' } } if (pt === 'vip') { return { kind: 'page', path: '/pages/vip/vip', label: '会员中心' } } if (pt === 'match') { return { kind: 'switchTab', path: '/pages/match/match', label: '找伙伴' } } if (pt === 'balance_recharge') { return { kind: 'page', path: '/pages/wallet/wallet', label: '余额' } } if (pt === 'gift_pay' || pt === 'gift_pay_batch') { return { kind: 'page', path: '/pages/purchases/purchases', label: '查看' } } if (productId && (/^\d+\.\d+/.test(productId) || productId.length > 0)) { return { kind: 'read', id: productId, mid: mid || 0, label: '阅读' } } return { kind: 'none', label: '--' } } function mapApiOrderToRow(item, bookFlat) { const status = String(item.status || '').toLowerCase() if (!PAID_STATUSES.has(status)) return null const pt = String(item.product_type || '').toLowerCase() const productId = String(item.product_id || item.section_id || '').trim() let mid = Number(item.section_mid ?? item.mid ?? item.MID ?? 0) || 0 if (pt === 'section' && productId && !mid) mid = midForSection(productId, bookFlat) const titleRaw = cleanSingleLineField(item.product_name || '') const title = titleRaw || (pt === 'balance_recharge' ? '余额充值' : productId ? `订单 ${productId}` : '消费记录') const amt = Number(item.amount) const amountStr = Number.isFinite(amt) ? amt.toFixed(2) : '--' const t = parseOrderTimeMs(item) const nav = classifyNav(pt, productId, mid) return { rowKey: String(item.order_sn || item.id || `o_${t}`), kind: 'order', title, subLine: `¥${amountStr} · ${formatShortDate(t)}`, actionLabel: nav.label, nav, _sortMs: t } } Page({ data: { statusBarHeight: 44, loading: true, allRows: [], displayRows: [], historyExpanded: false }, onLoad() { wx.showShareMenu({ withShareTimeline: true }) this.setData({ statusBarHeight: app.globalData.statusBarHeight }) this.loadOrders() }, onShow() { if (!this._purchasesFirstOnShowSkipped) { this._purchasesFirstOnShowSkipped = true return } if (app.globalData.isLoggedIn) this.loadOrders() }, applyDisplay(expanded) { const all = this.data.allRows || [] const display = expanded || all.length <= 5 ? all : all.slice(0, 5) this.setData({ displayRows: display, historyExpanded: !!expanded }) }, expandHistory() { if (this.data.historyExpanded) return this.applyDisplay(true) }, async loadOrders() { this.setData({ loading: true }) const bookFlat = Array.isArray(app.globalData.bookData) ? app.globalData.bookData : [] const userId = app.globalData.userInfo?.id try { let orderRows = [] if (userId) { const orderRes = await app.request({ url: `/api/miniprogram/orders?userId=${encodeURIComponent(userId)}`, silent: true, }).catch(() => null) if (orderRes && orderRes.success && Array.isArray(orderRes.data)) { orderRows = orderRes.data.map((item) => mapApiOrderToRow(item, bookFlat)).filter(Boolean) } } if (!orderRows.length) { const ids = [...(app.globalData.purchasedSections || [])].reverse() orderRows = ids.map((id, index) => { const mid = midForSection(id, bookFlat) const row = bookFlat.find((s) => s.id === id) const title = cleanSingleLineField( row?.sectionTitle || row?.section_title || row?.title || row?.chapterTitle || '' ) || `章节 ${id}` const t = Date.now() - index * 86400000 return { rowKey: `p_${id}_${index}`, kind: 'order', title, subLine: `已解锁 · ${formatShortDate(t)}`, actionLabel: '阅读', nav: { kind: 'read', id, mid, label: '阅读' }, _sortMs: t, } }) } let giftRows = [] if (userId && !app.globalData.auditMode) { const giftRes = await app .request(`/api/miniprogram/gift-pay/my-requests?userId=${encodeURIComponent(userId)}`, { silent: true, }) .catch(() => null) if (giftRes && giftRes.success && Array.isArray(giftRes.list)) { giftRows = giftRes.list.map(mapGiftPayToRow).filter(Boolean) } } const merged = [...orderRows, ...giftRows].sort((a, b) => b._sortMs - a._sortMs) const stripped = merged.map(({ _sortMs, ...rest }) => rest) this.setData({ allRows: stripped, loading: false }) this.applyDisplay(false) } catch (e) { console.error('加载订单失败:', e) this.setData({ allRows: [], loading: false }) this.applyDisplay(false) } }, onUnifiedRowTap(e) { const index = e.currentTarget.dataset.index const row = (this.data.displayRows || [])[index] if (!row) return if (row.kind === 'giftPay' && row.requestSn) { wx.navigateTo({ url: `/pages/gift-pay/redemption-detail?requestSn=${encodeURIComponent(String(row.requestSn))}`, }) return } if (!row.nav) return const { nav } = row if (nav.kind === 'read' && nav.id) { const q = nav.mid ? `mid=${nav.mid}` : `id=${nav.id}` wx.navigateTo({ url: `/pages/read/read?${q}` }) return } if (nav.kind === 'page' && nav.path) { if (app.globalData.auditMode) { const block = { '/pages/vip/vip': true, '/pages/wallet/wallet': true } if (block[nav.path]) { wx.showToast({ title: '当前为体验版,暂无法访问', icon: 'none' }) return } } wx.navigateTo({ url: nav.path }) return } if (nav.kind === 'switchTab' && nav.path) { wx.switchTab({ url: nav.path }) } }, async onGiftPayCancel(e) { if (e && typeof e.stopPropagation === 'function') e.stopPropagation() const requestSn = e?.currentTarget?.dataset?.sn if (!requestSn) return const ok = await new Promise((r) => { wx.showModal({ title: '取消代付', content: '确定取消该代付请求?', success: (res) => r(res.confirm) }) }) if (!ok) return try { const res = await app.request({ url: '/api/miniprogram/gift-pay/cancel', method: 'POST', data: { requestSn, userId: app.globalData.userInfo?.id }, }) if (res && res.success) { wx.showToast({ title: '已取消', icon: 'success' }) this.loadOrders() } else { wx.showToast({ title: res?.error || '取消失败', icon: 'none' }) } } catch (_) { wx.showToast({ title: '取消失败', icon: 'none' }) } }, onGiftPayShare(e) { if (e && typeof e.stopPropagation === 'function') e.stopPropagation() const requestSn = e?.currentTarget?.dataset?.sn if (!requestSn) return wx.navigateTo({ url: `/pages/gift-pay/detail?requestSn=${encodeURIComponent(String(requestSn))}`, }) }, goBack() { getApp().goBackOrToHome() }, onShareAppMessage() { const ref = app.getMyReferralCode() return { title: '卡若创业派对 - 订单与代付', path: ref ? `/pages/purchases/purchases?ref=${ref}` : '/pages/purchases/purchases' } }, onShareTimeline() { const ref = app.getMyReferralCode() return { title: '卡若创业派对 - 订单与代付', query: ref ? `ref=${ref}` : '' } } })