修正了 pages 名为拼音的问题

This commit is contained in:
2026-06-13 10:44:02 +08:00
parent 76cc4ac55e
commit 296e41a8a7
249 changed files with 29660 additions and 29505 deletions

View File

@@ -0,0 +1,975 @@
// pages/dashou-chongzhi/index.js
import request from '../../utils/request';
// 引入弹窗服务(路径根据实际调整)
import PopupService from '../../services/popupService.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();
}
},
onShow() {
// 每次显示页面都刷新数据
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 });
},
});