order_taking_page.dart 16 KB

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