order_taking_page.dart 19 KB

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