order_taking_page.dart 17 KB

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