withdraw_page.dart 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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(MyCookie().userBean.forbidWithdraw){
  344. showSimpleDialog('你已经被冻结提现,请联系群主或客服。', context, (){
  345. Navigator.pop(context);
  346. });
  347. return;
  348. }
  349. if (withdrawalStatus == 0) {
  350. withdrawalStatus = 1;
  351. withdraw();
  352. } else {}
  353. },
  354. behavior: HitTestBehavior.translucent,
  355. child: Container(
  356. decoration: BoxDecoration(
  357. color: withdrawalStatus == 0
  358. ? MyColors.cFF4233
  359. : MyColors.cEFEFEF,
  360. borderRadius: BorderRadius.circular(20)),
  361. child: MyViews().myText('提现', Colors.white, 14),
  362. alignment: Alignment.center,
  363. height: 40,
  364. margin: EdgeInsets.only(top: 20, bottom: 15),
  365. ),
  366. ),
  367. Container(
  368. margin: EdgeInsets.only(bottom: 8),
  369. child: RichText(
  370. text: TextSpan(
  371. text: '您的提现手续费为:',
  372. style: TextStyle(
  373. color: MyColors.c999999, fontSize: 14),
  374. children: [
  375. TextSpan(
  376. text:
  377. '${NumUtil.multiply(percentFee, 100)}%${extraFee == 0 ? '' : '+$extraFee'}',
  378. style: TextStyle(
  379. color: MyColors.cE2A62D,
  380. fontSize: 14),
  381. ),
  382. // TextSpan(
  383. // text: '元',
  384. // style: TextStyle(
  385. // color: MyColors.c999999,
  386. // fontSize: 14),
  387. // ),
  388. ]),
  389. ),
  390. ),
  391. Visibility(
  392. visible: maxPerHand != 0,
  393. child: Container(
  394. margin: EdgeInsets.only(bottom: 8),
  395. child: RichText(
  396. text: TextSpan(
  397. text: '单笔最高限额:',
  398. style: TextStyle(
  399. color: MyColors.c999999, fontSize: 14),
  400. children: [
  401. TextSpan(
  402. text: '$maxPerHand',
  403. style: TextStyle(
  404. color: MyColors.cE2A62D,
  405. fontSize: 14),
  406. ),
  407. TextSpan(
  408. text: '元',
  409. style: TextStyle(
  410. color: MyColors.c999999,
  411. fontSize: 14),
  412. ),
  413. ]),
  414. ),
  415. ),
  416. ),
  417. Visibility(
  418. visible: minPerHand != 0,
  419. child: Container(
  420. margin: EdgeInsets.only(bottom: 8),
  421. child: RichText(
  422. text: TextSpan(
  423. text: '单笔最低限额:',
  424. style: TextStyle(
  425. color: MyColors.c999999, fontSize: 14),
  426. children: [
  427. TextSpan(
  428. text: '$minPerHand',
  429. style: TextStyle(
  430. color: MyColors.cE2A62D,
  431. fontSize: 14),
  432. ),
  433. TextSpan(
  434. text: '元',
  435. style: TextStyle(
  436. color: MyColors.c999999,
  437. fontSize: 14),
  438. ),
  439. ]),
  440. ),
  441. ),
  442. ),
  443. Visibility(
  444. visible: threshold != 0,
  445. child: RichText(
  446. text: TextSpan(
  447. text: '当日免手续费提现额度:',
  448. style: TextStyle(
  449. color: MyColors.c999999, fontSize: 14),
  450. children: [
  451. TextSpan(
  452. text: '$threshold',
  453. style: TextStyle(
  454. color: MyColors.cE2A62D,
  455. fontSize: 14),
  456. ),
  457. TextSpan(
  458. text: '元',
  459. style: TextStyle(
  460. color: MyColors.c999999,
  461. fontSize: 14),
  462. ),
  463. ]),
  464. ),
  465. ),
  466. ],
  467. crossAxisAlignment: CrossAxisAlignment.start,
  468. ),
  469. )
  470. ],
  471. ),
  472. ),
  473. ),
  474. ],
  475. ),
  476. ),
  477. );
  478. }
  479. void withdraw() {
  480. try {
  481. double amount = double.parse(_controller.text.toString());
  482. if (amount <= MyCookie().userBean.balance && amount >= minPerHand) {
  483. var j = {
  484. 'user_uid': MyCookie().getUID(),
  485. 'way':withdrawalPath,
  486. 'amount': amount
  487. };
  488. if(withdrawalPath==2){
  489. j['wx_openid'] = MyCookie().userBean.wxOpenid;
  490. }
  491. print(j.toString());
  492. MyDio().post('/pay/withdraw',j , (response, hasError) {
  493. if (!hasError) {
  494. showToast('提现成功');
  495. withdrawalStatus = 2;
  496. queryPersonalInformation();
  497. } else {
  498. setState(() {
  499. withdrawalStatus = 0;
  500. });
  501. }
  502. }, (error) {
  503. setState(() {
  504. withdrawalStatus = 0;
  505. });
  506. });
  507. } else if (amount > MyCookie().userBean.balance) {
  508. setState(() {
  509. withdrawalStatus = 0;
  510. });
  511. showSimpleDialog('您的余额不足。', context, () {
  512. Navigator.pop(context);
  513. });
  514. } else {
  515. setState(() {
  516. withdrawalStatus = 0;
  517. });
  518. showSimpleDialog('提现失败:提现金额不能低于$minPerHand元。', context, () {
  519. Navigator.pop(context);
  520. });
  521. }
  522. } catch (e) {
  523. setState(() {
  524. withdrawalStatus = 0;
  525. EasyLoading.dismiss();
  526. });
  527. showSimpleDialog('输入内容有误,请重新输入', context, () {
  528. Navigator.pop(context);
  529. });
  530. }
  531. }
  532. void queryPersonalInformation() {
  533. MyDio().query({
  534. "key": "user",
  535. "filters": {
  536. "conditions": ["uid == ${MyCookie().getUID()}"]
  537. },
  538. "dims": userDims,
  539. "paging": [1, 20]
  540. }, (response, hasError) {
  541. if (!hasError) {
  542. UserBeanEntity entity =
  543. UserBeanEntity().fromJson(json.decode(response.data.toString()));
  544. MyCookie().userBean = entity.data.data[0];
  545. EventBus().emit('userChange');
  546. setState(() {});
  547. if (withdrawalStatus == 2) {
  548. Navigator.pop(context);
  549. }
  550. }
  551. }, (error) {});
  552. }
  553. void queryWithdrawalInstructions() {
  554. MyDio().query({
  555. "key": "withdraw_pricing",
  556. "filters": {},
  557. "dims": withdrawPricingDims,
  558. "paging": [1, 20]
  559. }, (response, hasError) {
  560. if (!hasError) {
  561. WithdrawPricingBeanEntity entity = WithdrawPricingBeanEntity()
  562. .fromJson(json.decode(response.data.toString()));
  563. if (entity.data.data.isNotEmpty) {
  564. percentFee = entity.data.data[0].percentFee;
  565. extraFee = entity.data.data[0].extraFee;
  566. threshold = entity.data.data[0].threshold;
  567. maxPerHand = entity.data.data[0].maxPerHand;
  568. minPerHand = entity.data.data[0].minPerHand;
  569. }
  570. }
  571. setState(() {});
  572. }, (error) {});
  573. }
  574. showH(){
  575. try{
  576. double amount = double.parse(_controller.text.toString());
  577. if(amount>=minPerHand){
  578. handlingFee = double.parse((double.parse(_controller.text.toString())*percentFee*100).toStringAsFixed(0))/100+extraFee;
  579. setState(() {
  580. showHandlingFee = true;
  581. });
  582. }else{
  583. setState(() {
  584. showHandlingFee = false;
  585. });
  586. }
  587. }catch(e){
  588. setState(() {
  589. showHandlingFee = false;
  590. });
  591. }
  592. }
  593. }
  594. class MoneyTextInputFormatter extends TextInputFormatter{
  595. @override
  596. TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
  597. // TODO: implement formatEditUpdate
  598. String newvalueText=newValue.text;
  599. if(newvalueText=="."){
  600. //第一个数为.
  601. newvalueText="0.";
  602. } else if(newvalueText.contains(".")){
  603. if(newvalueText.lastIndexOf(".")!=newvalueText.indexOf(".")){
  604. //输入了2个小数点
  605. newvalueText= newvalueText.substring(0,newvalueText.lastIndexOf('.'));
  606. }else if(newvalueText.length-1-newvalueText.indexOf(".")>2){
  607. //输入了1个小数点 小数点后两位
  608. newvalueText=newvalueText.substring(0,newvalueText.indexOf(".")+3);
  609. }
  610. }
  611. return TextEditingValue(
  612. text: newvalueText,
  613. selection: new TextSelection.collapsed(offset: newvalueText.length),
  614. );
  615. }
  616. }