/** * Soul创业实验 - 订单页(已支付消费流水:章节/VIP/余额/代付等) */ 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 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/gift-pay/list', 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}`), 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 { if (userId) { const res = await app.request({ url: `/api/miniprogram/orders?userId=${encodeURIComponent(userId)}`, silent: true }) if (res && res.success && Array.isArray(res.data)) { const rows = res.data .map((item) => mapApiOrderToRow(item, bookFlat)) .filter(Boolean) .sort((a, b) => b._sortMs - a._sortMs) .map(({ _sortMs, ...rest }) => rest) this.setData({ allRows: rows, loading: false }) this.applyDisplay(false) return } } const ids = [...(app.globalData.purchasedSections || [])].reverse() const rows = 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}`, title, subLine: `已解锁 · ${formatShortDate(t)}`, actionLabel: '阅读', nav: { kind: 'read', id, mid, label: '阅读' } } }) this.setData({ allRows: rows, loading: false }) this.applyDisplay(false) } catch (e) { console.error('加载订单失败:', e) this.setData({ allRows: [], loading: false }) this.applyDisplay(false) } }, onOrderRowTap(e) { const index = e.currentTarget.dataset.index const row = (this.data.displayRows || [])[index] if (!row || !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) { wx.navigateTo({ url: nav.path }) return } if (nav.kind === 'switchTab' && nav.path) { wx.switchTab({ url: nav.path }) } }, 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}` : '' } } })