notice_list.dart 18 KB

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