Hibok
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

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