order_taking_page.dart 21 KB

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