hejianhao
2026-06-02 8116f4b4a382e4b5c07e4fb6186bc8da19bc9a32
Merge branch 'feature_v1.0' of http://gitlab.xiaopeng.local:18080/robotaxi1/xp-robotaxi-miniprogram into feature_v1.0
1个文件已修改
322 ■■■■■ 已修改文件
src/pages/cashier/index.tsx 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/cashier/index.tsx
@@ -2,7 +2,7 @@
import { Component } from 'react';
import { connect } from 'react-redux';
import { View, Text, Image, Button } from '@tarojs/components';
import { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchCreditPaySign, dispatchCreditPaySignQuery, dispatchCreditOrderCreate, dispatchCreditOrderQuery } from '../../actions/cashier';
import { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult } from '../../actions/cashier';
import { getStorage } from '../../utils/tools';
import { jumpTo } from '../../utils/jump';
import { dispatchSubscribeCreateFree } from '../../actions/im';
@@ -17,10 +17,6 @@
  dispatchMakePay: any
  dispatchGetResult: any
  dispatchSubscribeCreateFree: any
  dispatchCreditPaySign: any
  dispatchCreditPaySignQuery: any
  dispatchCreditOrderCreate: any
  dispatchCreditOrderQuery: any
}
type State = {
@@ -32,7 +28,7 @@
const ENV = process.env.TARO_ENV;
// @ts-ignore
@connect(() => ({}), { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchSubscribeCreateFree, dispatchCreditPaySign, dispatchCreditPaySignQuery, dispatchCreditOrderCreate, dispatchCreditOrderQuery })
@connect(() => ({}), { dispatchGetOrderInfo, dispatchMakePay, dispatchGetResult, dispatchSubscribeCreateFree })
/**
 * 收银台页面
 *
@@ -129,7 +125,7 @@
            return;
          }
          if (ENV === 'weapp') {
            if (item.payType === 1 || item.payType === 11 || item.payType === 17 || item.payType === 19 || item.payType === 13) {
            if (item.payType === 1 || item.payType === 11 || item.payType === 17 || item.payType === 19) {
              payType = item.payType;
            }
          } else if (ENV === 'alipay') {
@@ -165,12 +161,6 @@
    const { payType } = this.state;
    // 微信支付分走单独流程
    if (payType === 13) {
      this.creditPay();
      return;
    }
    const { openId } = await this.$app.getIdData() || {};
    getStorage(_UID)
      .then(res => {
@@ -199,297 +189,6 @@
        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 = ({ businessOrderId, authOrderId, channelOrderId }): Promise<void> => {
    const maxRetries = 10;
    const interval = 2000;
    Taro.showLoading({ title: '查询订单状态...' });
    return new Promise((resolve) => {
      let retries = 0;
      const poll = 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') {
            Taro.hideLoading();
            this.resetLoading();
            this.creditOrderSuccess(queryRes);
            resolve();
            return;
          }
          if (status === 'REVOKED' || status === 'EXPIRED') {
            Taro.hideLoading();
            this.resetLoading();
            Taro.showToast({ title: '订单已取消或失效', icon: 'none' });
            resolve();
            return;
          }
          if (retries >= maxRetries) {
            Taro.hideLoading();
            this.resetLoading();
            Taro.showToast({ title: '查询超时,请稍后再试', icon: 'none' });
            resolve();
            return;
          }
          // 继续轮询
          this.timer = setTimeout(poll, interval);
        } catch (err) {
          console.error('pollCreditOrderStatus error:', err);
          if (retries >= maxRetries) {
            Taro.hideLoading();
            this.resetLoading();
            Taro.showToast({ title: '查询订单状态失败', icon: 'none' });
            resolve();
            return;
          }
          // 出错也继续重试
          this.timer = setTimeout(poll, 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');
    if (signItem) {
      return signItem.status || '';
    }
    // 未签约时 signList 仅一项且 payType 为空
    if (signList.length === 1 && (signList[0].payType === '' || signList[0].payType == null)) {
      return signList[0]?.status || '';
    }
    return '';
  }
  // 银联云闪付支付
@@ -720,7 +419,7 @@
        {ENV === 'weapp' && this.from !== 'app' && (
          <View className='pay-list'>
            {payTypeList.map(item => {
              //普通微信:1, 建行在微信:17,微信支付分13
              //普通微信:1, 建行在微信:17
              if (item.payType === 1 || item.payType === 11 || item.payType === 17) {
                return (
                  <View key={item.payType} className='pay-item' onClick={() => this.selectPayType(item.payType)}>
@@ -739,19 +438,6 @@
                  <View key={item.payType} className='pay-item' onClick={() => this.selectPayType(item.payType)}>
                    <Image className='icon' src={item.icon}></Image>
                    <View className='name'>{item.description}</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>
                );
              }
              if (item.payType === 13) {
                return (
                  <View key={item.payType} className='pay-item' onClick={() => this.selectPayType(item.payType)}>
                    <Image className='icon' src={require('./assets/ic_wxf.png')}></Image>
                    <View className='name'>微信支付分 | 先乘后付</View>
                    {payType === item.payType ? (
                      <Image className='ic-right' src={require('./assets/ic_select.png')}></Image>
                    ) : (