import 'dart:async'; import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:chat/data/UserData.dart'; import 'package:chat/data/WebData.dart'; import 'package:chat/data/constants.dart'; import 'package:chat/data/conversation.dart'; import 'package:chat/generated/i18n.dart'; import 'package:chat/home/BindBank.dart'; import 'package:chat/home/ProfilePage.dart'; import 'package:chat/home/rich_title.dart'; import 'package:chat/models/money_change.dart'; import 'package:chat/utils/ChargeMoney.dart'; import 'package:chat/utils/CustomUI.dart'; import 'package:chat/utils/HttpUtil.dart'; import 'package:chat/utils/MessageMgr.dart'; import 'package:chat/utils/TokenMgr.dart'; import 'package:chat/utils/app_navigator.dart'; import 'package:chat/utils/screen.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx; import 'package:oktoast/oktoast.dart'; import 'package:provider/provider.dart'; class _ConversationItem extends StatelessWidget { const _ConversationItem( {Key key, this.conversation, this.callback, this.showRight = true, this.rightButton, this.showReturn = false, this.applyInfo, this.bgColor, this.money, this.title}) : assert(conversation != null), super(key: key); final Widget rightButton; final Conversation conversation; final callback; final int money; final bool showRight; final title; final applyInfo; final bgColor; final bool showReturn; @override Widget build(BuildContext context) { Widget avatar; double width = 44.55; if (conversation.isAvatarFromNet()) { avatar = ClipRRect( borderRadius: BorderRadius.circular(10), child: CachedNetworkImage( imageUrl: conversation.avatar, placeholder: (context, url) => Image.asset( Constants.DefaultHeadImgUrl, width: width, height: width, ), fit: BoxFit.cover, width: width, height: width, )); } else { avatar = ClipRRect( borderRadius: BorderRadius.circular(10), child: Container( width: width, height: width, alignment: Alignment.center, decoration: BoxDecoration( gradient: this.bgColor, borderRadius: BorderRadius.all(Radius.circular(50))), child: Image.asset( conversation.avatar, height: 27, ))); } return InkWell( child: Container( padding: const EdgeInsets.only(left: 21, top: 9.5, bottom: 9.5, right: 24.5), decoration: BoxDecoration( color: Color(AppColors.ConversationItemBgColor), border: Border( bottom: BorderSide( color: AppColors.DividerColor, width: Constants.DividerWidth))), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ avatar, Container(width: 14.0), Expanded( child: Container( padding: EdgeInsets.only(top: 3), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: title == null ? Text(conversation.title, textScaleFactor: 1.0, style: TextStyle( fontSize: 11, color: Constants.LightGreyTextColor)) : title), Container( padding: EdgeInsets.only(top: 10), child: Text(conversation.desc, textScaleFactor: 1.0, style: TextStyle( fontSize: 11, color: Constants.LightGreyTextColor)), ) ], ), )), Container( height: width, margin: EdgeInsets.only(left: 10), child: Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '${money > 0 ? '+' : ''}$money${I18n.of(context).mask_coin}', textScaleFactor: 1.0, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: money > 0 ? Color(0xFFFE4624) : Color(0xFF5498FF)), ), showReturn ? Padding( padding: EdgeInsets.only(top: 3), child: Text( I18n.of(context).alreay_back, textScaleFactor: 1.0, style: TextStyle( fontSize: 12, fontWeight: FontWeight.normal, color: Constants.BlackTextColor), )) : Container() ], ), alignment: Alignment.center, ), ], ), ), onTap: () { callback(); }, ); } } class MoneyPageOld extends StatefulWidget { MoneyPageOld({Key key}) : super(key: key); MoneyPageOldState createState() => MoneyPageOldState(); } class MoneyPageOldState extends State with SingleTickerProviderStateMixin { List list = new List(); //列表要展示的数据 ScrollController _scrollController = ScrollController(); //listview的控制器 int _page = 1; //加载的页数 int rows = 20; bool isLoading = false; //是否正在加载数据 bool isLoadingFish = false; bool showMore = false; TabController tabCtrl; var bindAccount; messageGetBindBank(data) { getBinkInfo(); } @override void initState() { super.initState(); print('MoneyPageOld initState'); tabCtrl = TabController(length: 2, vsync: this); getBinkInfo(); MessageMgr().on('bind_bank', messageGetBindBank); fluwx.responseFromPayment.listen((data) { if (data.errCode == 0) { Navigator.of(context).pop(); setState(() {}); showToast(I18n.of(context).payment_successful); } }); getNewData(initList); _scrollController.addListener(() { if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) { setState(() { showMore = true; }); _getMore(); } }); } void addList(data) { data == null || data.length == 0 ? _page-- : list.addAll(data); isLoading = false; showMore = false; setState(() {}); } Future _getMore() async { if (!isLoading) { setState(() { isLoading = true; }); _page++; getNewData(addList); } } void changeMoney() async { if (Provider.of(context).money < 40) { showToast(I18n.of(context).not_enough); return; } if (bindAccount == null || bindAccount['CId'] == null) { showToast(I18n.of(context).needCard); return; } if (Platform.isIOS) { AppNavigator.pushServicePage(context, questionIndex: 1); return; } String money; var confirm = CustomUI.buildConfirmBotton(I18n.of(context).determine, () async { int minMoney = 40; int maxMoney = 4000; var m = int.parse(money); if (m == null || m == 0) { showToast(I18n.of(context).enter_amount); return; } if (m > Provider.of(context).money) { showToast(I18n.of(context).not_enough); return; } if (m < minMoney) { showToast(I18n.of(context) .little_min .replaceFirst('/s1', minMoney.toString())); return; } if (m > maxMoney) { showToast( I18n.of(context).more_big.replaceFirst('/s1', maxMoney.toString())); return; } var data = { "userId": UserData().basicInfo.userId, "cId": bindAccount['CId'], "amount": m, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('wallet/draw/order', data: data); Map resData = res.data; showToast(resData['msg']); if (resData['code'] == 0) { Navigator.of(context).pop(); UserData().totalMoney -= m; Provider.of(context, listen: false).subMoney(m); MessageMgr().emit('refresh_money'); _onRefresh(); } }); var tip = Column( children: [ Container( margin: EdgeInsets.only(top: 20), child: Text( I18n.of(context).withdrawal_application, textScaleFactor: 1.0, style: TextStyle(color: Constants.BlackTextColor, fontSize: 16), ), ), Container( margin: EdgeInsets.only(top: 23, bottom: 25), decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.all(Radius.circular(8))), child: TextField( keyboardAppearance: Brightness.light, textAlign: TextAlign.center, textInputAction: TextInputAction.search, style: TextStyle(textBaseline: TextBaseline.alphabetic, fontSize: 14), decoration: InputDecoration( hintText: I18n.of(context).enter_amount, filled: true, contentPadding: EdgeInsets.only(top: 10, bottom: 10), fillColor: Colors.transparent, border: InputBorder.none, ), keyboardType: TextInputType.phone, maxLines: 1, inputFormatters: [ WhitelistingTextInputFormatter(RegExp("^([1-9][0-9]*)\$")), WhitelistingTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(5) ], onChanged: (str) { money = str; }, ), ) ], ); var content = CustomUI.buildConfirmContent(tip, confirm); CustomUI.buildTip(context, '', content); } void getBinkInfo() async { Map data = { "userId": UserData().basicInfo.userId, }; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil().post('wallet/bind/bankInfo', data: data, failback: () => Navigator.of(context).pop()); Map resData = res.data; if (resData['code'] == 0) { bindAccount = resData['data']; isLoadingFish = true; setState(() {}); } } @override void dispose() { tabCtrl.dispose(); MessageMgr().off('bind_bank', messageGetBindBank); if (_conectionSubscription != null) { _conectionSubscription.cancel(); _conectionSubscription = null; } if (_purchaseUpdatedSubscription != null) { _purchaseUpdatedSubscription.cancel(); _purchaseUpdatedSubscription = null; } if (_purchaseErrorSubscription != null) { _purchaseErrorSubscription.cancel(); _purchaseErrorSubscription = null; } super.dispose(); } @override Widget build(BuildContext context) { Widget content = Scaffold( resizeToAvoidBottomPadding: false, appBar: AppBar( backgroundColor: AppColors.NewAppbarBgColor, leading: CustomUI.buildCustomLeading(context), title: Text( I18n.of(context).wallet, textScaleFactor: 1.0, style: TextStyle(color: AppColors.NewAppbarTextColor), ), centerTitle: true, ), body: SafeArea(child: showCoin()), ); return CustomUI.buildPageLoading(context, content, !isLoadingFish); } Widget _buildBindAccount() { return InkWell( onTap: () { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return BindBankPage( isBind: (bindAccount == null || bindAccount == ''), bankInfo: bindAccount, ); }, ), ); }, child: Container( decoration: BoxDecoration( color: Colors.white, border: Border( top: BorderSide(color: Colors.grey, width: 0.2), bottom: BorderSide(color: Colors.grey, width: 0.2), )), padding: EdgeInsets.only(top: 15, bottom: 15, left: 30, right: 8), child: Row( children: [ Text( I18n.of(context).bind_account.replaceFirst('/s1', ''), textScaleFactor: 1.0, style: TextStyle(fontWeight: FontWeight.normal), ), Expanded( child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ (bindAccount == null || bindAccount == '') ? Container() : Text( bindAccount['Name'], textScaleFactor: 1.0, style: TextStyle(), ), Icon( IconData(0xe63c, fontFamily: 'iconfont'), size: 22.0, color: Colors.grey, ) ], )), ) ], ), )); } Widget _buildCard(int money2) { return Container( color: Colors.white, child: Stack( children: [ Container( margin: EdgeInsets.only(bottom: 2), color: Colors.white, width: Screen.width, child: Image.asset( 'assets/images/qianbao_bg.png', fit: BoxFit.fitWidth, ), ), Container( margin: EdgeInsets.only(top: 20, left: 25, right: 25, bottom: 20), child: Column( children: [ Padding( child: Text( '${I18n.of(context).get_way}${I18n.of(context).coin_use}', textScaleFactor: 1.0, style: TextStyle(color: Colors.white, fontSize: 10.5), ), padding: EdgeInsets.only( left: 5, right: 5, top: 13, bottom: Screen.width * 0.05), ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( alignment: Alignment.centerLeft, child: Text( I18n.of(context).coin_total, textAlign: TextAlign.left, textScaleFactor: 1.0, style: TextStyle( color: Colors.white, fontSize: 15), ), padding: EdgeInsets.only(right: 5, top: 0, left: 22), ), Row( children: [ Padding( child: Container( child: Text( UserData().totalMoney.toString(), textScaleFactor: 1.0, style: TextStyle( color: Colors.white, fontSize: 31.5), ), ), padding: EdgeInsets.only(left: 25, right: 5), ), ], ) ], ), ), Platform.isIOS ? Container() : Expanded( child: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ InkWell( onTap: changeMoney, child: Container( margin: EdgeInsets.only( top: 23, right: 5), width: double.infinity, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Text( I18n.of(context) .exchange_cash, textScaleFactor: 1.0, style: TextStyle( color: Colors.white, fontSize: 14)), Icon( IconData(0xe63c, fontFamily: 'iconfont'), size: 20.0, color: Colors.white, ), ], ))), Container( padding: EdgeInsets.only(top: 5, right: 10), alignment: Alignment.centerRight, child: Consumer( builder: (context, MoneyChangeProvider counter, child) => Text( '${I18n.of(context).can_withdraw} $money2', textScaleFactor: 1.0, style: TextStyle( color: Colors.white, fontSize: 12), ), ), ) ], ), )) ], ), ], ), ), Positioned( bottom: 6, //left: ScreenUtil().setWidth(20), child: Platform.isIOS ? Container() : Container( //color: Colors.red, margin: EdgeInsets.only(left: ScreenUtil().setWidth(20)), width: Screen.width - ScreenUtil().setWidth(35), child: Text( I18n.of(context).warning_text, style: TextStyle( fontSize: 11, color: const Color(0xFFFE4624)), ), ), ) ], )); } Widget _buildBottomSheet() { var blueColor = AppColors.NewAppbarBgColor; return Container( height: 50, decoration: BoxDecoration( color: Constants.LightGreyBackgroundColor, border: Border(top: BorderSide(color: Color(0xffeaeaea)))), child: Row( mainAxisAlignment: Platform.isIOS ? MainAxisAlignment.center : MainAxisAlignment.spaceEvenly, children: [ InkWell( onTap: () { ChargeMoney.showChargeSheet(context, () { setState(() {}); }); }, child: Container( width: MediaQuery.of(context).size.width / 2, alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( IconData( 0xe642, fontFamily: 'iconfont', ), color: blueColor, ), SizedBox(width: 7.5), Text( I18n.of(context).recharge, textScaleFactor: 1.0, style: TextStyle(color: blueColor), ), ], ))), Platform.isIOS ? Container() : InkWell( onTap: changeMoney, child: Container( width: MediaQuery.of(context).size.width / 2, alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( IconData( 0xe64a, fontFamily: 'iconfont', ), color: blueColor, ), SizedBox(width: 7.5), Text( Platform.isIOS ? '咨询客服' : I18n.of(context).exchange_cash, textScaleFactor: 1.0, style: TextStyle(color: blueColor), ), ], ))) ], ), ); } Widget showCoin() { return Scaffold( bottomNavigationBar: _buildBottomSheet(), body: SafeArea( child: Center( child: Container( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: _buildCoinBody(), ), ))); } /* * 下拉刷新方法,为list重新赋值 */ Future _onRefresh() async { _page = 1; _scrollController.jumpTo(0); getNewData(initList); } void initList(data) { list.clear(); if (data != null) { list.addAll(data); } isLoadingFish = true; setState(() {}); } getNewData(callback) async { Map data = { "userId": UserData().basicInfo.userId, }; data['sign'] = TokenMgr().getSign(data); data["page"] = _page; data['rows'] = rows; data['type'] = 2; Response res = await HttpUtil().post('message/wallet/message', data: data); var resData = res.data; print(resData); if (resData['code'] == 0) { callback(resData['data']); } else { showToast(resData['msg']); } } bool isAdd(bool isMyself, int type) { return type == 1 || type == 10 || type == 11 || (!isMyself && type == 3) || (!isMyself && type == 4) || (!isMyself && type == 7) || (!isMyself && type == 8) || (!isMyself && type == 9); } //钱包通知 Widget _buildMoneyInfo(data) { bool isMyself = data['UserId'] == UserData().basicInfo.userId; String imgUrl = data['HeadImg'] == null || data['HeadImg'] == '' ? UserData().basicInfo.headimgurl : data['HeadImg']; return _ConversationItem( conversation: Conversation( avatar: imgUrl, title: '', desc: WebData().getLoginTime(context, data['CreateTime']), updateAt: '', ), bgColor: Constants.MoneyGradient, showReturn: data['DetailType'] == 10 || data['Status'] == 2 || (data['DetailType'] != 9 && data['DetailType'] != 6 && data['Status'] == 1), money: isAdd(isMyself, data['DetailType']) ? data['Value'] : -data['Value'], title: RichTitle.getRichTitleWidget(data, context, InfoType.IncomeMoney, titleStyle: TextStyle(fontSize: 12, color: const Color(0XFF7F7F7F)), nameStyle: TextStyle( fontWeight: FontWeight.normal, fontSize: 13, color: Constants.BlackTextColor)), callback: () { if (data['ChangeUserId'] != 0) { Navigator.of(context).push( new MaterialPageRoute( builder: (context) { return ProfilePage( userId: data['UserId'] == UserData().basicInfo.userId ? data['ChangeUserId'] : data['UserId'], ); }, ), ); } }, ); } Widget _renderRow(BuildContext context, int index) { if (list.length == 0) { return Column( children: [ _buildCard(Provider.of(context).money), // _buildBindAccount(), ], ); } if (index < list.length) { var userInfo = list[index]; Widget result = _buildMoneyInfo(userInfo); if (index == 0) { result = Column( children: [ _buildCard(Provider.of(context).money), Platform.isIOS ? Container() : _buildBindAccount(), Padding(padding: EdgeInsets.only(top: 10), child: result) ], ); } return result; } else if (showMore) { _getMoreWidget(); } return Container(); } Widget _getMoreWidget() { return Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Constants.BlueTextColor))); } Widget _buildCoinBody() { return RefreshIndicator( onRefresh: _onRefresh, child: ListView.builder( physics: AlwaysScrollableScrollPhysics(), itemBuilder: _renderRow, itemCount: list.length + 1, controller: _scrollController, ), ); } static String currentGoodsId = ''; static StreamSubscription _conectionSubscription, _purchaseUpdatedSubscription, _purchaseErrorSubscription; ///ios 内购初始化 static Future initPayConf(BuildContext context) async { if (_purchaseErrorSubscription != null) { return; } // prepare print('initPayConf -------- start: '); var result = await FlutterInappPurchase.instance.initConnection; print('initPayConf -------- result: $result'); FlutterInappPurchase.instance.clearTransactionIOS(); _conectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) { print('connected: $connected'); }); _purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) { print('支付成功,成功回调 ------ purchase-updated: $productItem'); // showToast('支付成功,成功回调 ------ purchase-updated: $productItem'); if (productItem.transactionReceipt != null && productItem.transactionReceipt.isNotEmpty) { HttpUtil().createOrder(currentGoodsId, productItem.transactionReceipt, productItem.purchaseToken, context: context); showToast(I18n.of(context).payment_successful); } Navigator.of(context).pop(); }); _purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) { // showToast('支付失败回调 -------- purchase-error: $purchaseError'); FlutterInappPurchase.instance.clearTransactionIOS(); Navigator.of(context).pop(); }); } }