// pages/submit/submit.js const app = getApp() import request from '../../utils/request.js' // 引入弹窗服务(路径请根据项目实际调整) import PopupService from '../../services/popupService.js' Page({ data: { // 全局变量 ossImageUrl: '', apiBaseUrl: '', // 从商品详情页传入的数据 shangpinData: null, shangpinId: '', // 表单数据 nicheng: '', // 游戏昵称/ID beizhu: '', // 备注信息 zhiding: '', // 指定打手ID(新增) jine: 0, // 总金额 // 页面状态 isSubmitting: false, canSubmit: false, isPaying: false, // 支付相关 orderId: '', payParams: null, checkCount: 0, maxCheckCount: 3 }, onLoad(options) { // 获取全局变量 this.setData({ ossImageUrl: app.globalData.ossImageUrl || '', apiBaseUrl: app.globalData.apiBaseUrl || '' }) // 设置页面标题 wx.setNavigationBarTitle({ title: '提交订单' }) // 解析传递的商品数据 try { if (options.data) { const shangpinData = JSON.parse(decodeURIComponent(options.data)) // 处理图片URL(拼接完整路径) if (shangpinData.image && !shangpinData.image.startsWith('http')) { shangpinData.image = this.data.ossImageUrl + shangpinData.image } // 处理价格显示 if (shangpinData.price) { const price = parseFloat(shangpinData.price) || 0 const priceInteger = Math.floor(price) let priceDecimal = '00' const decimalPart = (price - priceInteger).toFixed(2) if (decimalPart > 0) { priceDecimal = decimalPart.toString().split('.')[1] } shangpinData.priceInteger = priceInteger shangpinData.priceDecimal = priceDecimal } // 设置商品数据 this.setData({ shangpinData: shangpinData, shangpinId: shangpinData.id || '', jine: parseFloat(shangpinData.price) || 0, }) } else { this.handleDataError('商品数据不完整') } } catch (error) { this.handleDataError('解析商品数据失败') } }, onShow() { // 原有代码:注册通知组件 this.registerNotificationComponent(); // 🆕 进入页面时触发弹窗检查(PopupService 会自动判断是否展示) PopupService.checkAndShow(this, 'tijiao'); }, // pages/submit/submit.js 中添加 onHide 方法(如果已有则合并内容) onHide() { const popupComp = this.selectComponent('#popupNotice'); if (popupComp && popupComp.cleanup) { popupComp.cleanup(); } }, // 新增:注册通知组件 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() }; } }, /** * 处理数据错误 */ handleDataError(errorMsg) { wx.showToast({ title: errorMsg || '数据错误', icon: 'none' }) setTimeout(() => { wx.navigateBack() }, 1500) }, /** * 游戏昵称输入事件 */ onNicknameInput(e) { const value = e.detail.value.trim() this.setData({ nicheng: value }, () => { this.checkFormValid() }) }, /** * 备注信息输入事件 */ onRemarkInput(e) { const value = e.detail.value.trim() this.setData({ beizhu: value }) }, /** * 指定打手ID输入事件 */ onZhidingInput(e) { const value = e.detail.value.trim() this.setData({ zhiding: value }) }, /** * 检查表单是否有效 */ checkFormValid() { const { nicheng } = this.data const isValid = nicheng && nicheng.length > 0 && nicheng.length <= 15 this.setData({ canSubmit: isValid }) }, /** * 提交订单 */ onSubmitOrder() { const { nicheng, beizhu, zhiding, jine, shangpinId, canSubmit, isSubmitting } = this.data // 验证表单 if (!canSubmit) { wx.showToast({ title: '请填写游戏昵称', icon: 'none' }) return } // 防止重复提交 if (isSubmitting) { return } this.setData({ isSubmitting: true, isPaying: false }) // 显示loading(超时设为10秒) wx.showLoading({ title: '创建订单中...', mask: true }) const timeoutTimer = setTimeout(() => { wx.hideLoading() wx.showToast({ title: '网络超时,请检查您是否已登录', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) }, 10000) // 构建请求数据(添加zhiding字段) const orderData = { shangpin_id: shangpinId, // 商品ID nicheng: nicheng, // 游戏昵称 beizhu: beizhu || '', // 备注(可为空) zhiding: zhiding || '', // 指定打手ID(可为空) jine: jine // 金额 } // 调用后端创建订单接口 request({ url: '/dingdan/xiadan', method: 'POST', data: orderData }) .then(res => { clearTimeout(timeoutTimer) wx.hideLoading() if (res.statusCode === 200 && res.data) { const response = res.data if (response.code === 0 && response.data) { // 保存订单ID和支付参数 const orderId = response.data.dingdanid const payParams = response.data.payParams || {} this.setData({ orderId: orderId, payParams: payParams, isSubmitting: false, isPaying: true, checkCount: 0 }) // 调起微信支付 this.triggerWxPayment(payParams) } else { wx.showToast({ title: response.msg || '创建订单失败', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) } } else { wx.showToast({ title: '网络错误,请重试', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) } }) .catch(error => { clearTimeout(timeoutTimer) wx.hideLoading() wx.showToast({ title: '创建订单失败', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) }) }, /** * 调起微信支付 */ triggerWxPayment(payParams) { // 验证支付参数是否完整 if (!payParams || !payParams.timeStamp || !payParams.nonceStr || !payParams.package || !payParams.signType || !payParams.paySign) { wx.showToast({ title: '支付参数不完整', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) return } wx.requestPayment({ timeStamp: payParams.timeStamp, nonceStr: payParams.nonceStr, package: payParams.package, signType: payParams.signType, paySign: payParams.paySign, success: (res) => { // 支付成功,开始双重确认 this.onPaymentSuccess() }, fail: (err) => { // 根据错误类型处理 if (err.errMsg === 'requestPayment:fail cancel') { // 用户取消支付 this.handleUserCancel() } else { // 其他支付错误 this.handlePaymentFail(err) } } }) }, /** * 处理用户取消支付 */ handleUserCancel() { const { orderId } = this.data wx.showToast({ title: '已取消支付', icon: 'none', duration: 1500 }) // 通知后端用户取消(静默请求,不阻塞用户) if (orderId) { request({ url: '/dingdan/shibai', method: 'POST', data: { dingdanid: orderId, yuanyin: 'user_cancel' } }).catch(() => { // 静默失败 }) } this.setData({ isSubmitting: false, isPaying: false }) }, /** * 处理支付失败 */ handlePaymentFail(err) { const { orderId } = this.data wx.showToast({ title: '支付失败', icon: 'none', duration: 1500 }) // 通知后端支付失败(简化流程,直接请求,不显示loading) if (orderId) { request({ url: '/dingdan/shibai', method: 'POST', data: { dingdanid: orderId, yuanyin: 'payment_fail', cuowu: err.errMsg || '' } }).catch(() => { // 静默失败 }).finally(() => { this.setData({ isSubmitting: false, isPaying: false }) }) } else { this.setData({ isSubmitting: false, isPaying: false }) } }, /** * 支付成功处理(双重确认) */ onPaymentSuccess() { const { orderId } = this.data if (!orderId) { wx.showToast({ title: '订单ID不存在', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) return } // 显示支付成功提示(时间缩短) wx.showToast({ title: '支付成功,确认中...', icon: 'none', duration: 1500 }) // 开始双重确认流程 this.checkOrderStatus() }, /** * 检查订单状态(双重确认) */ checkOrderStatus() { const { orderId, checkCount, maxCheckCount } = this.data // 显示加载(时间缩短) wx.showLoading({ title: `确认支付状态${checkCount > 0 ? `(${checkCount + 1})` : ''}`, mask: true }) // 超时设为5秒 const timeoutTimer = setTimeout(() => { wx.hideLoading() this.handleConfirmError('网络超时') }, 5000) // 向后端发起支付复查请求 request({ url: '/dingdan/fucha', method: 'POST', data: { dingdanid: orderId } }) .then(res => { clearTimeout(timeoutTimer) wx.hideLoading() if (res.statusCode === 200 && res.data) { const response = res.data if (response.code === 0) { // 确认成功,订单状态已更新 this.handleConfirmSuccess() } else { // 后端返回错误 this.handleConfirmError(response.msg || '订单状态异常') } } else { // 网络错误 this.handleConfirmError('网络错误') } }) .catch(error => { clearTimeout(timeoutTimer) wx.hideLoading() this.handleConfirmError('检查失败') }) }, /** * 处理确认成功 */ handleConfirmSuccess() { // 显示最终成功提示 wx.showToast({ title: '购买成功!', icon: 'success', duration: 1500 }) // 1.5秒后跳转到首页 setTimeout(() => { wx.switchTab({ url: '/pages/index/index' }) }, 1500) this.setData({ isSubmitting: false, isPaying: false }) }, /** * 处理确认错误 */ handleConfirmError(errorMsg) { const { checkCount, maxCheckCount } = this.data const newCheckCount = checkCount + 1 if (newCheckCount < maxCheckCount) { // 还可以重试 this.setData({ checkCount: newCheckCount }) // 1秒后重试 setTimeout(() => { this.checkOrderStatus() }, 1000) } else { // 达到最大重试次数 wx.showModal({ title: '支付确认中', content: '支付已成功,但订单状态确认异常。请稍后在订单列表中查看状态,如有问题请联系客服。', showCancel: false, confirmText: '我知道了', success: (res) => { if (res.confirm) { wx.switchTab({ url: '/pages/index/index' }) } } }) this.setData({ isSubmitting: false, isPaying: false }) } } })