bbs_page.dart 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:flustars/flustars.dart' as FlutterStars;
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_screenutil/flutter_screenutil.dart';
  6. import 'package:flutter_spinkit/flutter_spinkit.dart';
  7. import 'package:fluwx/fluwx.dart' as fluwx;
  8. import 'package:liftmanager/common/common.dart';
  9. import 'package:liftmanager/internal/account/account_router.dart';
  10. import 'package:liftmanager/internal/bbs/bbs_router.dart';
  11. import 'package:liftmanager/internal/bbs/model/banner_model.dart';
  12. import 'package:liftmanager/internal/bbs/model/news_comm_entity.dart';
  13. import 'package:liftmanager/internal/bbs/presenter/news_list_presenter.dart';
  14. import 'package:liftmanager/internal/bbs/provide/websocket.dart';
  15. import 'package:liftmanager/internal/means/means_router.dart';
  16. import 'package:liftmanager/internal/news/news_router.dart';
  17. import 'package:liftmanager/internal/search/presenter/base_list_provider.dart';
  18. import 'package:liftmanager/mvp/base_page_state.dart';
  19. import 'package:liftmanager/net/api_service.dart';
  20. import 'package:liftmanager/routers/fluro_navigator.dart';
  21. import 'package:liftmanager/utils/fast_notification.dart';
  22. import 'package:liftmanager/utils/image_utils.dart';
  23. import 'package:liftmanager/utils/location_helper.dart';
  24. import 'package:liftmanager/utils/theme_utils.dart';
  25. import 'package:liftmanager/utils/toast.dart';
  26. import 'package:liftmanager/utils/utils.dart';
  27. import 'package:liftmanager/widgets/app_city_search_bar.dart';
  28. import 'package:liftmanager/widgets/bbs_content.dart';
  29. import 'package:liftmanager/widgets/news_roller.dart';
  30. import 'package:provider/provider.dart';
  31. import 'package:umeng_common_sdk/umeng_common_sdk.dart';
  32. import '../../../utils/toast.dart';
  33. class BbsPage extends StatefulWidget {
  34. @override
  35. BbsPageState createState() => BbsPageState();
  36. }
  37. const timeout = const Duration(seconds: 5);
  38. class BbsPageState extends BasePageState<BbsPage, NewsListPresenter>
  39. with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  40. BaseListProvider<NewsItem> provider = BaseListProvider<NewsItem>();
  41. TabController _tabController;
  42. PageController _pageController = PageController();
  43. List<String> menuTitle = ["案例中心", "视频学堂", "配件商城", "招聘求职", "资料库"];
  44. List<String> menuImage = ['case', 'video', 'mall', 'recruitment', 'resource'];
  45. bool display = true;
  46. String _cityName;
  47. String _provinceName;
  48. Timer _timer;
  49. String latitude;
  50. String longitude;
  51. Widget bannerLastWidget;
  52. List<dynamic> bannerList;
  53. List<dynamic> questionsList;
  54. List<dynamic> newsList;
  55. List<dynamic> videoList;
  56. List<dynamic> shopList;
  57. List<dynamic> positionList;
  58. bool isCustom = false;
  59. @override
  60. void initState() {
  61. super.initState();
  62. if (FlutterStars.SpUtil.getString(Constant.userId) != "-1") {
  63. Provider.of<WebSocketProvide>(context, listen: false)
  64. .createWebsocket(FlutterStars.SpUtil.getString(Constant.userId));
  65. UmengCommonSdk.onProfileSignIn(
  66. FlutterStars.SpUtil.getString(Constant.userId));
  67. }
  68. getLocation();
  69. getBannerList();
  70. getNewsList();
  71. getQuestionList();
  72. getVideoList();
  73. getShopList();
  74. getPositionList();
  75. getNotificaList();
  76. _initFluwx();
  77. FastNotification.addListener("initNotice", (initThisNotice) {
  78. if (mounted) {
  79. setState(() {
  80. getNotificaList();
  81. });
  82. }
  83. });
  84. if (FlutterStars.SpUtil.getString(Constant.userId) == "-1") {
  85. isCustom = true;
  86. }
  87. }
  88. @override
  89. void dispose() {
  90. _tabController?.dispose();
  91. _pageController.dispose();
  92. cancelTimer();
  93. super.dispose();
  94. }
  95. getLocation() async {
  96. var helper = LocationHelper();
  97. helper.getLocation((lat, lng, cityName, {address, provinceName}) {
  98. if (cityName != null) {
  99. setState(() {
  100. _cityName = cityName;
  101. _provinceName = provinceName;
  102. });
  103. helper.stopGettingLocation();
  104. }
  105. latitude = lat;
  106. longitude = lng;
  107. if (FlutterStars.SpUtil.getString(Constant.userId) != "-1") {
  108. isDelayAddress();
  109. }
  110. });
  111. // helper.getLocation((lat, lng, cityName, { provinceName,a}}) {
  112. // if (cityName != null) {
  113. // setState(() {
  114. // _cityName = cityName;
  115. // _provinceName = provinceName;
  116. // });
  117. // helper.stopGettingLocation();
  118. // }
  119. // latitude = lat;
  120. // longitude = lng;
  121. // if (FlutterStars.SpUtil.getString(Constant.userId) != "-1") {
  122. // isDelayAddress();
  123. // }
  124. // });
  125. }
  126. _initFluwx() async {
  127. await fluwx.registerWxApi(
  128. appId: "wx0f10e6386fb9969e",
  129. doOnAndroid: true,
  130. doOnIOS: true,
  131. universalLink: "https://www.edtyun.com/");
  132. var result = await fluwx.isWeChatInstalled();
  133. setState(() {});
  134. }
  135. void startTimer(int intervalTime) {
  136. Duration period = Duration(minutes: intervalTime);
  137. _timer = Timer.periodic(period, (timer) {
  138. getStartDelayAddress();
  139. });
  140. }
  141. void cancelTimer() {
  142. if (_timer != null) {
  143. _timer.cancel();
  144. _timer = null;
  145. }
  146. }
  147. Future isDelayAddress() async {
  148. await NewApiService().isDelayAddress(onSuccess: (res) {
  149. print(res["id"]);
  150. print(jsonEncode(res));
  151. if (res["isPush"] != null && res["isPush"] == 1) {
  152. getStartDelayAddress();
  153. startTimer(res["intervalTime"]);
  154. }
  155. //intervalTime:时间间隔分钟 ; isPush:1推送 2不推送
  156. }, onError: (code, msg) {
  157. toasts(msg);
  158. });
  159. }
  160. Future getStartDelayAddress() async {
  161. String position = latitude.toString() + "," + longitude.toString();
  162. await NewApiService().startDelayAddress({
  163. "mobile": FlutterStars.SpUtil.getString(Constant.phone),
  164. "mtCompanyId": FlutterStars.SpUtil.getString(Constant.companyId) != ""
  165. ? int.parse(FlutterStars.SpUtil.getString(Constant.companyId))
  166. : "",
  167. "position": position,
  168. "userId": int.parse(FlutterStars.SpUtil.getString(Constant.userId))
  169. }, onSuccess: (res) {}, onError: (code, msg) {
  170. toasts(msg);
  171. });
  172. }
  173. Future getBannerList() async {
  174. await NewApiService().getBanner(1, 10, onSuccess: (BannerModel res) {
  175. bannerList = res.records;
  176. bannerLastWidget = Stack(
  177. children: [
  178. SizedBox(
  179. width: double.infinity,
  180. height: 40,
  181. child: Image.asset(
  182. ImageUtils.getImgPath('background_arch_blue'),
  183. fit: BoxFit.fill,
  184. ),
  185. ),
  186. Container(
  187. margin: EdgeInsets.all(10),
  188. child: SwipeWidget(
  189. banners: bannerList,
  190. ),
  191. )
  192. ],
  193. );
  194. setState(() {});
  195. }, onError: (code, msg) {
  196. toasts(msg);
  197. });
  198. }
  199. Future getNotificaList() async {
  200. display = true;
  201. await NewApiService().getNotificationMessageList(1, 10, onSuccess: (res) {
  202. res.records.forEach((item) {
  203. if (item.viewFlag == 0) {
  204. setState(() {
  205. display = false;
  206. });
  207. return;
  208. }
  209. });
  210. setState(() {});
  211. }, onError: (code, msg) {
  212. toasts(msg);
  213. });
  214. }
  215. Future getNewsList() async {
  216. await NewApiService().topNewsList(1, 3, 1, "", onSuccess: (res) {
  217. newsList = res.rows;
  218. print(JsonEncoder().convert(res.rows));
  219. setState(() {});
  220. }, onError: (code, msg) {
  221. toasts(msg);
  222. });
  223. }
  224. Future getQuestionList() async {
  225. await NewApiService().getQuestionList(1, 3, null, null, null,
  226. onSuccess: (res) {
  227. questionsList = res.records;
  228. setState(() {});
  229. }, onError: (code, msg) {
  230. toasts(msg);
  231. });
  232. }
  233. Future getVideoList() async {
  234. await NewApiService().getVideoList(1, 4, null, null, null, "app",
  235. onSuccess: (res) {
  236. videoList = res.records;
  237. setState(() {});
  238. }, onError: (code, msg) {
  239. toasts(msg);
  240. });
  241. }
  242. Future getShopList() async {
  243. await NewApiService().getShopList(1, 3, null, null, null, onSuccess: (res) {
  244. shopList = res.records;
  245. setState(() {});
  246. }, onError: (code, msg) {
  247. toasts(msg);
  248. });
  249. }
  250. Future getPositionList() async {
  251. await NewApiService().getPositionList(1, 3, onSuccess: (res) {
  252. positionList = res.records;
  253. setState(() {});
  254. }, onError: (code, msg) {
  255. toasts(msg);
  256. });
  257. }
  258. static const diagnosisObj = [
  259. {
  260. "title": "快速问诊",
  261. "img": "tab_first/Diagnosis_first",
  262. "desc": "搜电梯品牌 找专家咨询电梯疑问",
  263. },
  264. {
  265. "title": "出诊",
  266. "img": "tab_first/Diagnosis_second",
  267. "desc": "在线预约专家上门维修服务",
  268. },
  269. ];
  270. static const diagnosisObjMaster = [
  271. {
  272. "title": "工作台",
  273. "img": "tab_first/Diagnosis_third",
  274. "desc": "问诊、出诊工作快捷入口",
  275. },
  276. ];
  277. showAlertEvent() {
  278. showAlert(
  279. context,
  280. "提示",
  281. "确定登录?",
  282. "确定",
  283. () {
  284. NavigatorUtils.push(context, AccountRouter.loginPage, clearStack: true);
  285. },
  286. txt2: "取消",
  287. onPre2: () {
  288. NavigatorUtils.goBack(context);
  289. },
  290. );
  291. }
  292. @override
  293. Widget build(BuildContext context) {
  294. return ChangeNotifierProvider<BaseListProvider<NewsItem>>(
  295. create: (_) => provider,
  296. child: RefreshIndicator(
  297. onRefresh: () async {
  298. setState(() {
  299. bannerLastWidget = null;
  300. getLocation();
  301. getBannerList();
  302. getNewsList();
  303. getQuestionList();
  304. getVideoList();
  305. getShopList();
  306. getPositionList();
  307. });
  308. },
  309. child: Scaffold(
  310. appBar: AppCitySearchAppBar(
  311. city: "${_cityName ?? '暂无定位'}", display: display),
  312. backgroundColor: Colors.transparent,
  313. body: Container(
  314. child: CustomScrollView(
  315. slivers: [
  316. SliverList(
  317. delegate: SliverChildListDelegate([
  318. bannerLastWidget != null
  319. ? bannerLastWidget
  320. : Container(child: loadCircle()),
  321. Container(
  322. padding: EdgeInsets.only(top: 10),
  323. height: 100,
  324. color: ThemeUtils.getTabsBg(context),
  325. child: quickEntriesSection()),
  326. ClipRRect(
  327. child: Container(
  328. padding: EdgeInsets.fromLTRB(10, 10, 0, 10),
  329. margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
  330. height: 63,
  331. decoration: BoxDecoration(
  332. color: Colors.white,
  333. borderRadius: BorderRadius.all(
  334. Radius.circular(10),
  335. ),
  336. boxShadow: [
  337. BoxShadow(
  338. color: Colors.grey.withOpacity(0.2),
  339. spreadRadius: 1,
  340. blurRadius: 3,
  341. offset: Offset(
  342. 0, 3), // changes position of shadow
  343. ),
  344. ]),
  345. child:
  346. newsList != null ? newsSection() : loadCircle())),
  347. LabelTitle(
  348. title: "热门视频",
  349. userTap: () {
  350. if (!Utils.getAuthByRouter(
  351. context, 'video_center', false) &&
  352. isCustom) {
  353. showAlertEvent();
  354. } else {
  355. if (Utils.getAuthByRouter(context, 'video_center')) {
  356. NavigatorUtils.push(context, BbsRouter.videoList);
  357. }
  358. }
  359. },
  360. ),
  361. ])),
  362. if (videoList != null && videoList.length > 0)
  363. SliverPadding(
  364. padding: EdgeInsets.only(
  365. left: 10, right: 10, top: 10, bottom: 20),
  366. sliver: SliverGrid.count(
  367. crossAxisCount: 2,
  368. crossAxisSpacing: 10,
  369. mainAxisSpacing: 15,
  370. childAspectRatio: 1,
  371. children:
  372. HotClass(videoList: videoList).listWidget(context),
  373. ),
  374. ),
  375. SliverList(
  376. delegate: SliverChildListDelegate(
  377. [
  378. Container(
  379. height: 10,
  380. color: Color(0xffF9F9F9),
  381. ),
  382. LabelTitle(
  383. title: "热销商品",
  384. userTap: () {
  385. if (!Utils.getAuthByRouter(
  386. context, 'shopping_center', false) &&
  387. isCustom) {
  388. showAlertEvent();
  389. } else {
  390. if (Utils.getAuthByRouter(
  391. context, 'shopping_center')) {
  392. NavigatorUtils.push(
  393. context, BbsRouter.productList);
  394. }
  395. }
  396. },
  397. ),
  398. Container(
  399. padding: EdgeInsets.symmetric(horizontal: 10),
  400. child: shopList != null && shopList.length > 0
  401. ? HotProduct(productList: shopList)
  402. : loadCircle()),
  403. SizedBox(
  404. height: 10,
  405. ),
  406. Container(
  407. height: 10,
  408. color: Color(0xffF9F9F9),
  409. ),
  410. LabelTitle(
  411. title: "热门问题",
  412. userTap: () {
  413. if (!Utils.getAuthByRouter(
  414. context, 'question_center', false) &&
  415. isCustom) {
  416. showAlertEvent();
  417. } else {
  418. if (Utils.getAuthByRouter(
  419. context, 'question_center')) {
  420. NavigatorUtils.push(
  421. context, BbsRouter.questionList);
  422. }
  423. }
  424. },
  425. ),
  426. Container(
  427. child:
  428. questionsList != null && questionsList.length > 0
  429. ? HotQuestion(initList: questionsList)
  430. : loadCircle()),
  431. Container(
  432. height: 10,
  433. color: Color(0xffF9F9F9),
  434. ),
  435. LabelTitle(
  436. title: "热招职位",
  437. userTap: () {
  438. if (!Utils.getAuthByRouter(
  439. context, 'job_center', false) &&
  440. isCustom) {
  441. showAlertEvent();
  442. } else {
  443. if (Utils.getAuthByRouter(context, 'job_center')) {
  444. NavigatorUtils.push(context,
  445. "${BbsRouter.positionList}?city=${Uri.encodeComponent(_cityName ?? '')}&provinceName=${Uri.encodeComponent(_provinceName ?? '')}");
  446. }
  447. }
  448. },
  449. ),
  450. Container(
  451. padding: EdgeInsets.symmetric(
  452. horizontal: 10, vertical: 10),
  453. color: ThemeUtils.getTabsBg(context),
  454. child: positionList != null && positionList.length > 0
  455. ? HotPosition(positionList: positionList)
  456. : loadCircle()),
  457. ],
  458. ),
  459. )
  460. ],
  461. )),
  462. )),
  463. );
  464. }
  465. Widget quickEntriesSection() => _ToolsItem(menuTitle, menuImage, (index) {
  466. if (index == 0) {
  467. if (!Utils.getAuthByRouter(context, 'question_center', false) &&
  468. isCustom) {
  469. showAlertEvent();
  470. } else if (Utils.getAuthByRouter(context, 'question_center')) {
  471. NavigatorUtils.push(context, BbsRouter.questionList);
  472. }
  473. } else if (index == 1) {
  474. if (!Utils.getAuthByRouter(context, 'video_center', false) &&
  475. isCustom) {
  476. showAlertEvent();
  477. } else if (Utils.getAuthByRouter(context, 'video_center')) {
  478. NavigatorUtils.push(context, BbsRouter.videoList);
  479. }
  480. } else if (index == 2) {
  481. if (!Utils.getAuthByRouter(context, 'shopping_center', false) &&
  482. isCustom) {
  483. showAlertEvent();
  484. } else if (Utils.getAuthByRouter(context, 'shopping_center')) {
  485. NavigatorUtils.push(context, BbsRouter.productList);
  486. }
  487. } else if (index == 3) {
  488. if (!Utils.getAuthByRouter(context, 'job_center', false) &&
  489. isCustom) {
  490. showAlertEvent();
  491. } else if (Utils.getAuthByRouter(context, 'job_center')) {
  492. // _cityName = '武汉市';
  493. // _provinceName = '湖北省';
  494. NavigatorUtils.push(context,
  495. "${BbsRouter.positionList}?city=${Uri.encodeComponent(_cityName ?? '')}&provinceName=${Uri.encodeComponent(_provinceName ?? '')}");
  496. }
  497. } else if (index == 4) {
  498. if (!Utils.getAuthByRouter(context, 'database', false) && isCustom) {
  499. showAlertEvent();
  500. } else if (Utils.getAuthByRouter(context, 'database')) {
  501. NavigatorUtils.push(context, MeansRouter.meansPage);
  502. }
  503. }
  504. });
  505. Widget newsSection() =>
  506. Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
  507. Image.asset(ImageUtils.getImgPath('hotnews')),
  508. Expanded(child: NewsRoller(newsList), flex: 1),
  509. Expanded(
  510. flex: 0,
  511. child: GestureDetector(
  512. onTap: () {
  513. if (!Utils.getAuthByRouter(context, 'news', false) &&
  514. isCustom) {
  515. showAlertEvent();
  516. } else {
  517. if (Utils.getAuthByRouter(context, 'news')) {
  518. NavigatorUtils.push(context, NewsRouter.newsTopList);
  519. }
  520. }
  521. },
  522. child: Container(
  523. width: 40,
  524. height: 21,
  525. alignment: Alignment.center,
  526. decoration: BoxDecoration(
  527. gradient: LinearGradient(colors: [
  528. Color(0xff00ACFF),
  529. Color(0xff568AFF),
  530. ]),
  531. borderRadius: BorderRadius.only(
  532. topLeft: Radius.circular(10),
  533. bottomLeft: Radius.circular(10))),
  534. child: Text(
  535. '更多',
  536. style: TextStyle(
  537. color: Colors.white,
  538. fontSize: 11,
  539. ),
  540. )),
  541. ))
  542. ]);
  543. Widget loadCircle() {
  544. return Container(
  545. padding: EdgeInsets.only(top: 10, bottom: 10),
  546. color: ThemeUtils.getTabsBg(context),
  547. child: Center(
  548. child: SpinKitFadingCircle(
  549. color: Colors.blueAccent,
  550. size: 30.0,
  551. ),
  552. ),
  553. );
  554. }
  555. @override
  556. NewsListPresenter createPresenter() {
  557. return NewsListPresenter();
  558. }
  559. bool get wantKeepAlive => true;
  560. }
  561. class _ToolsItem extends StatelessWidget {
  562. _ToolsItem(this.titles, this.imgs, this.onTap, {Key key}) : super(key: key);
  563. final List<String> titles;
  564. final List<String> imgs;
  565. final Function onTap;
  566. @override
  567. Widget build(BuildContext context) {
  568. return GridView.builder(
  569. shrinkWrap: true,
  570. padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
  571. physics: NeverScrollableScrollPhysics(),
  572. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  573. crossAxisCount: 5, childAspectRatio: 0.9, crossAxisSpacing: 2),
  574. itemCount: titles.length,
  575. itemBuilder: (_, index) {
  576. return InkWell(
  577. child: Column(
  578. mainAxisAlignment: MainAxisAlignment.center,
  579. children: <Widget>[
  580. Image.asset(ImageUtils.getImgPath(imgs[index])),
  581. Expanded(
  582. child: Text(
  583. titles[index],
  584. style: TextStyle(fontSize: ScreenUtil().setSp(12)),
  585. )),
  586. ],
  587. ),
  588. onTap: () {
  589. onTap(index);
  590. },
  591. );
  592. },
  593. );
  594. }
  595. }