Files
a_long/miniprogram/pages/sjchongzhi/sjchongzhi.js
2026-06-27 01:26:11 +08:00

473 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// pages/shangjia-chongzhi/index.js
import request from '../../utils/request';
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() {
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
});
}
});