const { getLayout } = require('../../utils/layout'); const { api } = require('../../utils/request'); function formatBytes(bytes) { bytes = bytes || 0; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; if (bytes < 1024 * 1024 * 1024) return (bytes / 1024 / 1024).toFixed(1) + ' MB'; return (bytes / 1024 / 1024 / 1024).toFixed(2) + ' GB'; } Page({ onResize: function () { this.setData(getLayout()); }, data: { loading: true, error: false, usedBytes: 0, usedText: '0 MB', freeMb: 200, freeText: '200 MB', percent: 0, overQuota: false, isVip: false, vipExpireText: '', plans: [], paying: false, }, onLoad: function () { this.setData(getLayout()); }, onShow: function () { this.loadInfo(); }, onPullDownRefresh: function () { this.loadInfo().then(function () { wx.stopPullDownRefresh(); }); }, loadInfo: function () { var self = this; this.setData({ loading: true, error: false }); return api.storageInfo().then(function (d) { var freeBytes = d.free_bytes || d.freeBytes || 0; var usedBytes = d.used_bytes || d.usedBytes || 0; var percent = freeBytes > 0 ? Math.min(100, Math.round(usedBytes / freeBytes * 100)) : 0; var overQuota = usedBytes > freeBytes; var plans = (d.plans || []).map(function (p) { var cents = p.price_cents || p.priceCents || 0; return { key: p.key, name: p.name, priceText: (cents / 100).toFixed(cents % 100 === 0 ? 0 : 1), unit: p.key === 'year' ? '年' : '月', productId: p.product_id || p.productId, }; }); var vipExpireText = ''; if (d.is_vip || d.isVip) { var expire = d.vip_expire_at || d.vipExpireAt ? String(d.vip_expire_at || d.vipExpireAt).slice(0, 10) : ''; vipExpireText = expire ? ('有效期至 ' + expire) : '已开通无限空间'; } self.setData({ loading: false, usedBytes: usedBytes, usedText: formatBytes(usedBytes), freeMb: d.free_mb || d.freeMb || 200, freeText: formatBytes(freeBytes), percent: percent, overQuota: overQuota, isVip: !!(d.is_vip || d.isVip), vipExpireText: vipExpireText, plans: plans, }); }).catch(function (e) { self.setData({ loading: false, error: true }); console.error('加载存储信息失败', e); }); }, buyPlan: function (e) { var key = e.currentTarget.dataset.key; var self = this; if (this.data.paying) return; var plan = null; for (var i = 0; i < this.data.plans.length; i++) { if (this.data.plans[i].key === key) { plan = this.data.plans[i]; break; } } if (!plan) return; wx.showLoading({ title: '下单中...', mask: true }); this.setData({ paying: true }); api.storageCreateOrder({ plan_key: key }).then(function (order) { wx.hideLoading(); if (!order || !(order.sign_data || order.signData)) { self.setData({ paying: false }); wx.showToast({ title: '下单失败', icon: 'none' }); return; } self.callVirtualPay(order); }).catch(function (err) { wx.hideLoading(); self.setData({ paying: false }); wx.showToast({ title: (err && err.error) || '下单失败', icon: 'none' }); }); }, callVirtualPay: function (order) { var self = this; if (!wx.requestVirtualPayment) { this.setData({ paying: false }); wx.showModal({ title: '版本过低', content: '请升级微信至最新版本后再试。', showCancel: false }); return; } // wx.requestVirtualPayment 仅接受 signData / paySig / signature / mode 四个参数; // offerId、env、productId、goodsPrice 等均已编码在 signData JSON 字符串内,不可再平铺为顶层参数。 wx.requestVirtualPayment({ signData: order.sign_data || order.signData, paySig: order.pay_sig || order.paySig, signature: order.signature, mode: order.mode || 'short_series_goods', success: function () { self.setData({ paying: false }); wx.showToast({ title: '支付成功', icon: 'success' }); setTimeout(function () { self.loadInfo(); }, 1200); }, fail: function (err) { self.setData({ paying: false }); var msg = '支付未完成'; var m = (err && err.errMsg) || ''; if (m.indexOf('cancel') >= 0) msg = '已取消支付'; else if (m.indexOf('fail') >= 0) msg = '支付失败,请稍后重试'; wx.showToast({ title: msg, icon: 'none' }); } }); }, });