diff --git a/lib/const/api.dart b/lib/const/api.dart index da8ab70..b03ef1a 100644 --- a/lib/const/api.dart +++ b/lib/const/api.dart @@ -38,4 +38,10 @@ class _User { class _Manage { ///报事报修:查询 维修部组织信息及人员 String get fixers => '/user/repair/findRepairOrganization'; + + ///活动管理:管家app 查询所有的活动管理信息 + String get acitivityList => '/user/activity/list'; + + ///活动管理:管家app 根据活动管理主键id查询活动详情 + String get activityDetail => '/user/activity/findById'; } diff --git a/lib/models/manager/activity_detail_model.dart b/lib/models/manager/activity_detail_model.dart new file mode 100644 index 0000000..b2747ad --- /dev/null +++ b/lib/models/manager/activity_detail_model.dart @@ -0,0 +1,66 @@ +import 'package:aku_community_manager/models/common/img_model.dart'; +import 'package:common_utils/common_utils.dart'; + +class ActivityDetailModel { + int id; + String title; + String content; + String activityStartTime; + String activityEndTime; + String location; + String registrationEndTime; + List imgUrls; + ImgModel get firstImg { + if (imgUrls.isEmpty) + return null; + else + return imgUrls.first; + } + + DateTime get registrationEnd => DateUtil.getDateTime(registrationEndTime); + + DateTime get activityStart => DateUtil.getDateTime(activityStartTime); + + DateTime get activityEnd => DateUtil.getDateTime(activityEndTime); + + ActivityDetailModel( + {this.id, + this.title, + this.content, + this.activityStartTime, + this.activityEndTime, + this.location, + this.registrationEndTime, + this.imgUrls}); + + ActivityDetailModel.fromJson(Map json) { + id = json['id']; + title = json['title']; + content = json['content']; + activityStartTime = json['activityStartTime']; + activityEndTime = json['activityEndTime']; + location = json['location']; + registrationEndTime = json['registrationEndTime']; + if (json['imgUrls'] != null) { + imgUrls = new List(); + json['imgUrls'].forEach((v) { + imgUrls.add(new ImgModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['title'] = this.title; + data['content'] = this.content; + data['activityStartTime'] = this.activityStartTime; + data['activityEndTime'] = this.activityEndTime; + data['location'] = this.location; + data['registrationEndTime'] = this.registrationEndTime; + if (this.imgUrls != null) { + data['imgUrls'] = this.imgUrls.map((v) => v.toJson()).toList(); + } + return data; + } +} diff --git a/lib/models/manager/activity_item_model.dart b/lib/models/manager/activity_item_model.dart new file mode 100644 index 0000000..52f0738 --- /dev/null +++ b/lib/models/manager/activity_item_model.dart @@ -0,0 +1,67 @@ +import 'package:aku_community_manager/models/common/img_model.dart'; +import 'package:common_utils/common_utils.dart'; + +class ActivityItemModel { + int id; + String title; + String sponsorName; + String location; + String registrationStartTime; + String registrationEndTime; + String createDate; + List imgUrls; + + ImgModel get firstImg { + if (imgUrls.isEmpty) + return null; + else + return imgUrls.first; + } + + DateTime get create => DateUtil.getDateTime(createDate); + + DateTime get registrationStart => DateUtil.getDateTime(registrationStartTime); + + DateTime get registrationEnd => DateUtil.getDateTime(registrationEndTime); + + ActivityItemModel( + {this.id, + this.title, + this.sponsorName, + this.location, + this.registrationStartTime, + this.registrationEndTime, + this.createDate, + this.imgUrls}); + + ActivityItemModel.fromJson(Map json) { + id = json['id']; + title = json['title']; + sponsorName = json['sponsorName']; + location = json['location']; + registrationStartTime = json['registrationStartTime']; + registrationEndTime = json['registrationEndTime']; + createDate = json['createDate']; + if (json['imgUrls'] != null) { + imgUrls = new List(); + json['imgUrls'].forEach((v) { + imgUrls.add(new ImgModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['title'] = this.title; + data['sponsorName'] = this.sponsorName; + data['location'] = this.location; + data['registrationStartTime'] = this.registrationStartTime; + data['registrationEndTime'] = this.registrationEndTime; + data['createDate'] = this.createDate; + if (this.imgUrls != null) { + data['imgUrls'] = this.imgUrls.map((v) => v.toJson()).toList(); + } + return data; + } +} diff --git a/lib/ui/sub_pages/activity_manager/activity_detail_page.dart b/lib/ui/sub_pages/activity_manager/activity_detail_page.dart index f6a079a..6522d26 100644 --- a/lib/ui/sub_pages/activity_manager/activity_detail_page.dart +++ b/lib/ui/sub_pages/activity_manager/activity_detail_page.dart @@ -1,19 +1,24 @@ // Flutter imports: +import 'package:aku_community_manager/const/api.dart'; +import 'package:aku_community_manager/models/manager/activity_detail_model.dart'; +import 'package:aku_community_manager/utils/network/base_model.dart'; +import 'package:aku_community_manager/utils/network/net_util.dart'; import 'package:flutter/material.dart'; // Package imports: import 'package:common_utils/common_utils.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:velocity_x/velocity_x.dart'; // Project imports: import 'package:aku_community_manager/style/app_style.dart'; import 'package:aku_community_manager/tools/screen_tool.dart'; import 'package:aku_community_manager/tools/widget_tool.dart'; -import 'package:aku_community_manager/ui/sub_pages/activity_manager/fake_activity_model.dart'; import 'package:aku_community_manager/ui/widgets/common/aku_scaffold.dart'; class ActivityDetailPage extends StatefulWidget { - final FakeActivityManagerModel model; - ActivityDetailPage({Key key, @required this.model}) : super(key: key); + final int id; + ActivityDetailPage({Key key, @required this.id}) : super(key: key); @override _ActivityDetailPageState createState() => _ActivityDetailPageState(); @@ -21,61 +26,73 @@ class ActivityDetailPage extends StatefulWidget { class _ActivityDetailPageState extends State { static const String format = 'yyyy年MM月dd日HH:mm'; + ActivityDetailModel _detailModel; String get startDate => - DateUtil.formatDate(widget.model.dateStart, format: format); + DateUtil.formatDate(_detailModel.activityStart, format: format); String get endDate => - DateUtil.formatDate(widget.model.dateEnd, format: format); + DateUtil.formatDate(_detailModel.activityEnd, format: format); String get checkInDate => - DateUtil.formatDate(widget.model.checkInDate, format: format); + DateUtil.formatDate(_detailModel.registrationEnd, format: format); @override Widget build(BuildContext context) { return AkuScaffold( title: '活动详情', - body: ListView( - children: [ - Hero( - tag: widget.model.title, - child: Image.asset( - widget.model.imgPath, - height: 228.w, - fit: BoxFit.cover, - ), - ), - Padding( - padding: EdgeInsets.symmetric( - vertical: 24.w, - horizontal: 32.w, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - widget.model.title, - style: TextStyle( - color: AppStyle.primaryTextColor, - fontSize: 36.sp, - fontWeight: FontWeight.bold, + body: EasyRefresh( + firstRefresh: true, + header: MaterialHeader(), + onRefresh: () async { + BaseModel model = await NetUtil().get( + API.manage.activityDetail, + params: {'activityId': widget.id}, + ); + _detailModel = ActivityDetailModel.fromJson(model.data); + setState(() {}); + }, + child: _detailModel == null + ? SizedBox() + : ListView( + children: [ + FadeInImage.assetNetwork( + placeholder: R.ASSETS_PLACEHOLDER_WEBP, + image: _detailModel.firstImg?.url ?? '', + fit: BoxFit.cover, ), - ), - AkuBox.h(16), - Text( - widget.model.article, - style: TextStyle( - color: AppStyle.primaryTextColor, - fontSize: 28.sp, + Padding( + padding: EdgeInsets.symmetric( + vertical: 24.w, + horizontal: 32.w, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _detailModel.title, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 36.sp, + fontWeight: FontWeight.bold, + ), + ), + AkuBox.h(16), + Text( + _detailModel.content, + style: TextStyle( + color: AppStyle.primaryTextColor, + fontSize: 28.sp, + ), + ), + AkuBox.h(40), + _buildTile('开始时间', startDate), + _buildTile('结束时间', endDate), + _buildTile('地点', _detailModel.location), + _buildTile('参与人数', '不限'), + _buildTile('报名截止', checkInDate), + ], + ), ), - ), - AkuBox.h(40), - _buildTile('开始时间', startDate), - _buildTile('结束时间', endDate), - _buildTile('地点', widget.model.location), - _buildTile('参与人数', widget.model.people), - _buildTile('报名截止', checkInDate), - ], - ), - ), - ], + ], + ), ), ); } diff --git a/lib/ui/sub_pages/activity_manager/activity_manager_card.dart b/lib/ui/sub_pages/activity_manager/activity_manager_card.dart index 06d0891..743b1ab 100644 --- a/lib/ui/sub_pages/activity_manager/activity_manager_card.dart +++ b/lib/ui/sub_pages/activity_manager/activity_manager_card.dart @@ -1,4 +1,6 @@ // Flutter imports: +import 'package:aku_community_manager/models/manager/activity_item_model.dart'; +import 'package:aku_community_manager/ui/sub_pages/activity_manager/activity_detail_page.dart'; import 'package:flutter/material.dart'; // Package imports: @@ -9,26 +11,21 @@ import 'package:get/route_manager.dart'; import 'package:aku_community_manager/style/app_style.dart'; import 'package:aku_community_manager/tools/screen_tool.dart'; import 'package:aku_community_manager/tools/widget_tool.dart'; -import 'package:aku_community_manager/ui/sub_pages/activity_manager/activity_detail_page.dart'; -import 'package:aku_community_manager/ui/sub_pages/activity_manager/fake_activity_model.dart'; class ActivityManagerCard extends StatelessWidget { + final ActivityItemModel model; + const ActivityManagerCard({Key key, @required this.model}) : super(key: key); String get startDate => - DateUtil.formatDate(model.dateStart, format: 'yyyy-MM-dd'); - + DateUtil.formatDate(model.registrationStart, format: 'yyyy-MM-dd'); String get endDate => - DateUtil.formatDate(model.dateEnd, format: 'yyyy-MM-dd'); - - final FakeActivityManagerModel model; - const ActivityManagerCard({Key key, @required this.model}) : super(key: key); - + DateUtil.formatDate(model.registrationEnd, format: 'yyyy-MM-dd'); @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.symmetric(vertical: 24.w, horizontal: 32.w), child: GestureDetector( onTap: () { - Get.to(ActivityDetailPage(model: model)); + Get.to(ActivityDetailPage(id: model.id)); }, child: Column( mainAxisSize: MainAxisSize.min, @@ -41,8 +38,9 @@ class ActivityManagerCard extends StatelessWidget { width: double.infinity, child: Hero( tag: model.title, - child: Image.asset( - model.imgPath, + child: FadeInImage.assetNetwork( + placeholder: R.ASSETS_PLACEHOLDER_WEBP, + image: model.firstImg?.url ?? '', fit: BoxFit.cover, ), ), @@ -63,7 +61,7 @@ class ActivityManagerCard extends StatelessWidget { ), ), AkuBox.h(12), - _buildTile('主办方:', model.hostName), + _buildTile('主办方:', model.sponsorName), _buildTile('地点:', model.location), _buildTile('报名时间:', '$startDate\至$endDate'), ], diff --git a/lib/ui/sub_pages/activity_manager/activity_manager_page.dart b/lib/ui/sub_pages/activity_manager/activity_manager_page.dart index 5d67dc6..a28be4f 100644 --- a/lib/ui/sub_pages/activity_manager/activity_manager_page.dart +++ b/lib/ui/sub_pages/activity_manager/activity_manager_page.dart @@ -1,10 +1,14 @@ // Flutter imports: +import 'package:aku_community_manager/const/api.dart'; +import 'package:aku_community_manager/models/manager/activity_item_model.dart'; +import 'package:aku_community_manager/ui/widgets/common/bee_list_view.dart'; +import 'package:aku_community_manager/utils/network/base_list_model.dart'; import 'package:flutter/material.dart'; // Project imports: import 'package:aku_community_manager/ui/sub_pages/activity_manager/activity_manager_card.dart'; -import 'package:aku_community_manager/ui/sub_pages/activity_manager/fake_activity_model.dart'; import 'package:aku_community_manager/ui/widgets/common/aku_scaffold.dart'; +import 'package:flutter_easyrefresh/easy_refresh.dart'; class ActivityManagerPage extends StatefulWidget { ActivityManagerPage({Key key}) : super(key: key); @@ -14,16 +18,27 @@ class ActivityManagerPage extends StatefulWidget { } class _ActivityManagerPageState extends State { + EasyRefreshController _refreshController = EasyRefreshController(); @override Widget build(BuildContext context) { return AkuScaffold( title: '活动管理', - body: ListView.builder( - itemBuilder: (context, index) { - final model = fakeAcitivityManagerModels[index]; - return ActivityManagerCard(model: model); + body: BeeListView( + builder: (List items) { + return ListView.builder( + itemBuilder: (context, index) { + return ActivityManagerCard(model: items[index]); + }, + itemCount: items.length, + ); }, - itemCount: fakeAcitivityManagerModels.length, + controller: _refreshController, + convert: (BaseListModel model) { + return model.tableList + .map((e) => ActivityItemModel.fromJson(e)) + .toList(); + }, + path: API.manage.acitivityList, ), ); } diff --git a/lib/ui/sub_pages/activity_manager/fake_activity_model.dart b/lib/ui/sub_pages/activity_manager/fake_activity_model.dart deleted file mode 100644 index 2d6386a..0000000 --- a/lib/ui/sub_pages/activity_manager/fake_activity_model.dart +++ /dev/null @@ -1,58 +0,0 @@ -// Project imports: -import 'package:aku_community_manager/const/resource.dart'; - -class FakeActivityManagerModel { - String title; - String imgPath; - String location; - String hostName; - - String article; - String people; - - DateTime dateStart; - DateTime dateEnd; - DateTime checkInDate; - FakeActivityManagerModel({ - this.title, - this.imgPath, - this.location, - this.hostName, - this.article, - this.people, - this.dateStart, - this.dateEnd, - this.checkInDate, - }); -} - -List fakeAcitivityManagerModels = [ - FakeActivityManagerModel( - title: '华茂悦峰社区第三届六一亲子活动', - imgPath: R.ASSETS_STATIC_TEMP_F1_WEBP, - location: '中央活动区', - hostName: '深圳万科物业有限公司', - article: - '''为丰富文化体育生活,不断增进小区凝聚力和人与人之间的协作能力,市委政法委机关党办、机关工会联合举办“我参与、我健康、我快乐”系列主题活动。 - 鞋底擦地的沙沙声,拉绳时的呼号声,乘着悠悠暖风奏成一曲夏的交响乐。汗水落地迸溅的瞬间,队员们奋力拼搏的身姿,与融融暖阳,绘成一幅夏的长卷。 - ''', - people: '不限', - dateStart: DateTime(2020, 4, 12, 12, 0), - dateEnd: DateTime(2020, 4, 15, 12, 0), - checkInDate: DateTime(2020, 4, 13, 12, 0), - ), - FakeActivityManagerModel( - title: '宁化社区第一届煎蛋比赛报名开始', - imgPath: R.ASSETS_STATIC_TEMP_F5_WEBP, - location: '中央活动区', - hostName: '深圳万科物业有限公司', - article: - '''为丰富文化体育生活,不断增进小区凝聚力和人与人之间的协作能力,市委政法委机关党办、机关工会联合举办“我参与、我健康、我快乐”系列主题活动。 - 鞋底擦地的沙沙声,拉绳时的呼号声,乘着悠悠暖风奏成一曲夏的交响乐。汗水落地迸溅的瞬间,队员们奋力拼搏的身姿,与融融暖阳,绘成一幅夏的长卷。 - ''', - people: '不限', - dateStart: DateTime(2020, 4, 12, 12, 0), - dateEnd: DateTime(2020, 4, 15, 12, 0), - checkInDate: DateTime(2020, 4, 13, 12, 0), - ), -]; diff --git a/lib/ui/widgets/common/bee_list_view.dart b/lib/ui/widgets/common/bee_list_view.dart new file mode 100644 index 0000000..3eb7287 --- /dev/null +++ b/lib/ui/widgets/common/bee_list_view.dart @@ -0,0 +1,120 @@ +// Flutter imports: +import 'package:aku_community_manager/utils/network/base_list_model.dart'; +import 'package:aku_community_manager/utils/network/net_util.dart'; +import 'package:flutter/material.dart'; + +// Package imports: +import 'package:flutter_easyrefresh/easy_refresh.dart'; + + +/// ## BeeListView +///```dart +///BeeListView( +/// path: API.someAPI, +/// convert: (model) { +/// return model.tableList +/// .map((e) => SomeModel.fromJson(e)) +/// .toList(); +/// }, +/// controller: _refreshController, +/// builder: (items) { +/// return ListView.builder( +/// itemBuilder: (context, index) { +/// return _buildSomeItem(items[index]); +/// }, +/// itemCount: items.length, +/// ); +/// }, +///) +///``` +class BeeListView extends StatefulWidget { + ///API path + final String path; + + ///same as EasyRefreshController + final EasyRefreshController controller; + + ///转换器 + /// + ///BaseListModel to T + /// + ///T is a tableList item. + /// + ///```dart + ///... + ///convert: (model) { + /// return model.tableList + /// .map((e) => SomeModel.fromJson(e)) + /// .toList(); + ///}, + ///... + ///``` + final List Function(BaseListModel model) convert; + + ///子组件构造器 + final Widget Function(List items) builder; + + ///每页记录数 + final int size; + + ///额外的参数 + final Map extraParams; + BeeListView({ + Key key, + @required this.path, + @required this.controller, + @required this.convert, + @required this.builder, + this.size = 10, + this.extraParams, + }) : super(key: key); + + @override + _BeeListViewState createState() => _BeeListViewState(); +} + +class _BeeListViewState extends State { + int _pageNum = 1; + BaseListModel _model = BaseListModel.zero(); + List _models = []; + Map get _params { + Map tempMap = { + 'pageNum': _pageNum, + 'size': widget.size, + }; + tempMap.addAll(widget.extraParams ?? {}); + return tempMap; + } + + @override + Widget build(BuildContext context) { + return EasyRefresh( + controller: widget.controller, + header: MaterialHeader(), + footer: MaterialFooter(), + onRefresh: () async { + _pageNum = 1; + _model = await NetUtil().getList( + widget.path, + params: _params, + ); + _models = widget.convert(_model); + widget.controller?.resetLoadState(); + setState(() {}); + }, + firstRefresh: true, + onLoad: () async { + _pageNum++; + _model = await NetUtil().getList( + widget.path, + params: _params, + ); + _models.addAll(widget.convert(_model) as List); + if (_pageNum >= _model.pageCount) + widget.controller.finishLoad(noMore: true); + setState(() {}); + }, + child: widget.builder(_models), + ); + } +}