bloc.dart 5.78 KB
import 'dart:io';

import 'package:bloc/bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:fluwx/fluwx.dart';
import 'package:tobias/tobias.dart';
import 'package:wow_english/generated/json/base/json_convert_content.dart';
import 'package:wow_english/models/product_entity.dart';

import '../../common/request/dao/shop_dao.dart';
import '../../common/request/exception.dart';
import '../../utils/loading.dart';
import '../../utils/log_util.dart';
import '../../utils/toast_util.dart';
import 'event.dart';
import 'state.dart';

class ShoppingBloc extends Bloc<ShoppingEvent, ShoppingState> {

  ProductEntity? _productData;

  ProductEntity? get productData => _productData;

  PaymentChannel _curPaymentChannel = PaymentChannel.wechatPay;

  PaymentChannel get curPaymentChannel => _curPaymentChannel;

  Fluwx? fluwx;
  Function(WeChatResponse)? wxPayResponseListener;
  bool _isWxPayListenerInitialized = false;



  ShoppingBloc(this._productData) : super(ShoppingState().init()) {
    //页面初始化时刻
    on<InitEvent>(_init);
    on<ChangePaymentChannelEvent>(_changePaymentChannel);
    on<DoPayEvent>(_startPay);
    on<WxPaySuccessEvent>((event, emit) {
      emit(PaySuccessState());
    });
  }

  void _init(InitEvent event, Emitter<ShoppingState> emit) async {
    //处理一些初始化操作,然后刷新界面
    emit(state.clone());
  }

  /// 更换支付渠道
  void _changePaymentChannel(ChangePaymentChannelEvent event,
      Emitter<ShoppingState> emitter) async {
    Log.d("_curPaymentChannel=$_curPaymentChannel, event.paymentChannel=${event.paymentChannel}");
    if (_curPaymentChannel != event.paymentChannel) {
      _curPaymentChannel = event.paymentChannel;
      emitter(PaymentChannelChangeState());
    }
  }

  void _startPay(DoPayEvent event,
      Emitter<ShoppingState> emitter) async {
    //如果event.productEntity为空,中断流程并toast提示
    if (event.productEntity == null) {
      showToast("商品信息为空");
      return;
    }
    final productEntitySafely = event.productEntity!;
    try {
      await loading(() async {
        final Map<String, dynamic>? orderInfo = await ShopDao.createOrder(productEntitySafely);
        final String? orderNo = orderInfo?.getOrNull("orderNo");
        if (orderNo == null) {
          showToast("订单创建失败");
          return;
        }

        if (event.paymentChannel == PaymentChannel.wechatPay) {
          if (_isWxPayListenerInitialized == false) {
            _isWxPayListenerInitialized = true;
            fluwx = Fluwx();
            await fluwx?.registerApi(appId: "wx365e5a79956a450a",
                universalLink: "https://app-api.wowenglish.com.cn/app/");
            wxPayResponseListener = (WeChatResponse response) {
              debugPrint("wxPayResponseListener $response");
              if (response is WeChatPaymentResponse) {
                if (response.errCode == 0) {
                  showToast("支付成功");
                  // Log.d("emitter isDone=${emitter.isDone}");

                  /// 报错!_isCompleted  emit was called after an event handler completed normally
                  // emitter(PaySuccessState());

                  add(WxPaySuccessEvent());
                } else {
                  showToast("支付失败");
                }
              }
            };
            fluwx?.addSubscriber(wxPayResponseListener!);
          }

          bool installed = await fluwx?.isWeChatInstalled == true;
          if (!installed) {
            // 未安装微信,请前去下载
            String name = Platform.isIOS ? "AppStore" : "应用商店";
            showToast("您未安装微信,请前往$name下载~");
            return;
          }

          final Map<String, dynamic>? wxPayOrderInfo = await ShopDao.getWxPayToken(orderNo);
          if (wxPayOrderInfo == null) {
            showToast("微信订单创建失败");
            return;
          }

          await fluwx?.pay(
              which: Payment(
                appId: wxPayOrderInfo['appId'].toString(),
                partnerId: wxPayOrderInfo['partnerId'].toString(),
                prepayId: wxPayOrderInfo['prepayId'].toString(),
                packageValue: wxPayOrderInfo['packageValue'].toString(),
                nonceStr: wxPayOrderInfo['nonceStr'].toString(),
                timestamp: int.parse(wxPayOrderInfo['timeStamp']),
                sign: wxPayOrderInfo['sign'].toString(),
              ));
        } else {
          final Map<String, dynamic>? aliPayOrderInfo = await ShopDao.getAliPayToken(orderNo);
          debugPrint("aliPayOrderInfo=$aliPayOrderInfo type=${aliPayOrderInfo?.runtimeType}");
          final String? aliPayInfo = aliPayOrderInfo?.getOrNull("token");
          if (aliPayInfo == null) {
            showToast("支付宝订单创建失败");
            return;
          }
          debugPrint("aliPayInfo=$aliPayInfo");
          ///打印aliPayOrderInfo的type
          Tobias tobias = Tobias();
          final Map aliPayResult = await tobias.pay(aliPayInfo);
          debugPrint("aliPayResult=$aliPayResult");
          // 判断resultStatus 为9000则代表支付成功
          if (aliPayResult.getOrNull("resultStatus") == "9000") {
            showToast("支付成功");
            emitter(PaySuccessState());
          } else {
            showToast("支付失败");
          }
        }
      });
    } catch (e) {
      if (e is ApiException) {
        showToast(e.message ?? '请求失败,请检查网络连接');
      }
    }
  }

  void dispose() {
    fluwx?.clearSubscribers();
    // 释放资源的逻辑
    debugPrint('BLoC disposed');
  }
}

enum PaymentChannel {

  wechatPay(1, "微信支付"),

  aliPay(2, "支付宝支付");

  const PaymentChannel(this.payChannelType, this.payChannelName);

  final int payChannelType;

  final String payChannelName;
}