| | |
| | | import { Component } from 'react'; |
| | | import { connect } from 'react-redux'; |
| | | import { View, Text, Image, Button } from '@tarojs/components'; |
| | | import { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult } from '../../actions/cashier'; |
| | | import { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchCreditPaySign, dispatchCreditPaySignQuery, dispatchCreditOrderCreate, dispatchCreditOrderQuery } from '../../actions/cashier'; |
| | | import { getStorage } from '../../utils/tools'; |
| | | import { jumpTo } from '../../utils/jump'; |
| | | import { dispatchSubscribeCreateFree } from '../../actions/im'; |
| | |
| | | dispatchMakePay: any |
| | | dispatchGetResult: any |
| | | dispatchSubscribeCreateFree: any |
| | | dispatchCreditPaySign: any |
| | | dispatchCreditPaySignQuery: any |
| | | dispatchCreditOrderCreate: any |
| | | dispatchCreditOrderQuery: any |
| | | } |
| | | |
| | | type State = { |
| | |
| | | const ENV = process.env.TARO_ENV; |
| | | |
| | | // @ts-ignore |
| | | @connect(() => ({}), { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchSubscribeCreateFree }) |
| | | @connect(() => ({}), { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchSubscribeCreateFree, dispatchCreditPaySign, dispatchCreditPaySignQuery, dispatchCreditOrderCreate, dispatchCreditOrderQuery }) |
| | | /** |
| | | * 收银台页面 |
| | | * |
| | |
| | | return; |
| | | } |
| | | if (ENV === 'weapp') { |
| | | if (item.payType === 1 || item.payType === 11 || item.payType === 17 || item.payType === 19) { |
| | | if (item.payType === 1 || item.payType === 11 || item.payType === 17 || item.payType === 19 || item.payType === 13) { |
| | | payType = item.payType; |
| | | } |
| | | } else if (ENV === 'alipay') { |
| | |
| | | } |
| | | |
| | | const { payType } = this.state; |
| | | |
| | | // 微信支付分走单独流程 |
| | | if (payType === 13) { |
| | | this.creditPay(); |
| | | return; |
| | | } |
| | | |
| | | const { openId } = await this.$app.getIdData() || {}; |
| | | getStorage(_UID) |
| | | .then(res => { |
| | |
| | | console.log(err) |
| | | }) |
| | | .then(() => this.loading = false); |
| | | } |
| | | |
| | | // 微信支付分支付流程 |
| | | creditPay = async () => { |
| | | try { |
| | | // 第一步:查询微信支付分开通状态 |
| | | const status = await this.queryCreditPaySignStatus(); |
| | | console.log('creditPay sign status:', status); |
| | | |
| | | if (status === 'VALID') { |
| | | // 已开通,进入信用下单流程 |
| | | await this.creditOrderCreate(); |
| | | } else if (status === 'INVALID' || status === 'INIT') { |
| | | // 未签约,走签约开通流程 |
| | | await this.creditPaySign(); |
| | | } else { |
| | | Taro.showToast({ title: `当前状态: ${status || '未知'},暂不支持`, icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } catch (err) { |
| | | console.error('creditPay error:', err); |
| | | Taro.showToast({ title: '查询支付分状态失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } |
| | | |
| | | // 微信支付分签约开通 |
| | | creditPaySign = async () => { |
| | | try { |
| | | // 调用签约接口获取 signStr(预授权token) |
| | | const signRes = await this.props.dispatchCreditPaySign({ |
| | | token: this.token, |
| | | payType: 13, |
| | | returnUrl: null, |
| | | cancelUrl: null, |
| | | }); |
| | | console.log('creditPaySign result:', signRes); |
| | | |
| | | const signStr = signRes?.signStr; |
| | | if (!signStr) { |
| | | Taro.showToast({ title: '获取授权信息失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | return; |
| | | } |
| | | |
| | | // 拉起微信支付分授权窗口 |
| | | // @ts-ignore |
| | | if (wx.openBusinessView) { |
| | | // 即将跳转到微信侧,解锁 loading(用户在外部小程序中无法操作当前页面) |
| | | this.resetLoading(); |
| | | // @ts-ignore |
| | | wx.openBusinessView({ |
| | | businessType: 'wxpayScoreEnable', |
| | | extraData: { |
| | | apply_permissions_token: signStr, |
| | | }, |
| | | success: () => { |
| | | console.log('openBusinessView success'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('openBusinessView fail:', err); |
| | | Taro.showToast({ title: '拉起授权失败', icon: 'none' }); |
| | | }, |
| | | complete: () => { |
| | | console.log('openBusinessView complete'); |
| | | }, |
| | | }); |
| | | |
| | | // 监听从微信支付分小程序返回 |
| | | const handleAppShow = async (res) => { |
| | | if (res && res.scene === 1038) { |
| | | const { appId } = res.referrerInfo || {}; |
| | | if (appId === 'wxd8f3793ea3b935b8') { |
| | | Taro.offAppShow(handleAppShow); |
| | | this.appShowListener = null; |
| | | // 用户返回,重新加锁 |
| | | this.loading = true; |
| | | try { |
| | | const newStatus = await this.queryCreditPaySignStatus(); |
| | | console.log('sign callback status:', newStatus); |
| | | if (newStatus === 'VALID') { |
| | | Taro.showToast({ title: '开通成功', icon: 'success' }); |
| | | await this.creditOrderCreate(); |
| | | } else { |
| | | Taro.showToast({ title: '开通未完成', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } catch (e) { |
| | | console.error('query sign status after auth error:', e); |
| | | Taro.showToast({ title: '查询签约结果失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | this.appShowListener = handleAppShow; |
| | | Taro.onAppShow(handleAppShow); |
| | | } else { |
| | | Taro.showToast({ title: '请升级微信版本后重试', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } catch (err) { |
| | | console.error('creditPaySign error:', err); |
| | | Taro.showToast({ title: '签约请求失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } |
| | | |
| | | // 信用下单 |
| | | creditOrderCreate = async () => { |
| | | try { |
| | | Taro.showLoading({ title: '下单中...' }); |
| | | const { openId } = await this.$app.getIdData() || {}; |
| | | const orderRes = await this.props.dispatchCreditOrderCreate({ |
| | | token: this.token, |
| | | payType: 13, |
| | | openId, |
| | | }); |
| | | Taro.hideLoading(); |
| | | console.log('creditOrderCreate result:', orderRes); |
| | | |
| | | if (!orderRes) { |
| | | Taro.showToast({ title: '信用下单失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | return; |
| | | } |
| | | |
| | | const { businessOrderId, authOrderId, channelOrderId } = orderRes; |
| | | const packageStr = orderRes.package; |
| | | |
| | | // 拉起微信支付分订单确认页 |
| | | // @ts-ignore |
| | | if (wx.openBusinessView) { |
| | | // 即将跳转到微信侧,解锁 loading |
| | | this.resetLoading(); |
| | | // @ts-ignore |
| | | wx.openBusinessView({ |
| | | businessType: 'wxpayScoreUse', |
| | | extraData: { |
| | | package: packageStr, |
| | | }, |
| | | success: () => { |
| | | console.log('openBusinessView wxpayScoreUse success'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('openBusinessView wxpayScoreUse fail:', err); |
| | | Taro.showToast({ title: '拉起支付分订单失败', icon: 'none' }); |
| | | }, |
| | | complete: () => { |
| | | console.log('openBusinessView wxpayScoreUse complete'); |
| | | }, |
| | | }); |
| | | |
| | | // 监听从微信支付分小程序返回 |
| | | const handleAppShow = async (res) => { |
| | | if (res && res.scene === 1038) { |
| | | const { appId } = res.referrerInfo || {}; |
| | | if (appId === 'wxd8f3793ea3b935b8') { |
| | | Taro.offAppShow(handleAppShow); |
| | | this.appShowListener = null; |
| | | this.loading = true; |
| | | // 轮询查询信用订单状态 |
| | | await this.pollCreditOrderStatus({ businessOrderId, authOrderId, channelOrderId }); |
| | | } |
| | | } |
| | | }; |
| | | this.appShowListener = handleAppShow; |
| | | Taro.onAppShow(handleAppShow); |
| | | } else {/* */ |
| | | Taro.showToast({ title: '请升级微信版本后重试', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } catch (err) { |
| | | Taro.hideLoading(); |
| | | console.error('creditOrderCreate error:', err); |
| | | Taro.showToast({ title: '信用下单失败', icon: 'none' }); |
| | | this.resetLoading(); |
| | | } |
| | | } |
| | | |
| | | // 轮询查询信用订单状态 |
| | | pollCreditOrderStatus = async ({ businessOrderId, authOrderId, channelOrderId }) => { |
| | | const maxRetries = 10; |
| | | const interval = 2000; |
| | | let retries = 0; |
| | | |
| | | Taro.showLoading({ title: '查询订单状态...' }); |
| | | |
| | | const poll = () => { |
| | | this.timer = setInterval(async () => { |
| | | retries++; |
| | | try { |
| | | const queryRes = await this.props.dispatchCreditOrderQuery({ |
| | | token: this.token, |
| | | businessOrderId, |
| | | authOrderId, |
| | | channelOrderId, |
| | | payType: 13, |
| | | }); |
| | | console.log('creditOrderQuery result:', queryRes); |
| | | |
| | | const status = queryRes?.creditOrderStatus; |
| | | if (status === 'DOING' || status === 'DONE') { |
| | | clearInterval(this.timer); |
| | | Taro.hideLoading(); |
| | | this.resetLoading(); |
| | | this.creditOrderSuccess(queryRes); |
| | | return; |
| | | } |
| | | |
| | | if (status === 'REVOKED' || status === 'EXPIRED') { |
| | | clearInterval(this.timer); |
| | | Taro.hideLoading(); |
| | | this.resetLoading(); |
| | | Taro.showToast({ title: '订单已取消或失效', icon: 'none' }); |
| | | return; |
| | | } |
| | | |
| | | if (retries >= maxRetries) { |
| | | clearInterval(this.timer); |
| | | Taro.hideLoading(); |
| | | this.resetLoading(); |
| | | Taro.showToast({ title: '查询超时,请稍后再试', icon: 'none' }); |
| | | } |
| | | } catch (err) { |
| | | console.error('pollCreditOrderStatus error:', err); |
| | | if (retries >= maxRetries) { |
| | | clearInterval(this.timer); |
| | | Taro.hideLoading(); |
| | | this.resetLoading(); |
| | | Taro.showToast({ title: '查询订单状态失败', icon: 'none' }); |
| | | } |
| | | } |
| | | }, interval); |
| | | }; |
| | | |
| | | poll(); |
| | | } |
| | | |
| | | // 统一重置 loading 状态 |
| | | resetLoading = () => { |
| | | this.loading = false; |
| | | } |
| | | |
| | | // 信用订单成功回调 |
| | | creditOrderSuccess = (orderRes) => { |
| | | console.log('creditOrderSuccess:', orderRes); |
| | | |
| | | if (this.from === 'app') { |
| | | this.setState({ showModal: true }); |
| | | return; |
| | | } |
| | | |
| | | if (this.from === 'miniapp') { |
| | | Taro.eventCenter.trigger('cashier:paySuccess', { |
| | | businessOrderId: orderRes.businessOrderId, |
| | | channelOrderId: orderRes.channelOrderId, |
| | | authOrderId: orderRes.authOrderId, |
| | | creditOrderStatus: orderRes.creditOrderStatus, |
| | | }); |
| | | jumpTo({ type: 'back' }); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 查询微信支付分签约状态 |
| | | queryCreditPaySignStatus = async (): Promise<string> => { |
| | | const signRes = await this.props.dispatchCreditPaySignQuery({ |
| | | token: this.token, |
| | | payType: 13, |
| | | }); |
| | | console.log('creditPaySignQuery result:', signRes); |
| | | |
| | | const signList = signRes?.signList || []; |
| | | const signItem = signList.find((item: any) => String(item.payType) === '13'); |
| | | return signItem?.status || ''; |
| | | } |
| | | |
| | | // 银联云闪付支付 |
| | |
| | | </View> |
| | | ); |
| | | } |
| | | if (item.payType === 13) { |
| | | return ( |
| | | <View key={item.payType} className='pay-item' onClick={() => this.selectPayType(item.payType)}> |
| | | <Image className='icon' src={require('./assets/ic_wx.png')}></Image> |
| | | <View className='name'>微信支付分 | 先乘后付</View> |
| | | {payType === item.payType ? ( |
| | | <Image className='ic-right' src={require('./assets/ic_select.png')}></Image> |
| | | ) : ( |
| | | <Image className='ic-right' src={require('./assets/ic_se_default.png')}></Image> |
| | | )} |
| | | </View> |
| | | ); |
| | | } |
| | | })} |
| | | </View> |
| | | )} |