order_taking_page.dart 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:url_launcher/url_launcher.dart';
  4. import '../util/api.dart';
  5. import '../util/models.dart';
  6. import '../showDialog.dart';
  7. import '../util/session.dart';
  8. import '../util/util.dart';
  9. class OrderTakingPage extends StatefulWidget {
  10. OrderTakingPage({
  11. Key key
  12. }): super(key: key);
  13. _OrderTakingPageState createState() => _OrderTakingPageState();
  14. }
  15. class _OrderTakingPageState extends State < OrderTakingPage > with AutomaticKeepAliveClientMixin {
  16. ScrollController _scrollController = ScrollController(); //初始化滚动轴监控对象
  17. List < OrderList > orderList = []; //订单列表
  18. bool hasNextPage = true;
  19. List lineList = []; //线路列表
  20. String stationId;
  21. List < bool > checkStatusList = [];
  22. bool showLineStatus = true;
  23. String lineIdStr = '';
  24. String oldLineIdStr = '';
  25. int page = 1;
  26. bool loadMoreOrder = true;
  27. @override
  28. void initState() {
  29. super.initState();
  30. getKey('stationId').then((value) {
  31. stationId = value;
  32. getLine().then((childValue) {
  33. getKey('lineIdStr').then((value) {
  34. if (value != null) {
  35. getOrderList(stationId,value, page).then((resp) {
  36. if (isNotError(context, resp) && this.mounted) {
  37. setState(() {
  38. orderList = OrderListObj.fromJson(resp.data).data.items;
  39. hasNextPage = OrderListObj.fromJson(resp.data).data.hasNextPage;
  40. });
  41. lineIdStr = value;
  42. }
  43. });
  44. } else {
  45. getOrderList(stationId,lineIdStr, page).then((resp) {
  46. if (isNotError(context, resp) && this.mounted) {
  47. setState(() {
  48. orderList = OrderListObj.fromJson(resp.data).data.items;
  49. hasNextPage = OrderListObj.fromJson(resp.data).data.hasNextPage;
  50. });
  51. }
  52. });
  53. }
  54. });
  55. });
  56. });
  57. _scrollController.addListener(() {
  58. if (!showLineStatus) {
  59. setState(() {
  60. showLineStatus = true;
  61. });
  62. switchLine(context);
  63. }
  64. if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
  65. if (hasNextPage && loadMoreOrder) {
  66. loadMoreOrder = false;
  67. page = ++page;
  68. getOrderList(stationId,lineIdStr, page).then((resp) {
  69. if (isNotError(context, resp) && this.mounted) {
  70. OrderListObj tempObj = OrderListObj.fromJson(resp.data);
  71. setState(() {
  72. orderList.addAll(tempObj.data.items);
  73. hasNextPage = tempObj.data.hasNextPage;
  74. });
  75. loadMoreOrder = true;
  76. } else {
  77. loadMoreOrder = true;
  78. }
  79. });
  80. }
  81. }
  82. });
  83. }
  84. Future getLine() async {
  85. setState(() {
  86. lineList.clear();
  87. });
  88. await getAllLine().then((resp) {
  89. if (isNotError(context, resp) && this.mounted) {
  90. setState(() {
  91. checkStatusList = [];
  92. lineList = StationLine.fromJson(resp.data).data;
  93. getKey('lineIdStr').then((value) {
  94. if (value != null) {
  95. for (int i = 0; i < lineList.length; i++) {
  96. if (value.indexOf(lineList[i].id.toString()) != -1) {
  97. checkStatusList.add(true);
  98. } else {
  99. checkStatusList.add(false);
  100. }
  101. if (i < lineList.length - 1) {
  102. lineIdStr += lineList[i].id.toString() + ',';
  103. } else {
  104. lineIdStr += lineList[i].id.toString();
  105. }
  106. }
  107. } else {
  108. for (int i = 0; i < lineList.length; i++) {
  109. checkStatusList.add(true);
  110. if (i < lineList.length - 1) {
  111. lineIdStr += lineList[i].id.toString() + ',';
  112. } else {
  113. lineIdStr += lineList[i].id.toString();
  114. }
  115. }
  116. }
  117. });
  118. });
  119. return lineIdStr;
  120. }
  121. });
  122. }
  123. @override
  124. bool get wantKeepAlive => true;
  125. @override
  126. Widget build(BuildContext context) {
  127. super.build(context);
  128. return Container(
  129. child: Scaffold(
  130. appBar: AppBar(
  131. title: Text('接单', style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(36)), ),
  132. centerTitle: true,
  133. backgroundColor: Color.fromRGBO(64, 98, 254, 1),
  134. actions: < Widget > [
  135. IconButton(icon: Icon(Icons.add_circle_outline),
  136. onPressed: () {
  137. setState(() {
  138. showLineStatus = !showLineStatus;
  139. });
  140. if (!showLineStatus) {
  141. getLine();
  142. } else {
  143. switchLine(context);
  144. }
  145. }, )
  146. ]
  147. ),
  148. body: Stack(
  149. children: < Widget > [
  150. RefreshIndicator(
  151. onRefresh: _onRefresh, //回调方法
  152. child: InkWell(
  153. child: Container(
  154. padding: EdgeInsets.fromLTRB(ScreenUtil.getInstance().setWidth(20), ScreenUtil.getInstance().setWidth(20), ScreenUtil.getInstance().setWidth(20), 0),
  155. decoration: BoxDecoration(
  156. color: Color.fromRGBO(246, 246, 254, 1)
  157. ),
  158. child: ListView.builder(
  159. controller: _scrollController,
  160. physics: AlwaysScrollableScrollPhysics(),
  161. itemCount: orderList.length + 1,
  162. itemBuilder: (BuildContext context, int index) { //itemBuilder实际上就是一个map的循环
  163. if (index < orderList.length) {
  164. return OrderCardContainer(order: orderList[index], index: index, callback: (val) => deleteOrder(val));
  165. }
  166. if (hasNextPage) {
  167. return _getMoreWidget();
  168. } else {
  169. return _noMoreWidegt();
  170. }
  171. },
  172. )
  173. ),
  174. onTap: () {
  175. setState(() {
  176. showLineStatus = true;
  177. });
  178. switchLine(context);
  179. },
  180. ),
  181. ),
  182. Positioned(
  183. top: 0,
  184. right: 0,
  185. child:
  186. Offstage(
  187. offstage: showLineStatus,
  188. child: Container(
  189. width: ScreenUtil.getInstance().setWidth(350),
  190. height: ScreenUtil.getInstance().setHeight(500),
  191. margin: EdgeInsets.fromLTRB(0, 1, 1, 0),
  192. padding: EdgeInsets.fromLTRB(1, 0, 1, 0),
  193. decoration: BoxDecoration(
  194. color: Color.fromRGBO(0, 0, 0, 0.7),
  195. borderRadius: BorderRadius.all(Radius.circular(4.0))
  196. ),
  197. child: lineList.length == 0 ? Center(
  198. child: Container(
  199. width: ScreenUtil.getInstance().setWidth(50),
  200. height: ScreenUtil.getInstance().setHeight(50),
  201. child: CircularProgressIndicator(
  202. )
  203. ),
  204. ) :
  205. ListView.builder(
  206. itemCount: lineList.length,
  207. itemBuilder: (BuildContext context, int index) { //itemBuilder实际上就是一个map的循环
  208. if (index < lineList.length) {
  209. return _lineWidget(lineList[index], index, checkStatusList[index]);
  210. }
  211. },
  212. ),
  213. ),
  214. )
  215. )
  216. ],
  217. )
  218. ),
  219. );
  220. }
  221. Widget _lineWidget(LineObj lineObj, int index, bool checked) {
  222. return InkWell(
  223. child: Container(
  224. height: ScreenUtil.getInstance().setHeight(80),
  225. decoration: BoxDecoration(
  226. border: BorderDirectional(bottom: BorderSide(color: Colors.white, width: 0.1))
  227. ),
  228. child: Row(
  229. children: < Widget > [
  230. Padding(
  231. padding: EdgeInsets.only(right: 10),
  232. child: checked ? Icon(Icons.check, color: Colors.white, ) : Icon(Icons.check, color: Color.fromRGBO(0, 0, 0, 0.0, )),
  233. ),
  234. Expanded(
  235. flex: 1,
  236. child: Center(
  237. child: Text(lineObj.name, style: TextStyle(color: Colors.white))
  238. )
  239. )
  240. ],
  241. ),
  242. ),
  243. onTap: () {
  244. setState(() {
  245. checkStatusList[index] = !checked;
  246. });
  247. },
  248. );
  249. }
  250. Widget _getMoreWidget() {
  251. return Center(
  252. child: Padding(
  253. padding: EdgeInsets.all(10.0),
  254. child: Row(
  255. mainAxisAlignment: MainAxisAlignment.center,
  256. crossAxisAlignment: CrossAxisAlignment.center,
  257. children: < Widget > [
  258. Text(
  259. '加载中...',
  260. style: TextStyle(fontSize: 16.0),
  261. ),
  262. Container(
  263. width: ScreenUtil.getInstance().setWidth(50),
  264. height: ScreenUtil.getInstance().setHeight(50),
  265. child: CircularProgressIndicator()
  266. )
  267. ],
  268. ),
  269. ),
  270. );
  271. }
  272. Widget _noMoreWidegt() {
  273. return Center(
  274. child: Padding(
  275. padding: EdgeInsets.all(10.0),
  276. child: Text(
  277. '没有更多数据了...',
  278. style: TextStyle(fontSize: 16.0),
  279. ),
  280. ),
  281. );
  282. }
  283. Future _onRefresh() async {
  284. page = 1;
  285. print(lineIdStr);
  286. await getOrderList(stationId,lineIdStr, page).then((resp) {
  287. if (isNotError(context, resp) && this.mounted) {
  288. setState(() {
  289. orderList = OrderListObj.fromJson(resp.data).data.items;
  290. });
  291. }
  292. });
  293. }
  294. void deleteOrder(val) { //确认接单后的操作
  295. setState(() {
  296. orderList.removeAt(val);
  297. if (orderList.length < 4) {
  298. if (hasNextPage) {
  299. setState(() {
  300. page = ++page;
  301. });
  302. getOrderList(stationId,lineIdStr, page).then((resp) {
  303. if (resp.success && resp.code == 1) {
  304. setState(() {
  305. orderList.addAll(resp.data.items);
  306. hasNextPage = resp.data.hasNextPage;
  307. });
  308. }
  309. });
  310. }
  311. }
  312. });
  313. }
  314. void switchLine(BuildContext context) { //切换线路
  315. lineIdStr = '';
  316. for (int i = 0; i < checkStatusList.length; i++) {
  317. if (checkStatusList[i]) {
  318. lineIdStr += lineList[i].id.toString() + ',';
  319. }
  320. }
  321. if (lineIdStr == '') {
  322. setState(() {
  323. orderList = [];
  324. hasNextPage = false;
  325. });
  326. oldLineIdStr = lineIdStr;
  327. setKey('lineIdStr', lineIdStr);
  328. return;
  329. }
  330. lineIdStr = lineIdStr.substring(0, lineIdStr.length - 1);
  331. if (oldLineIdStr == lineIdStr) return;
  332. setState(() {
  333. orderList = [];
  334. hasNextPage = true;
  335. });
  336. getOrderList(stationId,lineIdStr, page).then((resp) {
  337. if (isNotError(context, resp) && this.mounted) {
  338. OrderListObj tempObj = OrderListObj.fromJson(resp.data);
  339. setState(() {
  340. orderList = tempObj.data.items;
  341. hasNextPage = tempObj.data.hasNextPage;
  342. });
  343. oldLineIdStr = lineIdStr;
  344. setKey('lineIdStr', lineIdStr);
  345. }
  346. });
  347. }
  348. }
  349. class OrderCardContainer extends StatefulWidget {
  350. final OrderList order;
  351. final int index;
  352. final callback;
  353. OrderCardContainer({
  354. Key key,
  355. @required this.order,
  356. @required this.index,
  357. @required this.callback
  358. }): super(key: key);
  359. _OrderCardContainerState createState() => _OrderCardContainerState();
  360. }
  361. class _OrderCardContainerState extends State < OrderCardContainer > with SingleTickerProviderStateMixin {
  362. Animation < dynamic > animation;
  363. AnimationController controller;
  364. String str = "联系方式";
  365. bool animationStatus = true;
  366. @override
  367. initState() {
  368. super.initState();
  369. controller = new AnimationController(duration: const Duration(milliseconds: 200), vsync: this);
  370. animation = Tween(begin: 0, end: 230).animate(controller);
  371. animation.addStatusListener((status) {
  372. if (status == AnimationStatus.completed) {
  373. //动画执行结束时反向执行动画
  374. setState(() {
  375. animationStatus = false;
  376. str = "收起";
  377. });
  378. } else if (status == AnimationStatus.dismissed) {
  379. //动画恢复到初始状态时执行动画(正向)
  380. setState(() {
  381. animationStatus = true;
  382. str = "联系方式";
  383. });
  384. }
  385. });
  386. }
  387. @override
  388. Widget build(BuildContext context) {
  389. return Card(
  390. color: Colors.white,
  391. elevation: 3.0,
  392. child: Container(
  393. padding: EdgeInsets.fromLTRB(ScreenUtil.getInstance().setWidth(30), ScreenUtil.getInstance().setWidth(30), ScreenUtil.getInstance().setWidth(30), 0),
  394. child: Column(
  395. children: < Widget > [
  396. orderNoRow(widget.order.orderNo, widget.order.createTime),
  397. orderAddress(widget.order.receiptCompanyName, widget.order.sendCompanyName),
  398. orderItem('货物名称', widget.order.goods, 15),
  399. orderItem('货物件数', '${widget.order.goodsQuantity}件', 30),
  400. orderCutLine(),
  401. orderBtn(context, animationStatus, controller, str, widget.order.orderNo),
  402. AnimatedOpen(animation: animation, openInfo: widget.order, )
  403. ],
  404. ),
  405. )
  406. );
  407. }
  408. dispose() {
  409. //路由销毁时需要释放动画资源
  410. controller.dispose();
  411. super.dispose();
  412. }
  413. Widget orderBtn(BuildContext context, bool animationStatus, AnimationController controller, String str, String orderNo) {
  414. return Container(
  415. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(20)),
  416. child: Row(
  417. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  418. children: < Widget > [
  419. InkWell(
  420. child: Container(
  421. width: ScreenUtil.getInstance().setWidth(100),
  422. height: ScreenUtil.getInstance().setHeight(48),
  423. color: Colors.white,
  424. child: Center(
  425. child: Text(str, style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(24), color: Color.fromRGBO(64, 98, 254, 1)), ),
  426. )
  427. ),
  428. onTap: () {
  429. if (animationStatus) {
  430. //动画恢复到初始状态时执行动画(正向)
  431. controller.forward();
  432. } else {
  433. //动画执行结束时反向执行动画
  434. controller.reverse();
  435. }
  436. },
  437. ),
  438. InkWell(
  439. child: Container(
  440. width: ScreenUtil.getInstance().setWidth(94),
  441. height: ScreenUtil.getInstance().setWidth(48),
  442. decoration: BoxDecoration(
  443. color: Color.fromRGBO(252, 97, 128, 1),
  444. borderRadius: BorderRadius.all(Radius.circular(4.0))
  445. ),
  446. child: Center(
  447. child: Text("接单", style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(24), color: Colors.white), ),
  448. ),
  449. ),
  450. onTap: () {
  451. showDialog < Null > (
  452. context: context, //BuildContext对象
  453. barrierDismissible: false,
  454. builder: (BuildContext context) {
  455. return new LoadingDialog( //调用对话框
  456. text: '是否确认接单', childCallback: (val) {
  457. if (val) {
  458. orderReception(orderNo).then((resp) {
  459. if (isNotError(context, resp) && this.mounted) {
  460. widget.callback(widget.index);
  461. }
  462. });
  463. } else {
  464. return;
  465. }
  466. },
  467. );
  468. });
  469. },
  470. )
  471. ],
  472. )
  473. );
  474. }
  475. }
  476. class AnimatedOpen extends AnimatedWidget {
  477. final OrderList openInfo;
  478. AnimatedOpen({
  479. Key key,
  480. Animation < dynamic > animation,
  481. @required this.openInfo
  482. }): super(key: key, listenable: animation);
  483. Widget build(BuildContext context) {
  484. final Animation < dynamic > animation = listenable;
  485. return Container(
  486. height: ScreenUtil.getInstance().setHeight(animation.value),
  487. child: orderDetailInfo(openInfo),
  488. );
  489. }
  490. }
  491. Widget orderNoRow(String orderNo, int createTime) { //订单号及时间
  492. String date = fromatDate(createTime);
  493. return Container(
  494. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(30)),
  495. child: Row(
  496. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  497. children: < Widget > [
  498. Text("订单号:${orderNo}", style: TextStyle(color: Color.fromRGBO(153, 153, 153, 1), fontSize: ScreenUtil.getInstance().setSp(24)), ),
  499. Text('${date}', style: TextStyle(color: Color.fromRGBO(153, 153, 153, 1), fontSize: ScreenUtil.getInstance().setSp(24)), ),
  500. ],
  501. ),
  502. );
  503. }
  504. Widget orderAddress(String startAddress, String endAddress) { //运送路线
  505. return Container(
  506. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(20)),
  507. child: Row(children: < Widget > [
  508. Text('${startAddress} ---> ${endAddress}', style: TextStyle(color: Colors.black, fontSize: ScreenUtil.getInstance().setSp(30)), ),
  509. ], )
  510. );
  511. }
  512. Widget orderCutLine() { //分割线
  513. return Container(
  514. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(20)),
  515. height: ScreenUtil.getInstance().setHeight(1),
  516. color: Color.fromRGBO(223, 223, 223, 1),
  517. );
  518. }
  519. Widget orderDetailInfo(OrderList obj) { //卡片展开信息
  520. return Container(
  521. child: Wrap(
  522. children: < Widget > [
  523. orderCutLine(),
  524. orderPhone('发件电话', obj.sendCompanyPhone, 15),
  525. orderItem('发件地址', obj.sendCompanyAddress, 30),
  526. orderPhone('收件电话', obj.receiptCompanyPhone, 15),
  527. orderItem('收件地址', obj.receiptCompanyAddress, 30),
  528. ],
  529. )
  530. );
  531. }
  532. Widget orderItem(String key, String value, int marginBottom) { //货物名称,件数
  533. return Container(
  534. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(marginBottom)),
  535. child: Row(children: < Widget > [
  536. Text('${key}:${value}', style: TextStyle(color: Color.fromRGBO(153, 153, 153, 1), fontSize: ScreenUtil.getInstance().setSp(24)), ),
  537. ], )
  538. );
  539. }
  540. Widget orderPhone(String key, String value, int marginBottom) {
  541. return InkWell(
  542. child: Container(
  543. margin: EdgeInsets.only(bottom: ScreenUtil.getInstance().setHeight(marginBottom)),
  544. child: Row(children: < Widget > [
  545. Text('${key}:', style: TextStyle(color: Color.fromRGBO(153, 153, 153, 1), fontSize: ScreenUtil.getInstance().setSp(24)), ),
  546. Text('${value}', style: TextStyle(color: Color.fromRGBO(64, 98, 254, 1), fontSize: ScreenUtil.getInstance().setSp(24)), ),
  547. ], )
  548. ),
  549. onTap: () async {
  550. String phone = 'tel:${value}';
  551. print(phone);
  552. if (await canLaunch(phone)) {
  553. await (launch(phone));
  554. } else {
  555. throw 'Could not launch $value';
  556. }
  557. },
  558. );
  559. }