notice_list.dart 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. import 'dart:async';
  2. import 'dart:math';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_screenutil/flutter_screenutil.dart';
  6. import 'package:flutter_slidable/flutter_slidable.dart';
  7. import 'package:liftmanager/internal/means/means_router.dart';
  8. import 'package:liftmanager/internal/search/presenter/base_list_provider.dart';
  9. import 'package:liftmanager/internal/wode/model/message_model.dart';
  10. import 'package:liftmanager/internal/wode/presenter/notice_list_presenter.dart';
  11. import 'package:liftmanager/mvp/base_page_state.dart';
  12. import 'package:liftmanager/net/api_service.dart';
  13. import 'package:liftmanager/res/iconfont.dart';
  14. import 'package:liftmanager/res/resources.dart';
  15. import 'package:liftmanager/routers/fluro_navigator.dart';
  16. import 'package:liftmanager/utils/fast_notification.dart';
  17. import 'package:liftmanager/utils/theme_utils.dart';
  18. import 'package:liftmanager/utils/toast.dart';
  19. import 'package:liftmanager/widgets/app_bar.dart';
  20. import 'package:liftmanager/widgets/my_refresh_list.dart';
  21. import 'package:liftmanager/widgets/popup_window.dart';
  22. import 'package:provider/provider.dart';
  23. import 'package:umeng_common_sdk/umeng_common_sdk.dart';
  24. class NoticeList extends StatefulWidget {
  25. @override
  26. NoticeListState createState() => NoticeListState();
  27. }
  28. class NoticeListState extends BasePageState<NoticeList, NoticeListPresenter> {
  29. BaseListProvider<Records> provider = BaseListProvider<Records>();
  30. int _page = 1;
  31. GlobalKey _addKey = GlobalKey();
  32. List<String> idList;
  33. @override
  34. void dispose() {
  35. UmengCommonSdk.onPageEnd("通知消息");
  36. super.dispose();
  37. }
  38. Future changeNoticeState(List<String> ids) async {
  39. await NewApiService().markMessagesRead(ids, onSuccess: (res) {
  40. String initThisNotice = randomInt(1111, 9999).toString() +
  41. DateTime.now().millisecondsSinceEpoch.toString();
  42. FastNotification.push("initNotice", initThisNotice);
  43. showToast('标记已读成功');
  44. _onRefresh();
  45. setState(() {});
  46. }, onError: (code, msg) {
  47. toasts(msg);
  48. });
  49. }
  50. Future removeNotificationMessages(List<String> ids) async {
  51. await NewApiService().removeAllMessage(ids, 4, onSuccess: (res) {
  52. showToast('删除成功');
  53. _onRefresh();
  54. setState(() {});
  55. }, onError: (code, msg) {
  56. toasts(msg);
  57. });
  58. }
  59. randomInt(int min, int max) {
  60. return new Random().nextInt(max) % (max - min + 1) + min;
  61. }
  62. @override
  63. void initState() {
  64. UmengCommonSdk.onPageStart("通知消息");
  65. super.initState();
  66. _onRefresh();
  67. }
  68. @override
  69. Widget build(BuildContext context) {
  70. double width = MediaQuery.of(context).size.width;
  71. return ChangeNotifierProvider<BaseListProvider<Records>>(
  72. create: (_) => provider,
  73. child: Scaffold(
  74. // resizeToAvoidBottomPadding: true,
  75. appBar: MyAppBar(
  76. centerTitle: "通知消息",
  77. actions: [
  78. IconButton(
  79. key: _addKey,
  80. icon: Icon(Iconfont.gengduo22),
  81. onPressed: () {
  82. _showAddMenu(context);
  83. })
  84. ],
  85. ),
  86. body: Container(
  87. color: Color(0xffF6F6F6),
  88. padding: EdgeInsets.all(10),
  89. child: Column(
  90. crossAxisAlignment: CrossAxisAlignment.start,
  91. children: <Widget>[
  92. Expanded(
  93. flex: 1,
  94. child: Consumer<BaseListProvider<Records>>(
  95. builder: (_, provider, __) {
  96. idList = provider.list.map((e) => e.id).toList();
  97. return MyListView(
  98. key: Key('notice_list'),
  99. itemCount: provider.list.length,
  100. stateType: provider.stateType,
  101. onRefresh: _onRefresh,
  102. loadMore: _loadMore,
  103. pageSize: 15,
  104. hasMore: provider.hasMore,
  105. itemBuilder: (_, index) {
  106. return Container(
  107. margin: EdgeInsets.only(bottom: 10),
  108. child: Slidable(
  109. key: UniqueKey(),
  110. actionPane: SlidableDrawerActionPane(),
  111. actionExtentRatio: 0.2,
  112. secondaryActions: <Widget>[
  113. Container(
  114. color: Color(0xffF94F45),
  115. alignment: Alignment.center,
  116. child: GestureDetector(
  117. onTap: () {
  118. removeNotificationMessages(
  119. [provider.list[index].id]);
  120. },
  121. child: Text(
  122. '删除',
  123. style: TextStyle(
  124. fontSize: 14, color: Colors.white),
  125. ),
  126. ),
  127. )
  128. ],
  129. child: InkWell(
  130. child: Container(
  131. padding: EdgeInsets.symmetric(
  132. horizontal: 10, vertical: 15),
  133. decoration: BoxDecoration(
  134. color: Colors.white,
  135. border: Border(
  136. bottom: BorderSide(
  137. width: 0.5, color: Colours.line),
  138. ),
  139. ),
  140. child: Row(
  141. crossAxisAlignment:
  142. CrossAxisAlignment.start,
  143. children: <Widget>[
  144. if (provider.list[index].viewFlag ==
  145. 0)
  146. Container(
  147. margin: EdgeInsets.only(top: 5),
  148. child: ClipRRect(
  149. borderRadius:
  150. BorderRadius.circular(3),
  151. child: Container(
  152. width: 6,
  153. height: 6,
  154. color: Colors.red)),
  155. ),
  156. SizedBox(width: 10),
  157. Expanded(
  158. child: Column(children: <Widget>[
  159. Row(
  160. mainAxisAlignment:
  161. MainAxisAlignment
  162. .spaceBetween,
  163. children: <Widget>[
  164. Text(
  165. "通知消息",
  166. textAlign: TextAlign.left,
  167. style: TextStyle(
  168. fontSize: 14,
  169. color: Color(0xff333333),
  170. ),
  171. ),
  172. Text(
  173. provider.list[index]
  174. .createTime ??
  175. "",
  176. textAlign: TextAlign.left,
  177. style: TextStyle(
  178. fontSize: 12,
  179. color: Color(0xffCCCCCC),
  180. ),
  181. ),
  182. ],
  183. ),
  184. SizedBox(
  185. height: 5,
  186. ),
  187. Row(
  188. mainAxisAlignment:
  189. MainAxisAlignment
  190. .spaceBetween,
  191. children: <Widget>[
  192. Container(
  193. width: width * 0.7,
  194. child: Text(
  195. provider.list[index]
  196. .content ??
  197. "",
  198. textAlign: TextAlign.left,
  199. style: TextStyle(
  200. fontSize: 13,
  201. color: Color(0xff999999),
  202. ),
  203. overflow:
  204. TextOverflow.ellipsis,
  205. ),
  206. ),
  207. ],
  208. ),
  209. ])),
  210. ]),
  211. ),
  212. onTap: () {
  213. changeNoticeState(
  214. [provider.list[index].id]);
  215. },
  216. )),
  217. );
  218. },
  219. );
  220. }))
  221. ],
  222. ),
  223. ),
  224. ));
  225. }
  226. Future _onRefresh() async {
  227. _page = 1;
  228. await presenter.getWalletList(_page);
  229. }
  230. Future _loadMore() async {
  231. _page++;
  232. await presenter.getWalletList(_page);
  233. }
  234. @override
  235. NoticeListPresenter createPresenter() {
  236. return NoticeListPresenter();
  237. }
  238. _showAddMenu(BuildContext context) {
  239. final RenderBox button = _addKey.currentContext.findRenderObject();
  240. final RenderBox overlay = Overlay.of(context).context.findRenderObject();
  241. var a = button.localToGlobal(
  242. Offset(button.size.width - 8.0, button.size.height - 12.0),
  243. ancestor: overlay);
  244. var b = button.localToGlobal(button.size.bottomLeft(Offset(0, -12.0)),
  245. ancestor: overlay);
  246. final RelativeRect position = RelativeRect.fromRect(
  247. Rect.fromPoints(a, b),
  248. Offset.zero & overlay.size,
  249. );
  250. final Color backgroundColor = ThemeUtils.getBackgroundColor(context);
  251. showPopupWindow(
  252. context: context,
  253. fullWidth: false,
  254. isShowBg: true,
  255. position: position,
  256. elevation: 2,
  257. child: GestureDetector(
  258. onTap: () => NavigatorUtils.goBack(context),
  259. child: Container(
  260. width: 120,
  261. decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
  262. child: Column(
  263. crossAxisAlignment: CrossAxisAlignment.center,
  264. children: <Widget>[
  265. // Container(
  266. // height: 10,
  267. // width: 10,
  268. // margin: EdgeInsets.only(bottom: 5),
  269. // child: Transform.rotate(
  270. // angle: -45 * pi / 180,
  271. // child: CustomPaint(
  272. // painter: _ShapesPainter(Color(0xffE4ECFF)),
  273. // size: Size(10, 10),
  274. // ),
  275. // ),
  276. // ),
  277. SizedBox(
  278. // width: 120.0,
  279. height: 40.0,
  280. child: FlatButton.icon(
  281. textColor: Color(0xff333333),
  282. onPressed: () {
  283. Navigator.pop(context);
  284. if (idList != null) {
  285. changeNoticeState(idList);
  286. }
  287. },
  288. color: backgroundColor,
  289. shape: RoundedRectangleBorder(
  290. borderRadius: BorderRadius.only(
  291. topLeft: Radius.circular(8.0),
  292. topRight: Radius.circular(8.0)),
  293. ),
  294. icon: Icon(Iconfont.yidu),
  295. label: const Text("一键已读")),
  296. ),
  297. Divider(),
  298. SizedBox(
  299. // width: 120.0,
  300. height: 40.0,
  301. child: FlatButton.icon(
  302. textColor: Color(0xff333333),
  303. color: backgroundColor,
  304. onPressed: () {
  305. Navigator.pop(context);
  306. if (idList != null) {
  307. removeNotificationMessages(idList);
  308. }
  309. },
  310. shape: RoundedRectangleBorder(
  311. borderRadius: BorderRadius.only(
  312. bottomLeft: Radius.circular(8.0),
  313. bottomRight: Radius.circular(8.0)),
  314. ),
  315. icon: Icon(Iconfont.yijianqingkong),
  316. label: const Text("一键清空")),
  317. ),
  318. ],
  319. ),
  320. ),
  321. ),
  322. );
  323. }
  324. }
  325. class _ShapesPainter extends CustomPainter {
  326. final Color color;
  327. _ShapesPainter(this.color);
  328. @override
  329. void paint(Canvas canvas, Size size) {
  330. final paint = Paint();
  331. paint.color = color;
  332. var path = Path();
  333. path.lineTo(size.width, 0);
  334. path.lineTo(size.height, size.width);
  335. path.close();
  336. canvas.drawPath(path, paint);
  337. }
  338. @override
  339. bool shouldRepaint(CustomPainter oldDelegate) => false;
  340. }
  341. class NoticeWidget extends StatelessWidget {
  342. NoticeWidget({Key key, this.list}) : super(key: key);
  343. List<dynamic> list;
  344. List<Widget> listWidget(context) => list.map((i) {
  345. return InkWell(
  346. child: Container(
  347. padding: EdgeInsets.only(
  348. left: ScreenUtil().setWidth(15),
  349. right: ScreenUtil().setWidth(15),
  350. top: ScreenUtil().setWidth(10),
  351. bottom: ScreenUtil().setWidth(10)),
  352. decoration: BoxDecoration(
  353. border: Border(
  354. bottom: BorderSide(width: 0.5, color: Colours.line),
  355. ),
  356. ),
  357. child: Row(
  358. crossAxisAlignment: CrossAxisAlignment.center,
  359. children: <Widget>[
  360. Container(
  361. padding: EdgeInsets.only(right: ScreenUtil().setWidth(10)),
  362. child: ClipRRect(
  363. borderRadius:
  364. BorderRadius.circular(ScreenUtil().setWidth(18)),
  365. child: Container(
  366. width: ScreenUtil().setWidth(36),
  367. height: ScreenUtil().setWidth(36),
  368. decoration: BoxDecoration(
  369. gradient: const LinearGradient(
  370. colors: [Color(0xFF00D9FF), Color(0xFF0287FF)]),
  371. ),
  372. // padding: EdgeInsets.only(right:10),
  373. child: Icon(
  374. IconData(i.type == "system" ? 0xe609 : 0xe62f,
  375. fontFamily: "Iconfont"),
  376. size: 24.0,
  377. color: Colors.white,
  378. ),
  379. ),
  380. ),
  381. ),
  382. Expanded(
  383. child: Column(children: <Widget>[
  384. Row(
  385. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  386. children: <Widget>[
  387. Text(
  388. i.type != null ? "系统消息" : "客服消息",
  389. textAlign: TextAlign.left,
  390. style: TextStyle(
  391. fontSize: ScreenUtil().setSp(16),
  392. color: Color(0xff000000),
  393. ),
  394. ),
  395. Text(
  396. i.createTime,
  397. textAlign: TextAlign.left,
  398. style: TextStyle(
  399. fontSize: ScreenUtil().setSp(14),
  400. color: Color(0xff999999),
  401. ),
  402. ),
  403. ],
  404. ),
  405. Row(
  406. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  407. children: <Widget>[
  408. Text(
  409. i.content,
  410. textAlign: TextAlign.left,
  411. style: TextStyle(
  412. fontSize: ScreenUtil().setSp(13),
  413. color: Color(0xff999999),
  414. ),
  415. ),
  416. i.viewFlag != 0
  417. ? ClipRRect(
  418. borderRadius: BorderRadius.circular(3),
  419. child: Container(
  420. child: null,
  421. width: 6,
  422. height: 6,
  423. color: Colors.red))
  424. : Container(child: null)
  425. ],
  426. ),
  427. ])),
  428. ]),
  429. ),
  430. onTap: () {
  431. print(i);
  432. NavigatorUtils.push(context, MeansRouter.errorDetail);
  433. },
  434. );
  435. }).toList();
  436. @override
  437. Widget build(BuildContext context) {
  438. return Container(
  439. color: Colors.white,
  440. child: Column(children: listWidget(context)),
  441. );
  442. }
  443. }