order_taking_page.dart 17 KB

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