// pages/shangjia-chongzhi/index.js import request from '../../utils/request'; import { guardMerchantOwnerAction } from '../../utils/staff-api.js'; Page({ data: { // 商家余额 sjyue: '0.00', // 充值金额相关 quickAmounts: [50, 100, 300, 500, 1000, 2000], selectedAmount: 50, // 默认选择第一个 customAmount: '', inputFocus: false, // 金额限制 minAmount: 1, maxAmount: 10000, // 支付状态 canPay: false, isLoading: false, loadingText: '', // 支付状态提示 showStatus: false, statusText: '', statusSubtext: '', showAction: false, actionText: '', // 订单ID currentDingdanid: '', // 轮询相关 pollingCount: 0, maxPollingCount: 15 }, onLoad() { if (!guardMerchantOwnerAction('仅商家老板可充值')) { setTimeout(() => wx.navigateBack(), 1200); return; } this.initPage(); }, onShow() { this.loadShangjiaBalance(); this.registerNotificationComponent(); }, registerNotificationComponent() { const app = getApp(); const notificationComp = this.selectComponent('#global-notification'); if (notificationComp && notificationComp.showNotification) { console.log('🏪 商城页面注册通知组件'); app.globalData.globalNotification = { show: (data) => notificationComp.showNotification(data), hide: () => notificationComp.hideNotification() }; } }, // 初始化页面 initPage() { this.loadShangjiaBalance(); this.checkPayCondition(); }, // 从全局变量加载商家余额 loadShangjiaBalance() { const app = getApp(); const globalData = app.globalData || {}; const shangjiaData = globalData.shangjia || {}; this.setData({ sjyue: shangjiaData.sjyue || '0.00' }); }, // 选择快捷金额 selectAmount(e) { const amount = parseInt(e.currentTarget.dataset.amount); this.setData({ selectedAmount: amount, customAmount: '', inputFocus: false }, () => { this.checkPayCondition(); }); }, // 自定义金额输入 onCustomInput(e) { const value = e.detail.value; // 只允许输入数字和小数点 let cleanedValue = value.replace(/[^\d.]/g, ''); // 只允许一个小数点 const dotCount = cleanedValue.split('.').length - 1; if (dotCount > 1) { cleanedValue = cleanedValue.substring(0, cleanedValue.lastIndexOf('.')); } // 限制小数点后两位 if (cleanedValue.includes('.')) { const parts = cleanedValue.split('.'); if (parts[1].length > 2) { cleanedValue = parts[0] + '.' + parts[1].substring(0, 2); } } this.setData({ customAmount: cleanedValue, selectedAmount: null }, () => { this.checkPayCondition(); }); }, // 输入框聚焦 onInputFocus() { this.setData({ inputFocus: true, selectedAmount: null }); }, // 输入框失焦 onInputBlur() { this.setData({ inputFocus: false }, () => { this.checkPayCondition(); }); }, // 检查金额是否有效 checkAmountValid() { const amount = this.getSelectedAmount(); if (!amount || amount === '') { return false; } const numAmount = parseFloat(amount); const min = this.data.minAmount; const max = this.data.maxAmount; if (numAmount < min || numAmount > max || isNaN(numAmount)) { return false; } return true; }, // 获取选中的金额 getSelectedAmount() { if (this.data.selectedAmount !== null && this.data.selectedAmount !== undefined) { return this.data.selectedAmount.toString(); } else if (this.data.customAmount) { return this.data.customAmount; } return null; }, // 检查支付条件 checkPayCondition() { const validAmount = this.checkAmountValid(); this.setData({ canPay: validAmount }); }, // ========== 支付逻辑 ========== // 处理支付 handlePay() { if (!this.data.canPay) { wx.showToast({ title: '请选择有效金额', icon: 'none' }); return; } const amount = this.getSelectedAmount(); const numAmount = parseFloat(amount); // 确认支付 wx.showModal({ title: '确认充值', content: `是否充值 ¥${numAmount.toFixed(2)}?`, success: (res) => { if (res.confirm) { this.startPayment(numAmount); } } }); }, // 开始支付流程 async startPayment(amount) { this.showLoading('发起支付中...'); try { const res = await request({ url: '/shangpin/sjcz', method: 'POST', data: { jine: amount // 关键字段:后端接口要求"jine" } }); if (res.data.code === 200) { const payParams = res.data.payParams; const dingdanid = res.data.dingdanid; this.setData({ currentDingdanid: dingdanid, pollingCount: 0 }); // 调起微信支付 await this.wechatPay(payParams); } else { this.hideLoading(); wx.showToast({ title: res.data.message || '支付发起失败', icon: 'none' }); } } catch (error) { console.error('发起支付失败:', error); this.hideLoading(); wx.showToast({ title: '网络错误,请重试', icon: 'none' }); } }, // 微信支付 async wechatPay(payParams) { this.showLoading('调起支付中...'); return new Promise((resolve, reject) => { if (!payParams || !payParams.timeStamp || !payParams.paySign) { this.hideLoading(); wx.showToast({ title: '支付参数错误', icon: 'none' }); reject(new Error('支付参数错误')); return; } wx.requestPayment({ timeStamp: payParams.timeStamp, nonceStr: payParams.nonceStr, package: payParams.package, signType: payParams.signType || 'MD5', paySign: payParams.paySign, success: async () => { this.hideLoading(); this.showStatusMessage('支付成功', '正在确认到账...', false); try { await this.startPolling(); resolve(); } catch (error) { reject(error); } }, fail: async (res) => { this.hideLoading(); let errorMsg = '支付失败'; if (res.errMsg.includes('cancel')) { errorMsg = '您取消了支付'; } this.showStatusMessage(errorMsg, '请重新尝试', true, '重新支付'); // 通知后端支付失败 try { await this.notifyPaymentFailure(); } catch (error) { console.error('支付失败通知失败:', error); } reject(new Error(res.errMsg)); } }); }); }, // 开始轮询支付结果 async startPolling() { this.setData({ pollingCount: 0 }); const poll = async () => { if (this.data.pollingCount >= this.data.maxPollingCount) { this.showStatusMessage('确认超时', '请联系客服确认到账情况', true, '联系客服'); return; } try { // 🟢 修改开始:修改checkPaymentStatus的调用和返回值处理 const result = await this.checkPaymentStatus(); if (result.success) { // 🟢 修改:更新全局变量中的商家余额 const app = getApp(); if (app.globalData && app.globalData.shangjia) { // 🟢 注意:后端返回yue,前端全局变量使用sjyue,保留两位小数 app.globalData.shangjia.sjyue = result.yue.toFixed(2); console.log('🟢 全局变量商家余额已更新:', app.globalData.shangjia.sjyue); } this.showStatusMessage('充值成功', '余额已到账', true, '完成'); this.refreshBalance(); return; } // 🟢 修改结束 this.setData({ pollingCount: this.data.pollingCount + 1 }); const delay = this.calculatePollingDelay(); setTimeout(poll, delay); } catch (error) { console.error('轮询失败:', error); this.setData({ pollingCount: this.data.pollingCount + 1 }); setTimeout(poll, 2000); } }; poll(); }, // 计算轮询延迟 calculatePollingDelay() { const count = this.data.pollingCount; if (count < 3) return 1000; if (count < 6) return 2000; if (count < 9) return 3000; return 5000; }, // 检查支付状态 async checkPaymentStatus() { const dingdanid = this.data.currentDingdanid; if (!dingdanid) { throw new Error('订单ID缺失'); } try { const res = await request({ url: '/shangpin/sjcg', method: 'POST', data: { dingdanid: dingdanid // 后端接口要求"dingdanid" } }); // 🟢 修改开始:返回对象,包含成功状态和余额 if (res.data.code === 200) { return { success: true, yue: res.data.yue // 🟢 注意:后端返回字段是yue }; } else { return { success: false }; } // 🟢 修改结束 } catch (error) { console.error('检查支付状态失败:', error); return { success: false }; } }, // 通知支付失败 async notifyPaymentFailure() { const dingdanid = this.data.currentDingdanid; if (!dingdanid) return; try { await request({ url: '/shangpin/sjshibai', method: 'POST', data: { dingdanid: dingdanid // 后端接口要求"dingdanid" } }); } catch (error) { console.error('支付失败通知失败:', error); } }, // 刷新余额 async refreshBalance() { try { this.loadShangjiaBalance(); } catch (error) { console.error('刷新余额失败:', error); } }, // ========== 状态提示 ========== // 显示状态消息 showStatusMessage(title, desc, showAction = false, actionBtnText = '') { this.setData({ showStatus: true, statusText: title, statusSubtext: desc, showAction: showAction, actionText: actionBtnText }); }, // 处理状态按钮点击 handleStatusAction() { const actionText = this.data.actionText; if (actionText === '重新支付' || actionText === '重试') { this.setData({ showStatus: false }); setTimeout(() => { this.handlePay(); }, 300); } else if (actionText === '联系客服') { wx.showModal({ title: '联系客服', content: '联系客服', showCancel: false, confirmText: '我知道了' }); } else if (actionText === '完成') { this.setData({ showStatus: false }); this.refreshBalance(); } }, // ========== 工具方法 ========== // 显示加载 showLoading(text = '加载中...') { this.setData({ isLoading: true, loadingText: text }); }, // 隐藏加载 hideLoading() { this.setData({ isLoading: false }); }, // 页面卸载时清理 onUnload() { this.setData({ showStatus: false, isLoading: false }); } });