order_taking_page.dart 18 KB

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