withdraw_page.dart 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. import 'dart:convert';
  2. import 'package:bbyyy/beans/pay_way_bean_entity.dart';
  3. import 'package:bbyyy/beans/user_bean_entity.dart';
  4. import 'package:bbyyy/beans/withdraw_pricing_bean_entity.dart';
  5. import 'package:bbyyy/https/MyDio.dart';
  6. import 'package:bbyyy/my_tools/dims.dart';
  7. import 'package:bbyyy/my_tools/easy_loading/easy_loading.dart';
  8. import 'package:bbyyy/my_tools/event_bus.dart';
  9. import 'package:bbyyy/my_tools/my_apis.dart';
  10. import 'package:bbyyy/my_tools/my_colors.dart';
  11. import 'package:bbyyy/my_tools/my_cookie.dart';
  12. import 'package:bbyyy/my_tools/my_tools.dart';
  13. import 'package:bbyyy/my_tools/my_views.dart';
  14. import 'package:bbyyy/paegs/mine_page/bind_alipay_page/bind_alipay_page.dart';
  15. import 'package:bbyyy/pay/pay_tools.dart';
  16. import 'package:flustars/flustars.dart';
  17. import 'package:flutter/cupertino.dart';
  18. import 'package:flutter/gestures.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:flutter/services.dart';
  21. class WithdrawPage extends StatefulWidget {
  22. @override
  23. _WithdrawPageState createState() => _WithdrawPageState();
  24. }
  25. class _WithdrawPageState extends State<WithdrawPage> {
  26. TextEditingController _controller = TextEditingController();
  27. int withdrawalStatus = 1; //0--未提现 1--提现中 2--提现完成
  28. double percentFee = 0.0;
  29. double extraFee = 0.0;
  30. double threshold = 0.0;
  31. double maxPerHand = 0.0;
  32. double minPerHand = 0.0;
  33. int withdrawalPath = -1; // 1---支付宝 2---微信
  34. List<PayWayBeanData> payWays;
  35. bool showAlipay = false;
  36. bool showWeChat = false;
  37. bool showHandlingFee = false;
  38. double handlingFee = 0.0;
  39. @override
  40. void initState() {
  41. // TODO: implement initState
  42. super.initState();
  43. queryPersonalInformation();
  44. queryWithdrawalInstructions();
  45. Future.delayed(Duration.zero, () {
  46. checkPaymentMethod((response, hasError) {
  47. if (!hasError) {
  48. PayWayBeanEntity entity =
  49. PayWayBeanEntity().fromJson(json.decode(response.toString()));
  50. payWays = entity.data;
  51. showWeChat =
  52. payWays[payWays.indexWhere((element) => element.way == 2)]
  53. .withdraw;
  54. showAlipay =
  55. payWays[payWays.indexWhere((element) => element.way == 1)]
  56. .withdraw;
  57. if (MyCookie().userBean.wxOpenid.isNotEmpty &&
  58. payWays[payWays.indexWhere((element) => element.way == 2)]
  59. .withdraw) {
  60. withdrawalPath = 2;
  61. } else if (MyCookie().userBean.aliPayAccount.isNotEmpty &&
  62. payWays[payWays.indexWhere((element) => element.way == 1)]
  63. .withdraw) {
  64. withdrawalPath = 1;
  65. }
  66. setState(() {});
  67. }
  68. }, (e) {});
  69. });
  70. }
  71. @override
  72. Widget build(BuildContext context) {
  73. return GestureDetector(
  74. onTap: () {
  75. MyTools().hideKeyboard(context);
  76. },
  77. behavior: HitTestBehavior.translucent,
  78. child: Scaffold(
  79. backgroundColor: MyColors.cF7F7F7,
  80. body: Column(
  81. children: [
  82. MyViews().myAppBar('申请提现', context, [
  83. GestureDetector(
  84. onTap: () {
  85. MyTools().toPage(context, BindAlipayPage(), (then) {
  86. setState(() {});
  87. });
  88. },
  89. behavior: HitTestBehavior.translucent,
  90. child: Container(
  91. padding: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
  92. child: Text(
  93. '修改绑定',
  94. style: TextStyle(color: MyColors.c333333, fontSize: 16),
  95. ),
  96. ),
  97. ),
  98. ]),
  99. Expanded(
  100. child: SingleChildScrollView(
  101. child: Column(
  102. children: [
  103. if (showAlipay)
  104. GestureDetector(
  105. onTap: () {
  106. if (!payWays[payWays
  107. .indexWhere((element) => element.way == 1)]
  108. .withdraw) {
  109. showToast('支付宝提现暂时维护中');
  110. return;
  111. }
  112. if (MyCookie().userBean.aliPayAccount.isEmpty) {
  113. showToast('未绑定支付宝');
  114. } else {
  115. setState(() {
  116. withdrawalPath = 1;
  117. });
  118. }
  119. },
  120. behavior: HitTestBehavior.translucent,
  121. child: Container(
  122. margin: EdgeInsets.fromLTRB(17, 24, 17, 0),
  123. child: Row(
  124. children: [
  125. Container(
  126. decoration: BoxDecoration(
  127. color: withdrawalPath == 1
  128. ? MyColors.cFF4233
  129. : MyColors.cD0D0D0,
  130. borderRadius: BorderRadius.circular(9)),
  131. height: 18,
  132. width: 18,
  133. child: Icon(
  134. Icons.check,
  135. color: Colors.white,
  136. size: 14,
  137. ),
  138. alignment: Alignment.center,
  139. margin: EdgeInsets.only(right: 10),
  140. ),
  141. MyViews().myText(
  142. '提现到支付宝:${MyCookie().userBean.aliPayAccount.isEmpty ? '未绑定支付宝' : MyCookie().userBean.aliPayAccount}',
  143. MyColors.c666666,
  144. 15),
  145. ],
  146. ),
  147. ),
  148. ),
  149. if (showWeChat)
  150. GestureDetector(
  151. onTap: () {
  152. // if (!payWays[payWays
  153. // .indexWhere((element) => element.way == 2)]
  154. // .withdraw) {
  155. // showToast('微信提现暂时维护中');
  156. // return;
  157. // }
  158. if (MyCookie().userBean.wxOpenid.isEmpty) {
  159. showToast('未绑定微信');
  160. } else {
  161. setState(() {
  162. withdrawalPath = 2;
  163. });
  164. }
  165. },
  166. behavior: HitTestBehavior.translucent,
  167. child: Container(
  168. margin: EdgeInsets.fromLTRB(17, 24, 17, 0),
  169. child: Row(
  170. children: [
  171. Container(
  172. decoration: BoxDecoration(
  173. color: withdrawalPath == 2
  174. ? MyColors.cFF4233
  175. : MyColors.cD0D0D0,
  176. borderRadius: BorderRadius.circular(9)),
  177. height: 18,
  178. width: 18,
  179. child: Icon(
  180. Icons.check,
  181. color: Colors.white,
  182. size: 14,
  183. ),
  184. alignment: Alignment.center,
  185. margin: EdgeInsets.only(right: 10),
  186. ),
  187. MyViews().myText('提现到微信:', MyColors.c666666, 15),
  188. MyCookie().userBean.wxOpenid.isEmpty
  189. ? MyViews()
  190. .myText('未绑定微信', MyColors.c666666, 15)
  191. : Row(
  192. children: [
  193. Container(
  194. margin: EdgeInsets.only(right: 10),
  195. child: ClipRRect(
  196. borderRadius:
  197. BorderRadius.circular(12),
  198. child: MyViews().netImg(
  199. MyCookie().userBean.wxPicture,
  200. 24,
  201. 24),
  202. ),
  203. ),
  204. MyViews().myText(
  205. MyCookie().userBean.wxName,
  206. MyColors.c666666,
  207. 15)
  208. ],
  209. )
  210. ],
  211. ),
  212. ),
  213. ),
  214. Container(
  215. decoration: BoxDecoration(
  216. color: Colors.white,
  217. borderRadius: BorderRadius.circular(4),
  218. ),
  219. margin:
  220. EdgeInsets.symmetric(horizontal: 17, vertical: 14),
  221. padding:
  222. EdgeInsets.symmetric(horizontal: 20, vertical: 15),
  223. child: Column(
  224. children: [
  225. MyViews().myText('提现金额', MyColors.c333333, 16),
  226. Container(
  227. margin: EdgeInsets.only(top: 15),
  228. child: Row(
  229. children: [
  230. Text(
  231. '¥',
  232. style: TextStyle(
  233. color: MyColors.c333333, fontSize: 30),
  234. ),
  235. Expanded(
  236. child: TextField(
  237. inputFormatters: [
  238. FilteringTextInputFormatter.allow(
  239. RegExp("[0-9.]")),
  240. MoneyTextInputFormatter()
  241. ],
  242. controller: _controller,
  243. cursorColor: MyColors.cFF4233,
  244. cursorWidth: 1.0,
  245. decoration: InputDecoration(
  246. border: InputBorder.none,
  247. disabledBorder: InputBorder.none,
  248. enabledBorder: InputBorder.none,
  249. focusedBorder: InputBorder.none,
  250. hintText: '请输入金额',
  251. hintStyle: TextStyle(
  252. color: MyColors.c999999,
  253. fontSize: 16),
  254. isDense: true,
  255. contentPadding:
  256. const EdgeInsets.fromLTRB(
  257. 14, 4.5, 8, 4.5)),
  258. maxLines: 1,
  259. style: TextStyle(
  260. color: MyColors.c333333,
  261. fontSize: 30,
  262. fontWeight: FontWeight.bold,
  263. height: 1.3,
  264. letterSpacing: 0.2),
  265. keyboardType: TextInputType.number,
  266. onChanged: (t) {
  267. try {
  268. showH();
  269. double amount = double.parse(t);
  270. if (amount > 0) {
  271. withdrawalStatus = 0;
  272. setState(() {});
  273. }
  274. } catch (e) {
  275. withdrawalStatus = 1;
  276. }
  277. setState(() {});
  278. },
  279. ),
  280. )
  281. ],
  282. ),
  283. ),
  284. Container(
  285. margin: EdgeInsets.only(top: 4, bottom: 15),
  286. color: MyColors.cE7E7E7,
  287. height: 0.5,
  288. ),
  289. RichText(
  290. text: TextSpan(
  291. text: '当前零钱余额',
  292. style: TextStyle(
  293. color: MyColors.c999999, fontSize: 15),
  294. children: [
  295. TextSpan(
  296. text: '${MyCookie().userBean.balance.toStringAsFixed(2)}',
  297. style: TextStyle(
  298. color: MyColors.cFF4233, fontSize: 15),
  299. ),
  300. TextSpan(
  301. text: '元,',
  302. style: TextStyle(
  303. color: MyColors.c999999, fontSize: 15),
  304. ),
  305. TextSpan(
  306. text: '全部提现',
  307. style: TextStyle(
  308. color: MyColors.cFF4233,
  309. fontSize: 15),
  310. recognizer: TapGestureRecognizer()
  311. ..onTap = () {
  312. _controller.text = MyCookie()
  313. .userBean
  314. .balance
  315. .toString();
  316. showH();
  317. setState(() {
  318. withdrawalStatus = 0;
  319. });
  320. }),
  321. ]),
  322. ),
  323. if (showHandlingFee)
  324. RichText(
  325. text: TextSpan(
  326. text: '手续费',
  327. style: TextStyle(
  328. color: MyColors.c999999, fontSize: 15),
  329. children: [
  330. TextSpan(
  331. text: '$handlingFee',
  332. style: TextStyle(
  333. color: MyColors.cFF4233,
  334. fontSize: 15),
  335. ),
  336. ]),
  337. ),
  338. if (showHandlingFee)
  339. RichText(
  340. text: TextSpan(
  341. text: '实际到账',
  342. style: TextStyle(
  343. color: MyColors.c999999, fontSize: 15),
  344. children: [
  345. TextSpan(
  346. text:
  347. '${double.parse(_controller.text.toString()) - handlingFee}',
  348. style: TextStyle(
  349. color: MyColors.cFF4233,
  350. fontSize: 15),
  351. ),
  352. ]),
  353. ),
  354. GestureDetector(
  355. onTap: () {
  356. if (withdrawalPath == -1) {
  357. showToast('请选择提现方式');
  358. return;
  359. }
  360. if (MyCookie().userBean.forbidWithdraw) {
  361. showSimpleDialog('你已经被冻结提现,请联系群主或客服。', context,
  362. () {
  363. Navigator.pop(context);
  364. });
  365. return;
  366. }
  367. if (withdrawalStatus == 0) {
  368. withdrawalStatus = 1;
  369. withdraw();
  370. } else {}
  371. },
  372. behavior: HitTestBehavior.translucent,
  373. child: Container(
  374. decoration: BoxDecoration(
  375. color: withdrawalStatus == 0
  376. ? MyColors.cFF4233
  377. : MyColors.cEFEFEF,
  378. borderRadius: BorderRadius.circular(20)),
  379. child: MyViews().myText('提现', Colors.white, 14),
  380. alignment: Alignment.center,
  381. height: 40,
  382. margin: EdgeInsets.only(top: 20, bottom: 15),
  383. ),
  384. ),
  385. Container(
  386. margin: EdgeInsets.only(bottom: 8),
  387. child: RichText(
  388. text: TextSpan(
  389. text: '您的提现手续费为:',
  390. style: TextStyle(
  391. color: MyColors.c999999, fontSize: 14),
  392. children: [
  393. TextSpan(
  394. text:
  395. '${NumUtil.multiply(percentFee, 100)}%${extraFee == 0 ? '' : '+$extraFee'}',
  396. style: TextStyle(
  397. color: MyColors.cE2A62D,
  398. fontSize: 14),
  399. ),
  400. // TextSpan(
  401. // text: '元',
  402. // style: TextStyle(
  403. // color: MyColors.c999999,
  404. // fontSize: 14),
  405. // ),
  406. ]),
  407. ),
  408. ),
  409. Visibility(
  410. visible: maxPerHand != 0,
  411. child: Container(
  412. margin: EdgeInsets.only(bottom: 8),
  413. child: RichText(
  414. text: TextSpan(
  415. text: '单笔最高限额:',
  416. style: TextStyle(
  417. color: MyColors.c999999, fontSize: 14),
  418. children: [
  419. TextSpan(
  420. text: '$maxPerHand',
  421. style: TextStyle(
  422. color: MyColors.cE2A62D,
  423. fontSize: 14),
  424. ),
  425. TextSpan(
  426. text: '元',
  427. style: TextStyle(
  428. color: MyColors.c999999,
  429. fontSize: 14),
  430. ),
  431. ]),
  432. ),
  433. ),
  434. ),
  435. Visibility(
  436. visible: minPerHand != 0,
  437. child: Container(
  438. margin: EdgeInsets.only(bottom: 8),
  439. child: RichText(
  440. text: TextSpan(
  441. text: '单笔最低限额:',
  442. style: TextStyle(
  443. color: MyColors.c999999, fontSize: 14),
  444. children: [
  445. TextSpan(
  446. text: '$minPerHand',
  447. style: TextStyle(
  448. color: MyColors.cE2A62D,
  449. fontSize: 14),
  450. ),
  451. TextSpan(
  452. text: '元',
  453. style: TextStyle(
  454. color: MyColors.c999999,
  455. fontSize: 14),
  456. ),
  457. ]),
  458. ),
  459. ),
  460. ),
  461. Visibility(
  462. visible: threshold != 0,
  463. child: RichText(
  464. text: TextSpan(
  465. text: '当日免手续费提现额度:',
  466. style: TextStyle(
  467. color: MyColors.c999999, fontSize: 14),
  468. children: [
  469. TextSpan(
  470. text: '$threshold',
  471. style: TextStyle(
  472. color: MyColors.cE2A62D,
  473. fontSize: 14),
  474. ),
  475. TextSpan(
  476. text: '元',
  477. style: TextStyle(
  478. color: MyColors.c999999,
  479. fontSize: 14),
  480. ),
  481. ]),
  482. ),
  483. ),
  484. ],
  485. crossAxisAlignment: CrossAxisAlignment.start,
  486. ),
  487. )
  488. ],
  489. ),
  490. ),
  491. ),
  492. ],
  493. ),
  494. ),
  495. );
  496. }
  497. void withdraw() {
  498. try {
  499. double amount = double.parse(_controller.text.toString());
  500. if (amount <= MyCookie().userBean.balance && amount >= minPerHand) {
  501. var j = {
  502. 'user_uid': MyCookie().getUID(),
  503. 'way': withdrawalPath,
  504. 'amount': amount
  505. };
  506. if (withdrawalPath == 2) {
  507. j['wx_openid'] = MyCookie().userBean.wxOpenid;
  508. }
  509. print(j.toString());
  510. MyDio().post(MyApis.getApi('withdraw'), j, (response, hasError) {
  511. if (!hasError) {
  512. showToast('提现成功');
  513. withdrawalStatus = 2;
  514. queryPersonalInformation();
  515. } else {
  516. setState(() {
  517. withdrawalStatus = 0;
  518. });
  519. }
  520. }, (error) {
  521. setState(() {
  522. withdrawalStatus = 0;
  523. });
  524. });
  525. } else if (amount > MyCookie().userBean.balance) {
  526. setState(() {
  527. withdrawalStatus = 0;
  528. });
  529. showSimpleDialog('您的余额不足。', context, () {
  530. Navigator.pop(context);
  531. });
  532. } else {
  533. setState(() {
  534. withdrawalStatus = 0;
  535. });
  536. showSimpleDialog('提现失败:提现金额不能低于$minPerHand元。', context, () {
  537. Navigator.pop(context);
  538. });
  539. }
  540. } catch (e) {
  541. setState(() {
  542. withdrawalStatus = 0;
  543. EasyLoading.dismiss();
  544. });
  545. showSimpleDialog('输入内容有误,请重新输入', context, () {
  546. Navigator.pop(context);
  547. });
  548. }
  549. }
  550. void queryPersonalInformation() {
  551. MyDio().query({
  552. "key": "user",
  553. "filters": {
  554. "conditions": ["uid == ${MyCookie().getUID()}"]
  555. },
  556. "dims": userDims,
  557. "paging": [1, 20]
  558. }, (response, hasError) {
  559. if (!hasError) {
  560. UserBeanEntity entity =
  561. UserBeanEntity().fromJson(json.decode(response.data.toString()));
  562. MyCookie().userBean = entity.data.data[0];
  563. EventBus().emit('userChange');
  564. setState(() {});
  565. if (withdrawalStatus == 2) {
  566. Navigator.pop(context);
  567. }
  568. }
  569. }, (error) {});
  570. }
  571. void queryWithdrawalInstructions() {
  572. MyDio().query({
  573. "key": "withdraw_pricing",
  574. "filters": {},
  575. "dims": withdrawPricingDims,
  576. "paging": [1, 20]
  577. }, (response, hasError) {
  578. if (!hasError) {
  579. WithdrawPricingBeanEntity entity = WithdrawPricingBeanEntity()
  580. .fromJson(json.decode(response.data.toString()));
  581. if (entity.data.data.isNotEmpty) {
  582. percentFee = entity.data.data[0].percentFee;
  583. extraFee = entity.data.data[0].extraFee;
  584. threshold = entity.data.data[0].threshold;
  585. maxPerHand = entity.data.data[0].maxPerHand;
  586. minPerHand = entity.data.data[0].minPerHand;
  587. }
  588. }
  589. setState(() {});
  590. }, (error) {});
  591. }
  592. showH() {
  593. try {
  594. double amount = double.parse(_controller.text.toString());
  595. if (amount >= minPerHand) {
  596. handlingFee = double.parse((double.parse(_controller.text.toString()) *
  597. percentFee *
  598. 100)
  599. .toStringAsFixed(0)) /
  600. 100 +
  601. extraFee;
  602. setState(() {
  603. showHandlingFee = true;
  604. });
  605. } else {
  606. setState(() {
  607. showHandlingFee = false;
  608. });
  609. }
  610. } catch (e) {
  611. setState(() {
  612. showHandlingFee = false;
  613. });
  614. }
  615. }
  616. }
  617. class MoneyTextInputFormatter extends TextInputFormatter {
  618. @override
  619. TextEditingValue formatEditUpdate(
  620. TextEditingValue oldValue, TextEditingValue newValue) {
  621. // TODO: implement formatEditUpdate
  622. String newvalueText = newValue.text;
  623. if (newvalueText == ".") {
  624. //第一个数为.
  625. newvalueText = "0.";
  626. } else if (newvalueText.contains(".")) {
  627. if (newvalueText.lastIndexOf(".") != newvalueText.indexOf(".")) {
  628. //输入了2个小数点
  629. newvalueText = newvalueText.substring(0, newvalueText.lastIndexOf('.'));
  630. } else if (newvalueText.length - 1 - newvalueText.indexOf(".") > 2) {
  631. //输入了1个小数点 小数点后两位
  632. newvalueText = newvalueText.substring(0, newvalueText.indexOf(".") + 3);
  633. }
  634. }
  635. return TextEditingValue(
  636. text: newvalueText,
  637. selection: new TextSelection.collapsed(offset: newvalueText.length),
  638. );
  639. }
  640. }