1026 lines
29 KiB
JavaScript
1026 lines
29 KiB
JavaScript
// pages/fighter-recharge/fighter-recharge.js
|
||
import request from '../../utils/request';
|
||
import PopupService from '../../services/popupService.js';
|
||
import { ensurePhoneAuth } from '../../utils/phone-auth.js';
|
||
import { ICON_KEYS, resolveConfiguredIcon, resolveMiniappIcon, ICON_FOLDER, refreshPindaoConfig } from '../../utils/miniapp-icons.js';
|
||
import { resolveAvatarFromStorage, onAvatarImageError } from '../../utils/avatar.js';
|
||
|
||
const app = getApp();
|
||
|
||
const PLATFORM_ADVANTAGE_META = [
|
||
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_1, title: '订单丰富', desc: '平台单、商家单多种类型' },
|
||
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_2, title: '俱乐部专属', desc: '按俱乐部独立配置权益' },
|
||
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_3, title: '客服支持', desc: '遇到问题随时联系客服' },
|
||
{ key: ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_4, title: '安全可靠', desc: '资金与订单平台保障' },
|
||
];
|
||
|
||
Page({
|
||
data: {
|
||
imgUrls: { pageBg: '' },
|
||
avatarUrl: '',
|
||
nickname: '',
|
||
uid: '',
|
||
memberBadge: '会员',
|
||
agreed: false,
|
||
memberBenefits: [],
|
||
platformAdvantages: [],
|
||
clubmber: [],
|
||
jifen: 0,
|
||
huiyuanList: [],
|
||
currentHuiyuanIndex: 0,
|
||
currentHuiyuan: {},
|
||
payLoading: false,
|
||
loadingText: '支付中...',
|
||
currentDingdanid: '',
|
||
detailRules: [],
|
||
jumpParams: {},
|
||
showPayMethodModal: false,
|
||
currentBuyType: null,
|
||
currentHuiyuanId: null,
|
||
currentBuyIsTrial: false,
|
||
showBalanceModal: false,
|
||
balanceOptions: [],
|
||
selectedBalanceId: null,
|
||
showConfirmModal: false,
|
||
selectedBalanceInfo: null,
|
||
showMemberModal: false,
|
||
currentMemberDetail: null,
|
||
},
|
||
|
||
// ========== 生命周期函数 ==========
|
||
onLoad(options) {
|
||
this.setData({ jumpParams: options || {} });
|
||
this.initImages();
|
||
this.loadUserInfo();
|
||
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();
|
||
this.refreshConfiguredIcons();
|
||
|
||
// 调用统一弹窗组件检查并展示公告
|
||
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();
|
||
},
|
||
|
||
initImages() {
|
||
this.setData({
|
||
imgUrls: {
|
||
pageBg: resolveConfiguredIcon(app, ICON_KEYS.FIGHTER_RECHARGE_VIP_BG),
|
||
},
|
||
platformAdvantages: this.buildPlatformAdvantages(),
|
||
});
|
||
},
|
||
|
||
async refreshConfiguredIcons() {
|
||
try {
|
||
await refreshPindaoConfig(app);
|
||
} catch (e) {
|
||
console.warn('refreshConfiguredIcons failed', e);
|
||
}
|
||
this.initImages();
|
||
const list = this.data.huiyuanList || [];
|
||
const idx = this.data.currentHuiyuanIndex || 0;
|
||
if (list.length) {
|
||
this.applyCurrentHuiyuan(list[idx] || {}, idx);
|
||
}
|
||
this.loadUserInfo();
|
||
},
|
||
|
||
_icon(key, fallbackRel) {
|
||
return resolveMiniappIcon(app, key, fallbackRel);
|
||
},
|
||
|
||
buildPlatformAdvantages() {
|
||
const fb = (name) => `${ICON_FOLDER}/${name}.png`;
|
||
const keys = [
|
||
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_1,
|
||
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_2,
|
||
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_3,
|
||
ICON_KEYS.FIGHTER_RECHARGE_ADVANTAGE_4,
|
||
];
|
||
return PLATFORM_ADVANTAGE_META.map((item, i) => ({
|
||
title: item.title,
|
||
desc: item.desc,
|
||
iconUrl: this._icon(keys[i], fb(keys[i])),
|
||
}));
|
||
},
|
||
|
||
loadUserInfo() {
|
||
const gd = app.globalData || {};
|
||
this.setData({
|
||
avatarUrl: resolveAvatarFromStorage(app),
|
||
nickname: gd.dashouNicheng || gd.nicheng || '打手',
|
||
uid: wx.getStorageSync('uid') || gd.uid || '',
|
||
});
|
||
},
|
||
|
||
onAvatarError() {
|
||
onAvatarImageError(this, 'avatarUrl', app);
|
||
},
|
||
|
||
resolveOssUrl(path) {
|
||
if (!path) return '';
|
||
if (path.startsWith('http')) return path;
|
||
return (app.globalData.ossImageUrl || '') + path;
|
||
},
|
||
|
||
buildMemberBenefits(huiyuan = {}) {
|
||
const name = huiyuan.mingzi || '会员';
|
||
const formalPrice = huiyuan.jiage || '0';
|
||
const trialPrice = huiyuan.trial_price || '0';
|
||
const fb = (name) => `${ICON_FOLDER}/${name}.png`;
|
||
const meta = [
|
||
{
|
||
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_1,
|
||
title: '充值立得',
|
||
desc: `开通${name}正式版 ¥${formalPrice},享优先接单`,
|
||
},
|
||
{
|
||
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_2,
|
||
title: '体验尝鲜',
|
||
desc: huiyuan.can_buy_trial
|
||
? `体验版 ¥${trialPrice}/${huiyuan.trial_days || 0}天,终身1次`
|
||
: '正式会员支持余额抵扣',
|
||
},
|
||
{
|
||
key: ICON_KEYS.FIGHTER_RECHARGE_BENEFIT_3,
|
||
title: '专属特权',
|
||
desc: '解锁平台单、优质接单等待遇',
|
||
},
|
||
];
|
||
return meta.map((item) => ({
|
||
title: item.title,
|
||
desc: item.desc,
|
||
iconUrl: this._icon(item.key, fb(item.key)),
|
||
}));
|
||
},
|
||
|
||
applyCurrentHuiyuan(huiyuan, index) {
|
||
this.setData({
|
||
currentHuiyuanIndex: index,
|
||
currentHuiyuan: huiyuan,
|
||
detailRules: this.buildDetailRules(huiyuan),
|
||
memberBenefits: this.buildMemberBenefits(huiyuan),
|
||
memberBadge: huiyuan.mingzi || '会员',
|
||
});
|
||
},
|
||
|
||
toggleAgree() {
|
||
this.setData({ agreed: !this.data.agreed });
|
||
},
|
||
|
||
goToDeposit() {
|
||
wx.navigateTo({ url: '/pages/fighter-recharge/fighter-deposit' });
|
||
},
|
||
|
||
onTapTrial(e) {
|
||
if (!this.data.agreed) {
|
||
wx.showToast({ title: '请先阅读并同意会员协议', icon: 'none' });
|
||
return;
|
||
}
|
||
this.onBuyHuiyuanClick(e);
|
||
},
|
||
|
||
onTapFormal(e) {
|
||
if (!this.data.agreed) {
|
||
wx.showToast({ title: '请先阅读并同意会员协议', icon: 'none' });
|
||
return;
|
||
}
|
||
this.onBuyHuiyuanClick(e);
|
||
},
|
||
|
||
stopPropagation() {},
|
||
|
||
// ========== 从全局变量加载数据 ==========
|
||
loadFromGlobalData() {
|
||
const app = getApp();
|
||
const globalData = app.globalData || {};
|
||
|
||
// ✅ 重要:保持字段对应关系
|
||
// 全局变量中是 clumber,页面中是 clubmber
|
||
// 全局变量中是 jinfen,页面中是 jifen
|
||
const rawClubmber = globalData.clumber || [];
|
||
const clubmber = rawClubmber.filter((c) => c && c.huiyuanid);
|
||
|
||
this.setData({
|
||
clubmber: clubmber,
|
||
jifen: globalData.jinfen || 0,
|
||
});
|
||
},
|
||
|
||
// ========== 获取会员商品列表 ==========
|
||
async fetchHuiyuanList() {
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/dshyhq',
|
||
method: 'POST',
|
||
data: {}
|
||
});
|
||
|
||
if (res.data.code === 200) {
|
||
const huiyuanList = this.processHuiyuanList(res.data.data || []);
|
||
let index = 0;
|
||
const targetId = this.data.jumpParams.huiyuanId;
|
||
if (targetId) {
|
||
const found = huiyuanList.findIndex((h) => String(h.id) === String(targetId));
|
||
if (found >= 0) index = found;
|
||
}
|
||
this.applyCurrentHuiyuan(huiyuanList[index] || {}, index);
|
||
this.setData({ huiyuanList });
|
||
} 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,
|
||
cardImageUrl: this.resolveOssUrl(item.card_image),
|
||
cardBgUrl: this.resolveOssUrl(item.card_bg),
|
||
};
|
||
});
|
||
},
|
||
|
||
// ========== Swiper切换事件 ==========
|
||
onSwiperChange(e) {
|
||
const current = e.detail.current;
|
||
const huiyuanList = this.data.huiyuanList || [];
|
||
this.applyCurrentHuiyuan(huiyuanList[current] || {}, current);
|
||
},
|
||
|
||
selectHuiyuan(e) {
|
||
const index = e.currentTarget.dataset.index;
|
||
const huiyuanList = this.data.huiyuanList || [];
|
||
this.applyCurrentHuiyuan(huiyuanList[index] || {}, index);
|
||
},
|
||
|
||
buildDetailRules(huiyuan = {}) {
|
||
const formalDays = huiyuan.formal_days || 30;
|
||
const rules = [
|
||
`有效期${formalDays}天`,
|
||
'可接多种订单类型',
|
||
'支持续费,天数叠加',
|
||
'正式会员支持余额抵扣',
|
||
];
|
||
if (huiyuan.can_buy_trial) {
|
||
rules[3] = `体验版¥${huiyuan.trial_price}/${huiyuan.trial_days}天`;
|
||
}
|
||
return rules.slice(0, 4);
|
||
},
|
||
|
||
// ========== 格式化到期时间 ==========
|
||
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.scrollTo !== 'jifen') return;
|
||
setTimeout(() => {
|
||
wx.pageScrollTo({ selector: '#jifen-section', duration: 300 });
|
||
}, 600);
|
||
},
|
||
|
||
// ========== 积分充值相关 ==========
|
||
// 🔥 修改点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, payMethod = 'wx') {
|
||
const huiyuanId = e.currentTarget.dataset.id;
|
||
const isTrial = e.currentTarget.dataset.trial === true || e.currentTarget.dataset.trial === 'true';
|
||
|
||
if (!huiyuanId) {
|
||
wx.showToast({
|
||
title: '会员信息错误',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 支付宝无需微信确认弹窗
|
||
if (payMethod !== 'alipay') {
|
||
const confirmed = await this.confirmWechatPurchase('huiyuan');
|
||
if (!confirmed) return;
|
||
}
|
||
|
||
this.showLoading('发起会员支付中...');
|
||
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/huiyuangm',
|
||
method: 'POST',
|
||
data: {
|
||
huiyuanid: huiyuanId,
|
||
is_trial: isTrial,
|
||
pay_method: payMethod === 'alipay' ? 'alipay' : 'wechat'
|
||
}
|
||
});
|
||
|
||
if (res.data.code === 200) {
|
||
const payParams = res.data.payParams;
|
||
const dingdanid = res.data.dingdanid;
|
||
|
||
this.setData({
|
||
currentDingdanid: dingdanid
|
||
});
|
||
|
||
// 支付宝分支:跳转二维码页
|
||
if (payMethod === 'alipay' || (payParams && payParams.pay_method === 'alipay')) {
|
||
this.hideLoading();
|
||
this.triggerAlipayPayment(payParams, dingdanid, 'huiyuan');
|
||
return;
|
||
}
|
||
|
||
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, payMethod = 'wx') {
|
||
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;
|
||
}
|
||
|
||
// 支付宝无需微信确认弹窗
|
||
if (payMethod !== 'alipay') {
|
||
const confirmed = await this.confirmWechatPurchase('jifen');
|
||
if (!confirmed) return;
|
||
}
|
||
|
||
this.showLoading('发起积分支付中...');
|
||
|
||
try {
|
||
const res = await request({
|
||
url: '/shangpin/jifenbc', // 正确的积分下单接口
|
||
method: 'POST',
|
||
data: {
|
||
pay_method: payMethod === 'alipay' ? 'alipay' : 'wechat'
|
||
}
|
||
});
|
||
|
||
if (res.data.code === 200) {
|
||
const payParams = res.data.payParams;
|
||
const dingdanid = res.data.dingdanid;
|
||
|
||
this.setData({ currentDingdanid: dingdanid });
|
||
|
||
// 支付宝分支:跳转二维码页
|
||
if (payMethod === 'alipay' || (payParams && payParams.pay_method === 'alipay')) {
|
||
this.hideLoading();
|
||
this.triggerAlipayPayment(payParams, dingdanid, 'jifen');
|
||
return;
|
||
}
|
||
|
||
await this.wechatPay(payParams, 'jifen');
|
||
} else {
|
||
wx.showToast({ title: res.data.message || '积分支付发起失败', icon: 'none' });
|
||
}
|
||
} catch (error) {
|
||
wx.showToast({ title: '支付失败,请重试', icon: 'none' });
|
||
} finally {
|
||
this.hideLoading();
|
||
}
|
||
},
|
||
|
||
// ========== 支付宝扫码支付封装 ==========
|
||
// 跳转到 alipay-webview 展示二维码,并按 payType 指定轮询接口
|
||
triggerAlipayPayment(payParams, orderId, payType) {
|
||
const qrImage = payParams && payParams.qr_image ? payParams.qr_image : '';
|
||
if (!qrImage) {
|
||
wx.showToast({ title: '支付宝二维码生成失败', icon: 'none' });
|
||
return;
|
||
}
|
||
const app = getApp();
|
||
app.globalData.alipayQrImage = qrImage;
|
||
let pollUrl = '/dingdan/fucha';
|
||
if (payType === 'huiyuan') pollUrl = '/shangpin/huiyuanlx';
|
||
else if (payType === 'jifen') pollUrl = '/shangpin/jifenlunxun';
|
||
const encodedPollUrl = encodeURIComponent(pollUrl);
|
||
wx.navigateTo({
|
||
url: `/pages/alipay-webview/alipay-webview?orderId=${orderId}&pollUrl=${encodedPollUrl}`
|
||
});
|
||
},
|
||
|
||
// ========== 微信支付封装 ==========
|
||
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));
|
||
},
|
||
|
||
/** 微信支付下单前确认(仅微信购买会员/押金/积分) */
|
||
confirmWechatPurchase(kind) {
|
||
const labelMap = {
|
||
huiyuan: '会员',
|
||
yajin: '押金',
|
||
jifen: '积分',
|
||
};
|
||
const label = labelMap[kind] || '服务';
|
||
return new Promise((resolve) => {
|
||
wx.showModal({
|
||
title: '确认微信支付',
|
||
content: `您即将通过微信支付购买${label}。请点击「确认购买」后才会发起支付;购买成功后不可随意退款,请确认无误后再继续。`,
|
||
confirmText: '确认购买',
|
||
cancelText: '再想想',
|
||
success: (res) => resolve(!!res.confirm),
|
||
fail: () => resolve(false),
|
||
});
|
||
});
|
||
},
|
||
|
||
// ========== 新增功能(余额抵扣等) ==========
|
||
onBuyHuiyuanClick(e) {
|
||
const huiyuanId = e.currentTarget.dataset.id;
|
||
const isTrial = e.currentTarget.dataset.trial === true || e.currentTarget.dataset.trial === 'true';
|
||
|
||
if (isTrial) {
|
||
this.setData({ currentBuyIsTrial: true });
|
||
this.handleHuiyuanBuy(e);
|
||
return;
|
||
}
|
||
|
||
this.setData({
|
||
currentBuyType: 1,
|
||
currentHuiyuanId: huiyuanId,
|
||
currentBuyIsTrial: false,
|
||
showPayMethodModal: true,
|
||
});
|
||
},
|
||
|
||
hidePayMethodModal() {
|
||
this.setData({ showPayMethodModal: false });
|
||
},
|
||
|
||
// 🔥 修改点2:选择支付方式时再次校验积分状态(防止异步过程中积分变化)
|
||
onPayMethodSelect(e) {
|
||
const method = e.currentTarget.dataset.method;
|
||
const { currentBuyType, currentHuiyuanId, jifen } = this.data;
|
||
this.hidePayMethodModal();
|
||
|
||
if (currentBuyType === 3 && jifen >= 10) {
|
||
wx.showToast({ title: '积分已满,无需补充', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
if (method === 'wx' || method === 'alipay') {
|
||
const payMethod = method === 'alipay' ? 'alipay' : 'wx';
|
||
if (currentBuyType === 1) {
|
||
this.handleHuiyuanBuy({
|
||
currentTarget: { dataset: { id: currentHuiyuanId, trial: this.data.currentBuyIsTrial ? 'true' : 'false' } },
|
||
}, payMethod);
|
||
} else if (currentBuyType === 3) {
|
||
this.handleJifenBuy({ currentTarget: { dataset: { disabled: 'false' } } }, payMethod);
|
||
}
|
||
} else if (method === 'balance') {
|
||
this.fetchBalanceOptions();
|
||
}
|
||
},
|
||
|
||
// 🔥 修改点3:请求余额抵扣选项前校验积分状态
|
||
async fetchBalanceOptions() {
|
||
const { currentBuyType, currentHuiyuanId, currentBuyIsTrial, jifen } = this.data;
|
||
|
||
if (currentBuyType === 1 && currentBuyIsTrial) {
|
||
wx.showToast({ title: '体验会员仅支持微信支付', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
// 如果是积分购买,且积分已满,拒绝发起余额抵扣
|
||
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,
|
||
is_trial: currentBuyType === 1 ? currentBuyIsTrial : 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, currentBuyIsTrial } = 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,
|
||
is_trial: currentBuyType === 1 ? currentBuyIsTrial : undefined,
|
||
},
|
||
});
|
||
|
||
if (res.data.code === 200) {
|
||
const responseData = res.data.data || {};
|
||
await this.updateAfterPayment(
|
||
currentBuyType === 1 ? 'huiyuan' : '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 });
|
||
},
|
||
}); |