order_taking_page.dart 18 KB

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