Hibok
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

867 Zeilen
29 KiB

  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'package:cached_network_image/cached_network_image.dart';
  4. import 'package:chat/data/UserData.dart';
  5. import 'package:chat/data/WebData.dart';
  6. import 'package:chat/data/constants.dart';
  7. import 'package:chat/data/conversation.dart';
  8. import 'package:chat/generated/i18n.dart';
  9. import 'package:chat/home/BindBank.dart';
  10. import 'package:chat/home/InfoList.dart';
  11. import 'package:chat/home/ProfilePage.dart';
  12. import 'package:chat/models/money_change.dart';
  13. import 'package:chat/utils/ChargeMoney.dart';
  14. import 'package:chat/utils/CustomUI.dart';
  15. import 'package:chat/utils/HttpUtil.dart';
  16. import 'package:chat/utils/MessageMgr.dart';
  17. import 'package:chat/utils/TokenMgr.dart';
  18. import 'package:chat/utils/app_navigator.dart';
  19. import 'package:chat/utils/screen.dart';
  20. import 'package:dio/dio.dart';
  21. import 'package:flutter/material.dart';
  22. import 'package:flutter/services.dart';
  23. import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
  24. import 'package:flutter_screenutil/flutter_screenutil.dart';
  25. import 'package:fluwx_no_pay/fluwx_no_pay.dart' as fluwx;
  26. import 'package:oktoast/oktoast.dart';
  27. import 'package:provider/provider.dart';
  28. class _ConversationItem extends StatelessWidget {
  29. const _ConversationItem(
  30. {Key key,
  31. this.conversation,
  32. this.callback,
  33. this.showRight = true,
  34. this.rightButton,
  35. this.showReturn = false,
  36. this.applyInfo,
  37. this.bgColor,
  38. this.money,
  39. this.title})
  40. : assert(conversation != null),
  41. super(key: key);
  42. final Widget rightButton;
  43. final Conversation conversation;
  44. final callback;
  45. final int money;
  46. final bool showRight;
  47. final title;
  48. final applyInfo;
  49. final bgColor;
  50. final bool showReturn;
  51. @override
  52. Widget build(BuildContext context) {
  53. Widget avatar;
  54. double width = 44.55;
  55. if (conversation.isAvatarFromNet()) {
  56. avatar = ClipRRect(
  57. borderRadius: BorderRadius.circular(10),
  58. child: CachedNetworkImage(
  59. imageUrl: conversation.avatar,
  60. placeholder: (context, url) => Image.asset(
  61. Constants.DefaultHeadImgUrl,
  62. width: width,
  63. height: width,
  64. ),
  65. fit: BoxFit.cover,
  66. width: width,
  67. height: width,
  68. ));
  69. } else {
  70. avatar = ClipRRect(
  71. borderRadius: BorderRadius.circular(10),
  72. child: Container(
  73. width: width,
  74. height: width,
  75. alignment: Alignment.center,
  76. decoration: BoxDecoration(
  77. gradient: this.bgColor,
  78. borderRadius: BorderRadius.all(Radius.circular(50))),
  79. child: Image.asset(
  80. conversation.avatar,
  81. height: 27,
  82. )));
  83. }
  84. return InkWell(
  85. child: Container(
  86. padding:
  87. const EdgeInsets.only(left: 21, top: 9.5, bottom: 9.5, right: 24.5),
  88. decoration: BoxDecoration(
  89. color: Color(AppColors.ConversationItemBgColor),
  90. border: Border(
  91. bottom: BorderSide(
  92. color: AppColors.DividerColor,
  93. width: Constants.DividerWidth))),
  94. child: Row(
  95. crossAxisAlignment: CrossAxisAlignment.center,
  96. children: <Widget>[
  97. avatar,
  98. Container(width: 14.0),
  99. Expanded(
  100. child: Container(
  101. padding: EdgeInsets.only(top: 3),
  102. child: Column(
  103. crossAxisAlignment: CrossAxisAlignment.start,
  104. children: <Widget>[
  105. Container(
  106. child: title == null
  107. ? Text(conversation.title,
  108. textScaleFactor: 1.0,
  109. style: TextStyle(
  110. fontSize: 11,
  111. color: Constants.LightGreyTextColor))
  112. : title),
  113. Container(
  114. padding: EdgeInsets.only(top: 10),
  115. child: Text(conversation.desc,
  116. textScaleFactor: 1.0,
  117. style: TextStyle(
  118. fontSize: 11, color: Constants.LightGreyTextColor)),
  119. )
  120. ],
  121. ),
  122. )),
  123. Container(
  124. height: width,
  125. margin: EdgeInsets.only(left: 10),
  126. child: Column(
  127. crossAxisAlignment: CrossAxisAlignment.end,
  128. mainAxisAlignment: MainAxisAlignment.center,
  129. children: <Widget>[
  130. Text(
  131. '${money > 0 ? '+' : ''}$money${I18n.of(context).mask_coin}',
  132. style: TextStyle(
  133. fontSize: 14,
  134. fontWeight: FontWeight.w500,
  135. color:
  136. money > 0 ? Color(0xFFFE4624) : Color(0xFF5498FF)),
  137. ),
  138. showReturn
  139. ? Padding(
  140. padding: EdgeInsets.only(top: 3),
  141. child: Text(
  142. I18n.of(context).alreay_back,
  143. style: TextStyle(
  144. fontSize: 12,
  145. fontWeight: FontWeight.normal,
  146. color: Constants.BlackTextColor),
  147. ))
  148. : Container()
  149. ],
  150. ),
  151. alignment: Alignment.center,
  152. ),
  153. ],
  154. ),
  155. ),
  156. onTap: () {
  157. callback();
  158. },
  159. );
  160. }
  161. }
  162. class MoneyPageOld extends StatefulWidget {
  163. MoneyPageOld({Key key}) : super(key: key);
  164. MoneyPageOldState createState() => MoneyPageOldState();
  165. }
  166. class MoneyPageOldState extends State<MoneyPageOld>
  167. with SingleTickerProviderStateMixin {
  168. List list = new List(); //列表要展示的数据
  169. ScrollController _scrollController = ScrollController(); //listview的控制器
  170. int _page = 1; //加载的页数
  171. int rows = 20;
  172. bool isLoading = false; //是否正在加载数据
  173. bool isLoadingFish = false;
  174. bool showMore = false;
  175. TabController tabCtrl;
  176. var bindAccount;
  177. messageGetBindBank(data) {
  178. getBinkInfo();
  179. }
  180. @override
  181. void initState() {
  182. super.initState();
  183. print('MoneyPageOld initState');
  184. tabCtrl = TabController(length: 2, vsync: this);
  185. getBinkInfo();
  186. MessageMgr().on('bind_bank', messageGetBindBank);
  187. fluwx.responseFromPayment.listen((data) {
  188. if (data.errCode == 0) {
  189. Navigator.of(context).pop();
  190. setState(() {});
  191. showToast(I18n.of(context).payment_successful);
  192. }
  193. });
  194. getNewData(initList);
  195. _scrollController.addListener(() {
  196. if (_scrollController.position.pixels ==
  197. _scrollController.position.maxScrollExtent) {
  198. setState(() {
  199. showMore = true;
  200. });
  201. _getMore();
  202. }
  203. });
  204. }
  205. void addList(data) {
  206. data == null || data.length == 0 ? _page-- : list.addAll(data);
  207. isLoading = false;
  208. showMore = false;
  209. setState(() {});
  210. }
  211. Future _getMore() async {
  212. if (!isLoading) {
  213. setState(() {
  214. isLoading = true;
  215. });
  216. _page++;
  217. getNewData(addList);
  218. }
  219. }
  220. void changeMoney() async {
  221. if (Provider.of<MoneyChangeProvider>(context).money < 40) {
  222. showToast(I18n.of(context).not_enough);
  223. return;
  224. }
  225. if (bindAccount == null || bindAccount['CId'] == null) {
  226. showToast(I18n.of(context).needCard);
  227. return;
  228. }
  229. if (Platform.isIOS) {
  230. AppNavigator.pushServicePage(context, questionIndex: 1);
  231. return;
  232. }
  233. String money;
  234. var confirm =
  235. CustomUI.buildConfirmBotton(I18n.of(context).determine, () async {
  236. int minMoney = 40;
  237. int maxMoney = 4000;
  238. var m = int.parse(money);
  239. if (m == null || m == 0) {
  240. showToast(I18n.of(context).enter_amount);
  241. return;
  242. }
  243. if (m > Provider.of<MoneyChangeProvider>(context).money) {
  244. showToast(I18n.of(context).not_enough);
  245. return;
  246. }
  247. if (m < minMoney) {
  248. showToast(I18n.of(context)
  249. .little_min
  250. .replaceFirst('/s1', minMoney.toString()));
  251. return;
  252. }
  253. if (m > maxMoney) {
  254. showToast(
  255. I18n.of(context).more_big.replaceFirst('/s1', maxMoney.toString()));
  256. return;
  257. }
  258. var data = {
  259. "userId": UserData().basicInfo.userId,
  260. "cId": bindAccount['CId'],
  261. "amount": m,
  262. };
  263. data['sign'] = TokenMgr().getSign(data);
  264. Response res = await HttpUtil().post('wallet/draw/order', data: data);
  265. Map resData = res.data;
  266. showToast(resData['msg']);
  267. if (resData['code'] == 0) {
  268. Navigator.of(context).pop();
  269. UserData().totalMoney -= m;
  270. Provider.of<MoneyChangeProvider>(context, listen: false).subMoney(m);
  271. MessageMgr().emit('refresh_money');
  272. _onRefresh();
  273. }
  274. });
  275. var tip = Column(
  276. children: <Widget>[
  277. Container(
  278. margin: EdgeInsets.only(top: 20),
  279. child: Text(
  280. I18n.of(context).withdrawal_application,
  281. style: TextStyle(color: Constants.BlackTextColor, fontSize: 16),
  282. ),
  283. ),
  284. Container(
  285. margin: EdgeInsets.only(top: 23, bottom: 25),
  286. decoration: BoxDecoration(
  287. color: Colors.grey[200],
  288. borderRadius: BorderRadius.all(Radius.circular(8))),
  289. child: TextField(
  290. keyboardAppearance: Brightness.light,
  291. textAlign: TextAlign.center,
  292. textInputAction: TextInputAction.search,
  293. style:
  294. TextStyle(textBaseline: TextBaseline.alphabetic, fontSize: 14),
  295. decoration: InputDecoration(
  296. hintText: I18n.of(context).enter_amount,
  297. filled: true,
  298. contentPadding: EdgeInsets.only(top: 10, bottom: 10),
  299. fillColor: Colors.transparent,
  300. border: InputBorder.none,
  301. ),
  302. keyboardType: TextInputType.phone,
  303. maxLines: 1,
  304. inputFormatters: [
  305. WhitelistingTextInputFormatter(RegExp("^([1-9][0-9]*)\$")),
  306. WhitelistingTextInputFormatter.digitsOnly,
  307. LengthLimitingTextInputFormatter(5)
  308. ],
  309. onChanged: (str) {
  310. money = str;
  311. },
  312. ),
  313. )
  314. ],
  315. );
  316. var content = CustomUI.buildConfirmContent(tip, confirm);
  317. CustomUI.buildTip(context, '', content);
  318. }
  319. void getBinkInfo() async {
  320. Map data = {
  321. "userId": UserData().basicInfo.userId,
  322. };
  323. data['sign'] = TokenMgr().getSign(data);
  324. Response res = await HttpUtil().post('wallet/bind/bankInfo',
  325. data: data, failback: () => Navigator.of(context).pop());
  326. Map resData = res.data;
  327. if (resData['code'] == 0) {
  328. bindAccount = resData['data'];
  329. isLoadingFish = true;
  330. setState(() {});
  331. }
  332. }
  333. @override
  334. void dispose() {
  335. tabCtrl.dispose();
  336. MessageMgr().off('bind_bank', messageGetBindBank);
  337. if (_conectionSubscription != null) {
  338. _conectionSubscription.cancel();
  339. _conectionSubscription = null;
  340. }
  341. if (_purchaseUpdatedSubscription != null) {
  342. _purchaseUpdatedSubscription.cancel();
  343. _purchaseUpdatedSubscription = null;
  344. }
  345. if (_purchaseErrorSubscription != null) {
  346. _purchaseErrorSubscription.cancel();
  347. _purchaseErrorSubscription = null;
  348. }
  349. super.dispose();
  350. }
  351. @override
  352. Widget build(BuildContext context) {
  353. Widget content = Scaffold(
  354. resizeToAvoidBottomPadding: false,
  355. appBar: AppBar(
  356. backgroundColor: AppColors.NewAppbarBgColor,
  357. leading: CustomUI.buildCustomLeading(context),
  358. title: Text(
  359. I18n.of(context).wallet,
  360. textScaleFactor: 1.0,
  361. style: TextStyle(color: AppColors.NewAppbarTextColor),
  362. ),
  363. centerTitle: true,
  364. ),
  365. body: SafeArea(child: showCoin()),
  366. );
  367. return CustomUI.buildPageLoading(context, content, !isLoadingFish);
  368. }
  369. Widget _buildBindAccount() {
  370. return InkWell(
  371. onTap: () {
  372. Navigator.of(context).push(
  373. new MaterialPageRoute(
  374. builder: (context) {
  375. return BindBankPage(
  376. isBind: (bindAccount == null || bindAccount == ''),
  377. bankInfo: bindAccount,
  378. );
  379. },
  380. ),
  381. );
  382. },
  383. child: Container(
  384. decoration: BoxDecoration(
  385. color: Colors.white,
  386. border: Border(
  387. top: BorderSide(color: Colors.grey, width: 0.2),
  388. bottom: BorderSide(color: Colors.grey, width: 0.2),
  389. )),
  390. padding: EdgeInsets.only(top: 15, bottom: 15, left: 30, right: 8),
  391. child: Row(
  392. children: <Widget>[
  393. Text(
  394. I18n.of(context).bind_account.replaceFirst('/s1', ''),
  395. textScaleFactor: 1.0,
  396. style: TextStyle(fontWeight: FontWeight.normal),
  397. ),
  398. Expanded(
  399. child: Container(
  400. alignment: Alignment.centerRight,
  401. child: Row(
  402. mainAxisAlignment: MainAxisAlignment.end,
  403. children: <Widget>[
  404. (bindAccount == null || bindAccount == '')
  405. ? Container()
  406. : Text(
  407. bindAccount['Name'],
  408. textScaleFactor: 1.0,
  409. style: TextStyle(),
  410. ),
  411. Icon(
  412. IconData(0xe63c, fontFamily: 'iconfont'),
  413. size: 22.0,
  414. color: Colors.grey,
  415. )
  416. ],
  417. )),
  418. )
  419. ],
  420. ),
  421. ));
  422. }
  423. Widget _buildCard(int money2) {
  424. return Container(
  425. color: Colors.white,
  426. child: Stack(
  427. children: <Widget>[
  428. Container(
  429. margin: EdgeInsets.only(bottom: 2),
  430. color: Colors.white,
  431. width: Screen.width,
  432. child: Image.asset(
  433. 'assets/images/qianbao_bg.png',
  434. fit: BoxFit.fitWidth,
  435. ),
  436. ),
  437. Container(
  438. margin: EdgeInsets.only(top: 20, left: 25, right: 25, bottom: 20),
  439. child: Column(
  440. children: <Widget>[
  441. Padding(
  442. child: Text(
  443. '${I18n.of(context).get_way}${I18n.of(context).coin_use}',
  444. textScaleFactor: 1.0,
  445. style: TextStyle(color: Colors.white, fontSize: 10.5),
  446. ),
  447. padding: EdgeInsets.only(
  448. left: 5,
  449. right: 5,
  450. top: 13,
  451. bottom: Screen.width * 0.05),
  452. ),
  453. Row(
  454. crossAxisAlignment: CrossAxisAlignment.start,
  455. children: <Widget>[
  456. Container(
  457. child: Column(
  458. crossAxisAlignment: CrossAxisAlignment.start,
  459. children: <Widget>[
  460. Container(
  461. alignment: Alignment.centerLeft,
  462. child: Text(
  463. I18n.of(context).coin_total,
  464. textAlign: TextAlign.left,
  465. textScaleFactor: 1.0,
  466. style: TextStyle(
  467. color: Colors.white, fontSize: 15),
  468. ),
  469. padding:
  470. EdgeInsets.only(right: 5, top: 0, left: 22),
  471. ),
  472. Row(
  473. children: <Widget>[
  474. Padding(
  475. child: Container(
  476. child: Text(
  477. UserData().totalMoney.toString(),
  478. textScaleFactor: 1.0,
  479. style: TextStyle(
  480. color: Colors.white, fontSize: 31.5),
  481. ),
  482. ),
  483. padding: EdgeInsets.only(left: 25, right: 5),
  484. ),
  485. ],
  486. )
  487. ],
  488. ),
  489. ),
  490. Platform.isIOS
  491. ? Container()
  492. : Expanded(
  493. child: Container(
  494. child: Column(
  495. crossAxisAlignment: CrossAxisAlignment.start,
  496. children: <Widget>[
  497. InkWell(
  498. onTap: changeMoney,
  499. child: Container(
  500. margin: EdgeInsets.only(
  501. top: 23, right: 5),
  502. width: double.infinity,
  503. child: Row(
  504. mainAxisAlignment:
  505. MainAxisAlignment.end,
  506. children: <Widget>[
  507. Text(
  508. I18n.of(context)
  509. .exchange_cash,
  510. textScaleFactor: 1.0,
  511. style: TextStyle(
  512. color: Colors.white,
  513. fontSize: 14)),
  514. Icon(
  515. IconData(0xe63c,
  516. fontFamily: 'iconfont'),
  517. size: 20.0,
  518. color: Colors.white,
  519. ),
  520. ],
  521. ))),
  522. Container(
  523. padding: EdgeInsets.only(top: 5, right: 10),
  524. alignment: Alignment.centerRight,
  525. child: Consumer<MoneyChangeProvider>(
  526. builder: (context,
  527. MoneyChangeProvider counter,
  528. child) =>
  529. Text(
  530. '${I18n.of(context).can_withdraw} $money2',
  531. textScaleFactor: 1.0,
  532. style: TextStyle(
  533. color: Colors.white, fontSize: 12),
  534. ),
  535. ),
  536. )
  537. ],
  538. ),
  539. ))
  540. ],
  541. ),
  542. ],
  543. ),
  544. ),
  545. Positioned(
  546. bottom: 6,
  547. //left: ScreenUtil().setWidth(20),
  548. child: Platform.isIOS
  549. ? Container()
  550. : Container(
  551. //color: Colors.red,
  552. margin: EdgeInsets.only(left: ScreenUtil().setWidth(20)),
  553. width: Screen.width - ScreenUtil().setWidth(35),
  554. child: Text(
  555. I18n.of(context).warning_text,
  556. style: TextStyle(
  557. fontSize: 11, color: const Color(0xFFFE4624)),
  558. ),
  559. ),
  560. )
  561. ],
  562. ));
  563. }
  564. Widget _buildBottomSheet() {
  565. var blueColor = AppColors.NewAppbarBgColor;
  566. return Container(
  567. height: 50,
  568. decoration: BoxDecoration(
  569. color: Constants.LightGreyBackgroundColor,
  570. border: Border(top: BorderSide(color: Color(0xffeaeaea)))),
  571. child: Row(
  572. mainAxisAlignment: Platform.isIOS
  573. ? MainAxisAlignment.center
  574. : MainAxisAlignment.spaceEvenly,
  575. children: <Widget>[
  576. InkWell(
  577. onTap: () {
  578. ChargeMoney.showChargeSheet(context, () {
  579. setState(() {});
  580. });
  581. },
  582. child: Container(
  583. width: MediaQuery.of(context).size.width / 2,
  584. alignment: Alignment.center,
  585. child: Row(
  586. mainAxisAlignment: MainAxisAlignment.center,
  587. children: <Widget>[
  588. Icon(
  589. IconData(
  590. 0xe642,
  591. fontFamily: 'iconfont',
  592. ),
  593. color: blueColor,
  594. ),
  595. SizedBox(width: 7.5),
  596. Text(
  597. I18n.of(context).recharge,
  598. textScaleFactor: 1.0,
  599. style: TextStyle(color: blueColor),
  600. ),
  601. ],
  602. ))),
  603. Platform.isIOS
  604. ? Container()
  605. : InkWell(
  606. onTap: changeMoney,
  607. child: Container(
  608. width: MediaQuery.of(context).size.width / 2,
  609. alignment: Alignment.center,
  610. child: Row(
  611. mainAxisAlignment: MainAxisAlignment.center,
  612. children: <Widget>[
  613. Icon(
  614. IconData(
  615. 0xe64a,
  616. fontFamily: 'iconfont',
  617. ),
  618. color: blueColor,
  619. ),
  620. SizedBox(width: 7.5),
  621. Text(
  622. Platform.isIOS
  623. ? '咨询客服'
  624. : I18n.of(context).exchange_cash,
  625. textScaleFactor: 1.0,
  626. style: TextStyle(color: blueColor),
  627. ),
  628. ],
  629. )))
  630. ],
  631. ),
  632. );
  633. }
  634. Widget showCoin() {
  635. return Scaffold(
  636. bottomNavigationBar: _buildBottomSheet(),
  637. body: SafeArea(
  638. child: Center(
  639. child: Container(
  640. height: MediaQuery.of(context).size.height,
  641. width: MediaQuery.of(context).size.width,
  642. child: _buildCoinBody(),
  643. ),
  644. )));
  645. }
  646. /*
  647. * 下拉刷新方法,为list重新赋值
  648. */
  649. Future<Null> _onRefresh() async {
  650. _page = 1;
  651. _scrollController.jumpTo(0);
  652. getNewData(initList);
  653. }
  654. void initList(data) {
  655. list.clear();
  656. if (data != null) {
  657. list.addAll(data);
  658. }
  659. isLoadingFish = true;
  660. setState(() {});
  661. }
  662. getNewData(callback) async {
  663. Map data = {
  664. "userId": UserData().basicInfo.userId,
  665. };
  666. data['sign'] = TokenMgr().getSign(data);
  667. data["page"] = _page;
  668. data['rows'] = rows;
  669. data['type'] = 2;
  670. Response res = await HttpUtil().post('message/wallet/message', data: data);
  671. var resData = res.data;
  672. print(resData);
  673. if (resData['code'] == 0) {
  674. callback(resData['data']);
  675. } else {
  676. showToast(resData['msg']);
  677. }
  678. }
  679. bool isAdd(bool isMyself, int type) {
  680. return type == 1 ||
  681. type == 10 ||
  682. type == 11 ||
  683. (!isMyself && type == 3) ||
  684. (!isMyself && type == 4) ||
  685. (!isMyself && type == 7) ||
  686. (!isMyself && type == 8) ||
  687. (!isMyself && type == 9);
  688. }
  689. //钱包通知
  690. Widget _buildMoneyInfo(data) {
  691. bool isMyself = data['UserId'] == UserData().basicInfo.userId;
  692. String imgUrl = data['HeadImg'] == null || data['HeadImg'] == ''
  693. ? UserData().basicInfo.headimgurl
  694. : data['HeadImg'];
  695. return _ConversationItem(
  696. conversation: Conversation(
  697. avatar: imgUrl,
  698. title: '',
  699. desc: WebData().getLoginTime(context, data['CreateTime']),
  700. updateAt: '',
  701. ),
  702. bgColor: Constants.MoneyGradient,
  703. showReturn: data['DetailType'] == 10 ||
  704. data['Status'] == 2 ||
  705. (data['DetailType'] != 9 &&
  706. data['DetailType'] != 6 &&
  707. data['Status'] == 1),
  708. money:
  709. isAdd(isMyself, data['DetailType']) ? data['Value'] : -data['Value'],
  710. title: RichTitle.getRichTitleWidget(data, context, InfoType.Money,
  711. titleStyle: TextStyle(fontSize: 12, color: const Color(0XFF7F7F7F)),
  712. nameStyle: TextStyle(
  713. fontWeight: FontWeight.normal,
  714. fontSize: 13,
  715. color: Constants.BlackTextColor)),
  716. callback: () {
  717. if (data['ChangeUserId'] != 0) {
  718. Navigator.of(context).push(
  719. new MaterialPageRoute(
  720. builder: (context) {
  721. return ProfilePage(
  722. userId: data['UserId'] == UserData().basicInfo.userId
  723. ? data['ChangeUserId']
  724. : data['UserId'],
  725. );
  726. },
  727. ),
  728. );
  729. }
  730. },
  731. );
  732. }
  733. Widget _renderRow(BuildContext context, int index) {
  734. if (list.length == 0) {
  735. return Column(
  736. children: <Widget>[
  737. _buildCard(Provider.of<MoneyChangeProvider>(context).money),
  738. // _buildBindAccount(),
  739. ],
  740. );
  741. }
  742. if (index < list.length) {
  743. var userInfo = list[index];
  744. Widget result = _buildMoneyInfo(userInfo);
  745. if (index == 0) {
  746. result = Column(
  747. children: <Widget>[
  748. _buildCard(Provider.of<MoneyChangeProvider>(context).money),
  749. Platform.isIOS ? Container() : _buildBindAccount(),
  750. Padding(padding: EdgeInsets.only(top: 10), child: result)
  751. ],
  752. );
  753. }
  754. return result;
  755. } else if (showMore) {
  756. _getMoreWidget();
  757. }
  758. return Container();
  759. }
  760. Widget _getMoreWidget() {
  761. return Center(
  762. child: CircularProgressIndicator(
  763. valueColor: AlwaysStoppedAnimation(Constants.BlueTextColor)));
  764. }
  765. Widget _buildCoinBody() {
  766. return RefreshIndicator(
  767. onRefresh: _onRefresh,
  768. child: ListView.builder(
  769. physics: AlwaysScrollableScrollPhysics(),
  770. itemBuilder: _renderRow,
  771. itemCount: list.length + 1,
  772. controller: _scrollController,
  773. ),
  774. );
  775. }
  776. static String currentGoodsId = '';
  777. static StreamSubscription _conectionSubscription,
  778. _purchaseUpdatedSubscription,
  779. _purchaseErrorSubscription;
  780. ///ios 内购初始化
  781. static Future initPayConf(BuildContext context) async {
  782. if (_purchaseErrorSubscription != null) {
  783. return;
  784. }
  785. // prepare
  786. print('initPayConf -------- start: ');
  787. var result = await FlutterInappPurchase.instance.initConnection;
  788. print('initPayConf -------- result: $result');
  789. FlutterInappPurchase.instance.clearTransactionIOS();
  790. _conectionSubscription =
  791. FlutterInappPurchase.connectionUpdated.listen((connected) {
  792. print('connected: $connected');
  793. });
  794. _purchaseUpdatedSubscription =
  795. FlutterInappPurchase.purchaseUpdated.listen((productItem) {
  796. print('支付成功,成功回调 ------ purchase-updated: $productItem');
  797. // showToast('支付成功,成功回调 ------ purchase-updated: $productItem');
  798. if (productItem.transactionReceipt != null &&
  799. productItem.transactionReceipt.isNotEmpty) {
  800. HttpUtil().createOrder(currentGoodsId, productItem.transactionReceipt,
  801. productItem.purchaseToken,
  802. context: context);
  803. showToast(I18n.of(context).payment_successful);
  804. }
  805. Navigator.of(context).pop();
  806. });
  807. _purchaseErrorSubscription =
  808. FlutterInappPurchase.purchaseError.listen((purchaseError) {
  809. // showToast('支付失败回调 -------- purchase-error: $purchaseError');
  810. FlutterInappPurchase.instance.clearTransactionIOS();
  811. Navigator.of(context).pop();
  812. });
  813. }
  814. }