order_taking_page.dart 19 KB

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