home_page.dart 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:bbyyy/beans/ad_bean_entity.dart';
  4. import 'package:bbyyy/beans/commodity_category_bean_entity.dart';
  5. import 'package:bbyyy/beans/goods_bean_entity.dart';
  6. import 'package:bbyyy/beans/my_shop_bean_entity.dart';
  7. import 'package:bbyyy/beans/store_bean_entity.dart';
  8. import 'package:bbyyy/https/MyDio.dart';
  9. import 'package:bbyyy/my_tools/const.dart';
  10. import 'package:bbyyy/my_tools/dims.dart';
  11. import 'package:bbyyy/my_tools/event_bus.dart';
  12. import 'package:bbyyy/my_tools/my_colors.dart';
  13. import 'package:bbyyy/my_tools/my_cookie.dart';
  14. import 'package:bbyyy/my_tools/my_tools.dart';
  15. import 'package:bbyyy/my_tools/my_views.dart';
  16. import 'package:bbyyy/paegs/root_page/root_page_view.dart';
  17. import 'package:flutter/cupertino.dart';
  18. import 'package:flutter/material.dart';
  19. import 'package:flutter_svg/flutter_svg.dart';
  20. import 'package:flutter_swiper/flutter_swiper.dart';
  21. import 'package:pull_to_refresh/pull_to_refresh.dart';
  22. class HomePage extends StatefulWidget {
  23. @override
  24. _HomePageState createState() => _HomePageState();
  25. }
  26. class _HomePageState extends State<HomePage>
  27. with AutomaticKeepAliveClientMixin {
  28. var data = [];
  29. var container = [];
  30. var puShop = [];
  31. var imgs = ['images/banner1.png', 'images/banner2.png', 'images/banner3.png'];
  32. int selectedIndex = 0;
  33. var tabs = ['全部'];
  34. var types = ['货帮', '货品'];
  35. List<DropdownMenuItem<String>> sortItems = [];
  36. int typeIndex = 1;
  37. List<MyShopBeanDataData> shops = [];
  38. ScrollController _controller = ScrollController();
  39. double maxH;
  40. double minH = 164;
  41. double H = 0;
  42. bool showInput = false;
  43. TextEditingController _description = TextEditingController();
  44. FocusNode _descriptionFocus = FocusNode();
  45. RefreshController _reController = RefreshController(initialRefresh: true);
  46. int page = 1;
  47. int pageIndex = 0;
  48. bool showS = false;
  49. @override
  50. void initState() {
  51. super.initState();
  52. EventBus().on('commodity_category', (arg) {
  53. setState(() {});
  54. });
  55. EventBus().on('uploadGoods', (arg) {
  56. _reController.requestRefresh();
  57. });
  58. EventBus().on('toTop', (arg) {
  59. _controller.animateTo(0.0,
  60. duration: Duration(milliseconds: 200), curve: Curves.easeIn);
  61. });
  62. EventBus().on('商品变动', (arg) {
  63. _reController.requestRefresh();
  64. });
  65. _controller.addListener(() {
  66. setState(() {
  67. if (_controller.offset == 0) {
  68. RootPageView().toTop = false;
  69. EventBus().emit('ChangePage');
  70. } else {
  71. RootPageView().toTop = true;
  72. EventBus().emit('ChangePage');
  73. }
  74. H = maxH - _controller.offset;
  75. if (H < minH) {
  76. H = minH;
  77. } else if (H > maxH) {
  78. H = maxH;
  79. }
  80. });
  81. });
  82. types.forEach((element) {
  83. sortItems.add(DropdownMenuItem(
  84. child: Text(
  85. element,
  86. style: TextStyle(color: MyColors.c666666, fontSize: 14),
  87. ),
  88. value: element,
  89. ));
  90. });
  91. _descriptionFocus.addListener(() {
  92. if (_descriptionFocus.hasFocus) {
  93. } else {
  94. if (_description.text.isEmpty) {
  95. showInput = false;
  96. }
  97. }
  98. });
  99. }
  100. @override
  101. void dispose() {
  102. // TODO: implement dispose
  103. super.dispose();
  104. EventBus().off('commodity_category');
  105. EventBus().off('uploadGoods');
  106. EventBus().off('toTop');
  107. }
  108. @override
  109. Widget build(BuildContext context) {
  110. maxH = MediaQuery.of(context).size.width * (520 / 750);
  111. minH = MediaQuery.of(context).padding.top + 64;
  112. if (H == 0) {
  113. H = maxH;
  114. }
  115. return GestureDetector(
  116. onTap: () {
  117. MyTools().hideKeyboard(context);
  118. },
  119. behavior: HitTestBehavior.translucent,
  120. child: Scaffold(
  121. resizeToAvoidBottomInset: false,
  122. body: Column(
  123. children: [
  124. Stack(
  125. children: [
  126. AnimatedContainer(
  127. height: H,
  128. duration: Duration(milliseconds: 200),
  129. child: Swiper(
  130. itemBuilder: (BuildContext context, int index) {
  131. return new Image.asset(
  132. "${imgs[index]}",
  133. fit: BoxFit.cover,
  134. );
  135. },
  136. itemCount: 3,
  137. viewportFraction: 1,
  138. scale: 1,
  139. autoplay: true,
  140. ),
  141. ),
  142. SafeArea(
  143. child: Stack(
  144. children: [
  145. AnimatedOpacity(
  146. duration: Duration(milliseconds: 200),
  147. opacity: showS ? 0.0 : 1.0,
  148. child: Container(
  149. margin: EdgeInsets.only(top: 18),
  150. width: double.infinity,
  151. child: Row(
  152. children: [
  153. GestureDetector(
  154. onTap: () {
  155. setState(() {
  156. pageIndex = 0;
  157. _reController.requestRefresh();
  158. });
  159. },
  160. behavior: HitTestBehavior.translucent,
  161. child: Container(
  162. height: 28,
  163. width: 60,
  164. alignment: Alignment.center,
  165. child: Column(
  166. children: [
  167. Text(
  168. '店铺',
  169. style: TextStyle(
  170. color: pageIndex == 0
  171. ? MyColors.cFF4233
  172. : MyColors.c333333,
  173. fontSize: 16,
  174. fontWeight: FontWeight.bold),
  175. ),
  176. Visibility(
  177. child: Container(
  178. width: 32,
  179. height: 2,
  180. decoration: BoxDecoration(
  181. color: MyColors.cFF4233,
  182. borderRadius:
  183. BorderRadius.circular(1)),
  184. ),
  185. visible: pageIndex == 0,
  186. ),
  187. ],
  188. ),
  189. ),
  190. ),
  191. Container(
  192. width: 40,
  193. ),
  194. GestureDetector(
  195. onTap: () {
  196. setState(() {
  197. pageIndex = 1;
  198. _reController.requestRefresh();
  199. });
  200. },
  201. behavior: HitTestBehavior.translucent,
  202. child: Container(
  203. height: 28,
  204. width: 60,
  205. alignment: Alignment.center,
  206. child: Column(
  207. children: [
  208. Text(
  209. '商品',
  210. style: TextStyle(
  211. color: pageIndex == 1
  212. ? MyColors.cFF4233
  213. : MyColors.c333333,
  214. fontSize: 16,
  215. fontWeight: FontWeight.bold),
  216. ),
  217. Visibility(
  218. child: Container(
  219. width: 32,
  220. height: 2,
  221. decoration: BoxDecoration(
  222. color: MyColors.cFF4233,
  223. borderRadius:
  224. BorderRadius.circular(1)),
  225. ),
  226. visible: pageIndex == 1,
  227. ),
  228. ],
  229. ),
  230. ),
  231. ),
  232. ],
  233. mainAxisAlignment: MainAxisAlignment.center,
  234. ),
  235. ),
  236. ),
  237. Container(
  238. padding: EdgeInsets.only(left: 10, right: 10, top: 12),
  239. child: GestureDetector(
  240. onTap: () {
  241. showS = !showS;
  242. if (!showS) {
  243. _description.clear();
  244. }
  245. setState(() {});
  246. },
  247. behavior: HitTestBehavior.translucent,
  248. child: AnimatedContainer(
  249. height: 40,
  250. width:
  251. !showS ? 40 : MediaQuery.of(context).size.width,
  252. child: Row(
  253. children: [
  254. SvgPicture.asset(
  255. showS
  256. ? 'images/svg/箭头.svg'
  257. : 'images/svg/搜索.svg',
  258. height: 15,
  259. width: 15,
  260. color:
  261. showS ? MyColors.cFF4233 : Colors.white,
  262. ),
  263. Visibility(
  264. visible: showS,
  265. child: Expanded(
  266. child: TextField(
  267. controller: _description,
  268. cursorColor: MyColors.cFF4233,
  269. cursorWidth: 1.0,
  270. onTap: () {},
  271. decoration: InputDecoration(
  272. border: InputBorder.none,
  273. disabledBorder: InputBorder.none,
  274. enabledBorder: InputBorder.none,
  275. focusedBorder: InputBorder.none,
  276. isDense: true,
  277. hintText: '请输入...',
  278. hintStyle: TextStyle(
  279. color: MyColors.c999999,
  280. fontSize: 16),
  281. contentPadding:
  282. const EdgeInsets.fromLTRB(
  283. 14, 4.5, 8, 4.5),
  284. ),
  285. maxLines: 1,
  286. style: TextStyle(
  287. color: MyColors.c333333,
  288. fontSize: 16,
  289. height: 1.3,
  290. letterSpacing: 0.2),
  291. keyboardType: TextInputType.text,
  292. onChanged: (t) {
  293. setState(() {});
  294. },
  295. ),
  296. ),
  297. ),
  298. Visibility(
  299. visible:
  300. showS && _description.text.isNotEmpty,
  301. child: GestureDetector(
  302. onTap: () {
  303. MyTools().hideKeyboard(context);
  304. _reController.requestRefresh();
  305. },
  306. behavior: HitTestBehavior.translucent,
  307. child: Container(
  308. child: MyViews()
  309. .myText('搜索', Colors.white, 13),
  310. decoration: BoxDecoration(
  311. color: MyColors.cFF4233,
  312. borderRadius: BorderRadius.circular(20),
  313. ),
  314. height: 40,
  315. width: 80,
  316. alignment: Alignment.center,
  317. ),
  318. ),
  319. )
  320. ],
  321. mainAxisAlignment: MainAxisAlignment.center,
  322. ),
  323. alignment: !showS
  324. ? Alignment.center
  325. : Alignment.centerLeft,
  326. padding: EdgeInsets.only(left: !showS ? 0 : 12),
  327. decoration: BoxDecoration(
  328. borderRadius:
  329. BorderRadius.all(Radius.circular(20)),
  330. color: showS ? Colors.white : MyColors.cFF4233),
  331. duration: Duration(milliseconds: 200),
  332. ),
  333. ),
  334. alignment: Alignment.centerRight,
  335. ),
  336. ],
  337. ),
  338. ),
  339. ],
  340. ),
  341. Column(
  342. children: [
  343. Container(
  344. height: 53,
  345. child: ListView.builder(
  346. padding: EdgeInsets.only(left: 12, right: 12),
  347. itemBuilder: (c, index) {
  348. return GestureDetector(
  349. onTap: () {
  350. setState(() {
  351. selectedIndex = index;
  352. _reController.requestRefresh();
  353. });
  354. },
  355. behavior: HitTestBehavior.translucent,
  356. child: Container(
  357. padding:
  358. EdgeInsets.only(right: 15, left: 15, bottom: 9),
  359. child: Column(
  360. children: [
  361. Text(
  362. tabs[index],
  363. style: TextStyle(
  364. color: index == selectedIndex
  365. ? MyColors.cFF4233
  366. : MyColors.c666666,
  367. fontSize: 14),
  368. ),
  369. Container(
  370. height: 10,
  371. child: Visibility(
  372. child: SvgPicture.asset('images/svg/tab.svg'),
  373. visible: index == selectedIndex,
  374. ),
  375. )
  376. ],
  377. mainAxisAlignment: MainAxisAlignment.end,
  378. ),
  379. height: 53,
  380. ),
  381. );
  382. },
  383. itemCount: tabs.length,
  384. scrollDirection: Axis.horizontal,
  385. ),
  386. ),
  387. Container(
  388. height: 1,
  389. color: MyColors.cf2f2f2,
  390. ),
  391. ],
  392. ),
  393. Expanded(
  394. flex: 1,
  395. child: SmartRefresher(
  396. controller: _reController,
  397. onRefresh: onRefresh,
  398. onLoading: onLoading,
  399. enablePullDown: true,
  400. enablePullUp: true,
  401. child: body(),
  402. ),
  403. )
  404. ],
  405. ),
  406. ),
  407. );
  408. }
  409. @override
  410. // TODO: implement wantKeepAlive
  411. bool get wantKeepAlive => true;
  412. void getGoods(List<dynamic> shopUID) {
  413. var qData;
  414. if (shopUID.length == 0) {
  415. var conditions = ["public == true", "on_sale == true"];
  416. if (selectedIndex != 0) {
  417. conditions.add("category == ${tabs[selectedIndex]}");
  418. }
  419. if (_description.text.isNotEmpty) {
  420. conditions.add('title LIKE ${_description.text.toString()}');
  421. }
  422. qData = {
  423. "key": "commodity",
  424. "filters": {"conditions": conditions},
  425. "dims": commodityDims,
  426. "paging": [page, 20]
  427. };
  428. } else {
  429. var conditions = ["shop_uid in $shopUID", "on_sale == true"];
  430. var conditions2 = ["public == true", "on_sale == true"];
  431. if (selectedIndex != 0) {
  432. conditions.add("category == ${tabs[selectedIndex]}");
  433. conditions2.add("category == ${tabs[selectedIndex]}");
  434. }
  435. if (_description.text.isNotEmpty) {
  436. conditions.add('title LIKE ${_description.text.toString()}');
  437. conditions2.add('title LIKE ${_description.text.toString()}');
  438. }
  439. qData = {
  440. "key": "commodity",
  441. "filters": {
  442. "or": true,
  443. "conditions": conditions,
  444. "filters": [
  445. {"conditions": conditions2}
  446. ]
  447. },
  448. "dims": commodityDims,
  449. "paging": [page, 20]
  450. };
  451. }
  452. MyDio().query(qData, (response, hasError) {
  453. if (!hasError) {
  454. GoodsBeanEntity entity =
  455. GoodsBeanEntity().fromJson(json.decode(response.data.toString()));
  456. container.clear();
  457. container.addAll(entity.data.data);
  458. }
  459. queryAd();
  460. }, (error) {
  461. queryAd();
  462. });
  463. }
  464. void onRefresh() {
  465. page = 1;
  466. if (pageIndex == 1) {
  467. initTabs();
  468. findAStore();
  469. } else {
  470. storeType();
  471. checkPublicStores();
  472. }
  473. }
  474. void onLoading() {
  475. page++;
  476. if (pageIndex == 1) {
  477. findAStore();
  478. } else {
  479. checkPublicStores();
  480. }
  481. }
  482. Future<void> initTabs() async {
  483. List<CommodityCategoryBeanData> commodityCategoryBeanData = [];
  484. MyDio().query({
  485. "key": "commodity_category",
  486. "filters": {},
  487. "dims": [
  488. "name",
  489. ]
  490. }, (response, hasError) {
  491. if (!hasError) {
  492. CommodityCategoryBeanEntity entity = CommodityCategoryBeanEntity()
  493. .fromJson(json.decode(response.data.toString()));
  494. commodityCategoryBeanData = entity.data;
  495. tabs.clear();
  496. tabs.add('全部');
  497. commodityCategoryBeanData.forEach((element) {
  498. tabs.insert(1, element.name);
  499. });
  500. setState(() {});
  501. } else {
  502. return commodityCategoryBeanData;
  503. }
  504. }, (error) {
  505. return commodityCategoryBeanData;
  506. });
  507. }
  508. findAStore() {
  509. MyDio().query({
  510. "key": "shop_user",
  511. "filters": {
  512. "or": true,
  513. "conditions": [
  514. "role!=$shopUserOwner",
  515. "user_uid==${MyCookie().getUID()}",
  516. "review_state==1"
  517. ],
  518. "filters": [
  519. {
  520. "conditions": [
  521. "role==$shopUserOwner",
  522. "user_uid==${MyCookie().getUID()}"
  523. ]
  524. }
  525. ]
  526. },
  527. "dims": shopUserDims,
  528. "paging": [1, 20000]
  529. }, (response, hasError) {
  530. if (!hasError) {
  531. MyShopBeanEntity entity =
  532. MyShopBeanEntity().fromJson(json.decode(response.data.toString()));
  533. shops = entity.data.data;
  534. var shopUID = [];
  535. shops.forEach((element) {
  536. shopUID.add(element.shopUid);
  537. });
  538. getGoods(shopUID);
  539. }
  540. }, (error) {});
  541. }
  542. queryAd() {
  543. MyDio().query({
  544. "key": "ad",
  545. "filters": {
  546. "conditions": ['on_show == true']
  547. },
  548. "dims": adDims,
  549. "paging": [page, 2]
  550. }, (response, hasError) {
  551. if (!hasError) {
  552. AdBeanEntity entity =
  553. AdBeanEntity().fromJson(json.decode(response.data.toString()));
  554. container.addAll(entity.data.data);
  555. container.shuffle();
  556. }
  557. if (page == 1) {
  558. data.clear();
  559. puShop.clear();
  560. }
  561. if (pageIndex == 1) {
  562. data.addAll(container);
  563. } else {
  564. puShop.addAll(container);
  565. }
  566. setState(() {});
  567. endRe(_reController);
  568. }, (error) {
  569. if (page == 1) {
  570. data.clear();
  571. }
  572. data.addAll(container);
  573. setState(() {});
  574. endRe(_reController);
  575. });
  576. }
  577. void checkPublicStores() {
  578. var conditions = ['private==false', 'state == $shopStateNormal'];
  579. if (selectedIndex != 0) {
  580. conditions.add("category == ${tabs[selectedIndex]}");
  581. }
  582. if (_description.text.isNotEmpty) {
  583. conditions.add('name LIKE ${_description.text.toString()}');
  584. }
  585. MyDio().query({
  586. "key": "shop",
  587. "filters": {"conditions": conditions},
  588. "dims": shopDims,
  589. "paging": [page, 20]
  590. }, (response, hasError) {
  591. if (!hasError) {
  592. StoreBeanEntity entity =
  593. StoreBeanEntity().fromJson(json.decode(response.data.toString()));
  594. container.clear();
  595. container.addAll(entity.data.data);
  596. }
  597. queryAd();
  598. }, (error) {
  599. queryAd();
  600. });
  601. }
  602. void storeType() {
  603. List<CommodityCategoryBeanData> commodityCategoryBeanData = [];
  604. MyDio().query({
  605. "key": "shop_category",
  606. "filters": {},
  607. "dims": [
  608. "name",
  609. ]
  610. }, (response, hasError) {
  611. if (!hasError) {
  612. CommodityCategoryBeanEntity entity = CommodityCategoryBeanEntity()
  613. .fromJson(json.decode(response.data.toString()));
  614. commodityCategoryBeanData = entity.data;
  615. tabs.clear();
  616. tabs.add('全部');
  617. commodityCategoryBeanData.forEach((element) {
  618. tabs.insert(1, element.name);
  619. });
  620. setState(() {});
  621. }
  622. }, (error) {});
  623. }
  624. body() {
  625. if (pageIndex == 1) {
  626. return body1();
  627. } else if (pageIndex == 0) {
  628. return body2();
  629. }
  630. }
  631. body1() {
  632. if (data.length == 0) {
  633. return noData();
  634. } else {
  635. return GridView.builder(
  636. controller: _controller,
  637. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  638. crossAxisCount: 2,
  639. childAspectRatio: 164 / 261,
  640. mainAxisSpacing: 8,
  641. crossAxisSpacing: 8),
  642. itemCount: data.length,
  643. padding: EdgeInsets.only(left: 14, right: 14, top: 14, bottom: 65),
  644. itemBuilder: (context, index) {
  645. return MyViews().getGoodsItem(data[index], context);
  646. });
  647. }
  648. }
  649. body2() {
  650. if (puShop.length == 0) {
  651. return noData();
  652. } else {
  653. return ListView.builder(
  654. controller: _controller,
  655. itemBuilder: (BuildContext context, int index) {
  656. return MyViews().pubShopItem(puShop[index], context);
  657. },
  658. itemCount: puShop.length,
  659. padding: EdgeInsets.all(10),
  660. );
  661. }
  662. }
  663. }