// 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: '', beizhu: '', zhiding: '', quantity: 1, jine: 0, totalPriceInteger: '0', totalPriceDecimal: '00', 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)) 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, }, () => this.updateTotalPrice()) } else { this.handleDataError('商品数据不完整') } } catch (error) { this.handleDataError('解析商品数据失败') } }, onShow() { this.registerNotificationComponent() PopupService.checkAndShow(this, 'tijiao') }, 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) { app.globalData.globalNotification = { show: (data) => notificationComp.showNotification(data), hide: () => notificationComp.hideNotification() } } }, updateTotalPrice() { const total = this.data.jine * this.data.quantity const intPart = Math.floor(total) const decPart = (total - intPart).toFixed(2).split('.')[1] this.setData({ totalPriceInteger: intPart, totalPriceDecimal: decPart }) }, onQtyMinus() { if (this.data.quantity <= 1) return this.setData({ quantity: this.data.quantity - 1 }, () => this.updateTotalPrice()) }, onQtyPlus() { if (this.data.quantity >= 99) return this.setData({ quantity: this.data.quantity + 1 }, () => this.updateTotalPrice()) }, handleDataError(errorMsg) { wx.showToast({ title: errorMsg || '数据错误', icon: 'none' }) setTimeout(() => wx.navigateBack(), 1500) }, goBack() { wx.navigateBack() }, onNicknameInput(e) { this.setData({ nicheng: e.detail.value.trim() }, () => this.checkFormValid()) }, onRemarkInput(e) { this.setData({ beizhu: e.detail.value.trim() }) }, onZhidingInput(e) { this.setData({ zhiding: e.detail.value.trim() }) }, checkFormValid() { const { nicheng } = this.data this.setData({ canSubmit: nicheng && nicheng.length > 0 && nicheng.length <= 15 }) }, onSubmitOrder() { const { nicheng, beizhu, zhiding, jine, quantity, shangpinId, canSubmit, isSubmitting } = this.data if (!canSubmit) { wx.showToast({ title: '请填写游戏昵称', icon: 'none' }) return } if (isSubmitting) return this.setData({ isSubmitting: true, isPaying: false }) wx.showLoading({ title: '创建订单中...', mask: true }) const timeoutTimer = setTimeout(() => { wx.hideLoading() wx.showToast({ title: '网络超时,请检查您是否已登录', icon: 'none' }) this.setData({ isSubmitting: false, isPaying: false }) }, 10000) const orderData = { shangpin_id: shangpinId, nicheng: nicheng, beizhu: beizhu || '', zhiding: zhiding || '', jine: jine * quantity, shuliang: quantity } 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) { 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(() => { 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: () => 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 }) 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 }) 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) { if (res.data.code === 0) { this.handleConfirmSuccess() } else { this.handleConfirmError(res.data.msg || '订单状态异常') } } else { this.handleConfirmError('网络错误') } }) .catch(() => { clearTimeout(timeoutTimer) wx.hideLoading() this.handleConfirmError('检查失败') }) }, handleConfirmSuccess() { wx.showToast({ title: '购买成功!', icon: 'success', duration: 1500 }) setTimeout(() => wx.switchTab({ url: '/pages/index/index' }), 1500) this.setData({ isSubmitting: false, isPaying: false }) }, handleConfirmError(errorMsg) { const newCheckCount = this.data.checkCount + 1 if (newCheckCount < this.data.maxCheckCount) { this.setData({ checkCount: newCheckCount }) 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 }) } } })