order_taking_page.dart 18 KB

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