Files
xingque/pages/fighter-recharge/fighter-recharge.js

978 lines
27 KiB
JavaScript
Raw 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/dashou-chongzhi/index.js
import request from '../../utils/request';
import PopupService from '../../services/popupService.js';
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
Page({
data: {
// ========== 全局数据 ==========
clubmber: [], // 会员列表(注意:全局变量中是 clumber这里保持原样
yajin: 0, // 押金
jifen: 0, // 积分(注意:全局变量中是 jinfen
jifenProgress: 0, // 积分进度条角度
// ========== 会员商品列表 ==========
huiyuanList: [], // 从后端获取的会员列表
currentHuiyuanIndex: 0, // 当前选中的会员索引
currentHuiyuan: {}, // 当前选中的会员详情
// ========== 押金充值相关 ==========
showYajinModal: false, // 显示押金弹窗
yajinAmount: '100', // 押金金额
// ========== 支付相关 ==========
payLoading: false, // 支付加载状态
loadingText: '支付中...',
// ========== 订单ID记录 ==========
currentDingdanid: '', // 当前操作的订单ID
// ========== 计算高度 ==========
huiyuanListHeight: 120,
// ========== 会员详情规则 ==========
detailRules: [
'会员有效期为30天从购买当天开始计算',
'会员期间享受优先接单特权',
'可享受专属客服服务',
'会员到期前3天会有提醒',
'支持随时续费,续费天数叠加'
],
// ========== 新增:跳转参数处理 ==========
// 用于接收从其他页面跳转过来的参数,决定是否自动滚动
jumpParams: {},
// ========== 新增:支付方式选择 ==========
showPayMethodModal: false, // 支付方式选择弹窗
currentBuyType: null, // 当前购买类型1会员 2押金 3积分
currentHuiyuanId: null, // 当前选中的会员ID用于会员购买
currentYajinAmount: null, // 当前押金金额(用于押金购买)
// ========== 新增:余额抵扣身份选择 ==========
showBalanceModal: false, // 余额抵扣身份选择弹窗
balanceOptions: [], // 后端返回的身份列表
selectedBalanceId: null, // 选中的身份ID
// ========== 新增:余额抵扣确认弹窗 ==========
showConfirmModal: false, // 余额抵扣确认弹窗
selectedBalanceInfo: null, // 选中的身份详情(用于确认弹窗)
// ========== 新增:会员详情弹窗 ==========
showMemberModal: false,
currentMemberDetail: null,
},
// ========== 生命周期函数 ==========
onLoad(options) {
//console.log('页面加载,跳转参数:', options);
// ✅ 新增:保存跳转参数
this.setData({
jumpParams: options || {}
});
this.initPage();
},
// pages/submit/submit.js 中添加 onHide 方法(如果已有则合并内容)
onHide() {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) {
popupComp.cleanup();
}
},
async onShow() {
const phoneOk = await ensurePhoneAuth({ redirect: true, role: 'dashou' });
if (!phoneOk) return;
// 每次显示页面都刷新数据
this.registerNotificationComponent();
this.loadFromGlobalData();
this.checkAndRefreshData();
// 调用统一弹窗组件检查并展示公告
PopupService.checkAndShow(this, 'dashouchongzhi');
},
// 注册通知组件(原有,保持不变)
registerNotificationComponent() {
const app = getApp();
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
onReady() {
// ✅ 新增:页面渲染完成后处理自动滚动
this.handleAutoScroll();
},
// ========== 初始化页面 ==========
async initPage() {
// 从全局数据加载
this.loadFromGlobalData();
// 获取会员商品列表
await this.fetchHuiyuanList();
// 计算会员列表高度
this.calculateHuiyuanHeight();
},
// ========== 从全局变量加载数据 ==========
loadFromGlobalData() {
const app = getApp();
const globalData = app.globalData || {};
// ✅ 重要:保持字段对应关系
// 全局变量中是 clumber页面中是 clubmber
// 全局变量中是 jinfen页面中是 jifen
this.setData({
clubmber: globalData.clumber || [],
yajin: globalData.yajin || 0,
jifen: globalData.jinfen || 0 // ✅ 注意:这里从 jinfen 读取
});
// 计算积分进度条
this.calculateJifenProgress();
},
// ========== 计算积分进度条角度 ==========
calculateJifenProgress() {
const jifen = this.data.jifen || 0;
const progress = (jifen / 10) * 360; // 满分10分
this.setData({
jifenProgress: progress
});
},
// ========== 计算会员列表高度 ==========
calculateHuiyuanHeight() {
const clubmber = this.data.clubmber || [];
const itemHeight = 100; // 每个会员标签高度
const maxHeight = 300; // 最大高度3个会员
let height = clubmber.length * itemHeight;
height = Math.min(height, maxHeight);
this.setData({
huiyuanListHeight: height
});
},
// ========== 获取会员商品列表 ==========
async fetchHuiyuanList() {
try {
const res = await request({
url: '/shangpin/dshyhq',
method: 'POST',
data: {}
});
if (res.data.code === 200) {
const huiyuanList = res.data.data || [];
// 处理数据,标记已购买的会员
const processedList = this.processHuiyuanList(huiyuanList);
this.setData({
huiyuanList: processedList,
currentHuiyuan: processedList[0] || {}
});
} else {
wx.showToast({
title: res.data.message || '获取会员列表失败',
icon: 'none'
});
}
} catch (error) {
console.error('获取会员列表失败:', error);
wx.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
},
// ========== 处理会员列表,标记已购买的会员 ==========
processHuiyuanList(huiyuanList) {
const clubmber = this.data.clubmber || [];
return huiyuanList.map(item => {
// 检查是否已购买注意会员ID字段是 id
const boughtItem = clubmber.find(c => c.huiyuanid === item.id);
return {
...item,
isBought: !!boughtItem,
buyInfo: boughtItem || null
};
});
},
// ========== Swiper切换事件 ==========
onSwiperChange(e) {
const current = e.detail.current;
const huiyuanList = this.data.huiyuanList || [];
this.setData({
currentHuiyuanIndex: current,
currentHuiyuan: huiyuanList[current] || {}
});
},
// ========== 手动选择会员 ==========
selectHuiyuan(e) {
const index = e.currentTarget.dataset.index;
const huiyuanList = this.data.huiyuanList || [];
this.setData({
currentHuiyuanIndex: index,
currentHuiyuan: huiyuanList[index] || {}
});
},
// ========== 格式化到期时间 ==========
formatDaoqiTime(daoqi) {
if (!daoqi) return '';
try {
// 如果是标准日期格式,格式化为 YYYY-MM-DD
if (daoqi.includes(' ')) {
const dateStr = daoqi.split(' ')[0];
const dateParts = dateStr.split('-');
if (dateParts.length === 3) {
return `${dateParts[0]}-${dateParts[1]}-${dateParts[2]}`;
}
}
return daoqi;
} catch (error) {
console.error('格式化到期时间错误:', error);
return daoqi;
}
},
// ========== 计算剩余时间 ==========
formatRemainTime(daoqi) {
if (!daoqi) return '';
try {
const now = new Date();
const end = new Date(daoqi);
const diff = end - now;
if (diff <= 0) return '已过期';
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
if (days > 0) {
return `${days}`;
}
const hours = Math.floor(diff / (1000 * 60 * 60));
if (hours > 0) {
return `${hours}小时`;
}
return '即将到期';
} catch (error) {
console.error('计算剩余时间错误:', error);
return '时间错误';
}
},
// ========== 处理自动滚动 ==========
handleAutoScroll() {
const { jumpParams } = this.data;
if (!jumpParams || !jumpParams.needScroll) return;
setTimeout(() => {
let scrollTop = 0;
if (jumpParams.scrollTo === 'bottom') {
scrollTop = 2000;
} else if (jumpParams.scrollTo === 'member') {
return;
}
if (scrollTop > 0) {
wx.pageScrollTo({
scrollTop: scrollTop,
duration: 300
});
}
}, 800);
},
// ========== 押金充值相关 ==========
showYajinModal() {
this.setData({
showYajinModal: true,
yajinAmount: '100'
});
},
hideYajinModal() {
this.setData({
showYajinModal: false
});
},
onYajinInput(e) {
let value = e.detail.value;
value = value.replace(/[^\d]/g, '');
if (value) {
const num = parseInt(value);
if (num < 1) value = '1';
if (num > 10000) value = '10000';
}
this.setData({
yajinAmount: value
});
},
setYajinAmount(e) {
const amount = e.currentTarget.dataset.amount;
this.setData({
yajinAmount: amount
});
},
async handleYajinPay() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({
title: '请输入1-10000元的金额',
icon: 'none'
});
return;
}
this.showLoading('发起支付中...');
try {
const res = await request({
url: '/shangpin/yajingoumai',
method: 'POST',
data: {
jine: parseInt(amount)
}
});
if (res.data.code === 200) {
const payParams = res.data.payParams;
const dingdanid = res.data.dingdanid;
this.setData({
currentDingdanid: dingdanid
});
await this.wechatPay(payParams, 'yajin');
} else {
wx.showToast({
title: res.data.message || '支付发起失败',
icon: 'none'
});
}
} catch (error) {
console.error('押金支付失败:', error);
wx.showToast({
title: '支付失败,请重试',
icon: 'none'
});
} finally {
this.hideLoading();
}
},
// ========== 积分充值相关 ==========
// 🔥 修改点1增加积分已满的硬拦截不弹任何提示直接返回
onJifenClick(e) {
// 优先判断积分是否已满10分为满分
if (this.data.jifen >= 10) {
// 积分已满,不弹窗,不提示,静默返回
return;
}
// 检查是否有会员
const clubmber = this.data.clubmber || [];
if (clubmber.length === 0) {
wx.showToast({
title: '请先购买会员才能充值积分',
icon: 'none',
duration: 3000
});
return;
}
// 积分未满,正常打开支付方式选择
this.setData({
currentBuyType: 3,
showPayMethodModal: true
});
},
// ========== 会员购买相关 ==========
async handleHuiyuanBuy(e) {
const huiyuanId = e.currentTarget.dataset.id;
if (!huiyuanId) {
wx.showToast({
title: '会员信息错误',
icon: 'none'
});
return;
}
this.showLoading('发起会员支付中...');
try {
const res = await request({
url: '/shangpin/huiyuangm',
method: 'POST',
data: {
huiyuanid: huiyuanId
}
});
if (res.data.code === 200) {
const payParams = res.data.payParams;
const dingdanid = res.data.dingdanid;
this.setData({
currentDingdanid: dingdanid
});
await this.wechatPay(payParams, 'huiyuan', huiyuanId);
} else {
wx.showToast({
title: res.data.message || '会员支付发起失败',
icon: 'none'
});
}
} catch (error) {
console.error('会员支付失败:', error);
wx.showToast({
title: '支付失败,请重试',
icon: 'none'
});
} finally {
this.hideLoading();
}
},
// ========== 积分购买(微信支付)—— 已替换为正确的后端接口 ==========
async handleJifenBuy(e) {
const disabled = e.currentTarget.dataset.disabled;
// 检查积分是否已满
if (disabled === 'true') {
wx.showToast({ title: '积分已满,无需补充', icon: 'none' });
return;
}
// 检查是否有会员
const clubmber = this.data.clubmber || [];
if (clubmber.length === 0) {
wx.showToast({ title: '请先购买会员才能充值积分', icon: 'none', duration: 3000 });
return;
}
this.showLoading('发起积分支付中...');
try {
const res = await request({
url: '/shangpin/jifenbc', // 正确的积分下单接口
method: 'POST',
data: {}
});
if (res.data.code === 200) {
const payParams = res.data.payParams;
const dingdanid = res.data.dingdanid;
this.setData({ currentDingdanid: dingdanid });
await this.wechatPay(payParams, 'jifen');
} else {
wx.showToast({ title: res.data.message || '积分支付发起失败', icon: 'none' });
}
} catch (error) {
wx.showToast({ title: '支付失败,请重试', icon: 'none' });
} finally {
this.hideLoading();
}
},
// ========== 微信支付封装 ==========
async wechatPay(payParams, payType, extraData = null) {
return new Promise((resolve, reject) => {
if (!payParams || !payParams.timeStamp || !payParams.paySign) {
wx.showToast({
title: '支付参数错误',
icon: 'none'
});
reject(new Error('支付参数错误'));
return;
}
this.showLoading('调起支付中...');
wx.requestPayment({
timeStamp: payParams.timeStamp,
nonceStr: payParams.nonceStr,
package: payParams.package,
signType: payParams.signType || 'MD5',
paySign: payParams.paySign,
success: async () => {
this.hideLoading();
wx.showToast({
title: '支付成功!确认中...',
icon: 'none',
duration: 2000
});
try {
await this.startPolling(payType, extraData);
resolve();
} catch (error) {
reject(error);
}
},
fail: async (res) => {
this.hideLoading();
let errorMsg = '支付失败';
if (res.errMsg.includes('cancel')) {
errorMsg = '您取消了支付';
} else if (res.errMsg.includes('fail')) {
errorMsg = '支付失败,请重试';
}
wx.showToast({
title: errorMsg,
icon: 'none'
});
try {
await this.handlePayFailure(payType, extraData);
} catch (error) {
console.error('支付失败通知失败:', error);
}
reject(new Error(res.errMsg));
}
});
});
},
// ========== 开始轮询支付结果 ==========
async startPolling(payType, extraData = null) {
const maxRetries = 10;
const interval = 2000;
const dingdanid = this.data.currentDingdanid;
if (!dingdanid) {
wx.showToast({
title: '订单号缺失',
icon: 'none'
});
return;
}
this.showLoading('确认支付结果中...');
for (let i = 0; i < maxRetries; i++) {
try {
const pollResult = await this.checkPayStatus(payType, dingdanid, extraData);
if (pollResult.success) {
this.hideLoading();
await this.updateAfterPayment(payType, extraData, pollResult.data);
wx.showToast({
title: this.getSuccessMessage(payType),
icon: 'success',
duration: 2000
});
return;
}
await this.sleep(interval);
} catch (error) {
console.error(`轮询失败第${i + 1}次:`, error);
}
}
this.hideLoading();
wx.showToast({
title: '支付确认超时,请联系客服',
icon: 'none'
});
},
// ========== 检查支付状态 ==========
async checkPayStatus(payType, dingdanid, extraData = null) {
let url = '';
let data = { dingdanid: dingdanid };
switch (payType) {
case 'yajin':
url = '/shangpin/yajinlunxun';
break;
case 'jifen':
url = '/shangpin/jifenlunxun';
break;
case 'huiyuan':
url = '/shangpin/huiyuanlx';
data.huiyuanid = extraData;
break;
default:
throw new Error('未知的支付类型');
}
try {
const res = await request({
url,
method: 'POST',
data
});
return {
success: res.data.code === 200,
data: res.data
};
} catch (error) {
console.error('检查支付状态失败:', error);
return {
success: false,
data: null
};
}
},
// ========== 支付失败处理 ==========
async handlePayFailure(payType, extraData = null) {
let url = '';
let data = { dingdanid: this.data.currentDingdanid };
switch (payType) {
case 'yajin':
url = '/shangpin/yajinshibai';
break;
case 'jifen':
url = '/shangpin/jifenshibai';
break;
case 'huiyuan':
url = '/shangpin/huiyuanshibai';
data.huiyuanid = extraData;
break;
default:
return;
}
try {
await request({
url,
method: 'POST',
data
});
} catch (error) {
console.error('支付失败通知失败:', error);
}
},
// ========== 支付成功后更新数据 ==========
async updateAfterPayment(payType, extraData = null, responseData = null) {
const app = getApp();
switch (payType) {
case 'yajin':
if (responseData && responseData.yajin !== undefined) {
app.globalData.yajin = responseData.yajin;
}
await this.refreshYajinData();
break;
case 'jifen':
if (responseData && responseData.jifen !== undefined) {
app.globalData.jinfen = responseData.jifen;
}
await this.refreshJifenData();
break;
case 'huiyuan':
if (responseData && responseData.huiyuan) {
app.globalData.jinfen = responseData.jifen;
await this.updateClubmberData(responseData.huiyuan);
}
await this.refreshHuiyuanData(extraData);
break;
}
this.loadFromGlobalData();
},
// ========== 刷新押金数据 ==========
async refreshYajinData() {
this.loadFromGlobalData();
},
// ========== 刷新积分数据 ==========
async refreshJifenData() {
this.loadFromGlobalData();
},
// ========== 刷新会员数据 ==========
async refreshHuiyuanData(huiyuanId) {
this.loadFromGlobalData();
await this.fetchHuiyuanList();
},
// ========== 更新会员数据到全局变量 ==========
async updateClubmberData(huiyuanData) {
const app = getApp();
const globalClubmber = app.globalData.clumber || [];
const { huiyuanid, huiyuanming, daoqi } = huiyuanData;
const index = globalClubmber.findIndex(item => item.huiyuanid === huiyuanid);
if (index >= 0) {
globalClubmber[index].daoqi = daoqi;
} else {
globalClubmber.push({
huiyuanid: huiyuanid,
huiyuanming: huiyuanming,
daoqi: daoqi
});
}
app.globalData.clumber = globalClubmber;
this.setData({
clubmber: [...globalClubmber]
});
},
// ========== 检查并刷新数据 ==========
async checkAndRefreshData() {
this.loadFromGlobalData();
},
// ========== 工具方法 ==========
getSuccessMessage(payType) {
switch (payType) {
case 'yajin': return '押金充值成功';
case 'jifen': return '积分补充成功';
case 'huiyuan': return '会员购买成功';
default: return '支付成功';
}
},
showLoading(text = '加载中...') {
this.setData({
payLoading: true,
loadingText: text
});
},
hideLoading() {
this.setData({
payLoading: false
});
},
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
// ========== 新增功能(余额抵扣等) ==========
onBuyHuiyuanClick(e) {
const huiyuanId = e.currentTarget.dataset.id;
this.setData({
currentBuyType: 1,
currentHuiyuanId: huiyuanId,
showPayMethodModal: true
});
},
onYajinClick() {
this.showYajinModal();
},
onYajinConfirm() {
const amount = this.data.yajinAmount;
if (!amount || amount < 1 || amount > 10000) {
wx.showToast({ title: '请输入1-10000元的金额', icon: 'none' });
return;
}
this.hideYajinModal();
this.setData({
currentBuyType: 2,
currentYajinAmount: amount,
showPayMethodModal: true
});
},
hidePayMethodModal() {
this.setData({ showPayMethodModal: false });
},
// 🔥 修改点2选择支付方式时再次校验积分状态防止异步过程中积分变化
onPayMethodSelect(e) {
const method = e.currentTarget.dataset.method;
const { currentBuyType, currentHuiyuanId, currentYajinAmount, jifen } = this.data;
this.hidePayMethodModal();
// 如果是积分购买,且积分已满,直接拒绝
if (currentBuyType === 3 && jifen >= 10) {
wx.showToast({
title: '积分已满,无需补充',
icon: 'none'
});
return;
}
if (method === 'wx') {
if (currentBuyType === 1) {
this.handleHuiyuanBuy({ currentTarget: { dataset: { id: currentHuiyuanId } } });
} else if (currentBuyType === 2) {
this.setData({ yajinAmount: currentYajinAmount }, () => {
this.handleYajinPay();
});
} else if (currentBuyType === 3) {
// ✅ 调用已修正的积分支付函数
this.handleJifenBuy({ currentTarget: { dataset: { disabled: 'false' } } });
}
} else if (method === 'balance') {
this.fetchBalanceOptions();
}
},
// 🔥 修改点3请求余额抵扣选项前校验积分状态
async fetchBalanceOptions() {
const { currentBuyType, currentHuiyuanId, currentYajinAmount, jifen } = this.data;
// 如果是积分购买,且积分已满,拒绝发起余额抵扣
if (currentBuyType === 3 && jifen >= 10) {
wx.showToast({
title: '积分已满,无需补充',
icon: 'none'
});
return;
}
this.showLoading('获取抵扣信息...');
try {
const res = await request({
url: '/shangpin/czhqdy',
method: 'POST',
data: {
leixing: currentBuyType,
huiyuan_id: currentBuyType === 1 ? currentHuiyuanId : undefined,
yajin_jine: currentBuyType === 2 ? parseInt(currentYajinAmount) : undefined,
}
});
if (res.data.code === 200) {
const options = res.data.data || [];
this.setData({
balanceOptions: options,
showBalanceModal: true
});
} else {
wx.showToast({ title: res.data.message || '获取失败', icon: 'none' });
}
} catch (error) {
console.error('获取抵扣身份失败:', error);
wx.showToast({ title: '网络错误', icon: 'none' });
} finally {
this.hideLoading();
}
},
hideBalanceModal() {
this.setData({ showBalanceModal: false });
},
onBalanceSelect(e) {
const identityId = e.currentTarget.dataset.id;
const selected = this.data.balanceOptions.find(opt => opt.id === identityId);
if (!selected) return;
this.setData({
selectedBalanceId: identityId,
selectedBalanceInfo: selected,
showConfirmModal: true,
showBalanceModal: false
});
},
hideConfirmModal() {
this.setData({ showConfirmModal: false });
},
async confirmBalancePay() {
const { selectedBalanceId, currentBuyType, currentHuiyuanId, currentYajinAmount } = this.data;
if (!selectedBalanceId) return;
this.hideConfirmModal();
this.showLoading('抵扣支付中...');
try {
const res = await request({
url: '/shangpin/dsqrgmdh',
method: 'POST',
data: {
leixing: currentBuyType,
shenfen_id: selectedBalanceId,
huiyuan_id: currentBuyType === 1 ? currentHuiyuanId : undefined,
yajin_jine: currentBuyType === 2 ? parseInt(currentYajinAmount) : undefined,
}
});
if (res.data.code === 200) {
const responseData = res.data.data || {};
await this.updateAfterPayment(
currentBuyType === 1 ? 'huiyuan' : (currentBuyType === 2 ? 'yajin' : 'jifen'),
currentBuyType === 1 ? currentHuiyuanId : null,
responseData
);
wx.showToast({ title: '购买成功', icon: 'success' });
} else {
wx.showToast({ title: res.data.message || '购买失败', icon: 'none' });
}
} catch (error) {
console.error('抵扣支付失败:', error);
wx.showToast({ title: '网络错误', icon: 'none' });
} finally {
this.hideLoading();
}
},
showMemberDetail(e) {
const item = e.currentTarget.dataset.item;
this.setData({
currentMemberDetail: item,
showMemberModal: true
});
},
hideMemberModal() {
this.setData({ showMemberModal: false });
},
});