withdraw_page.dart 26 KB

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