From c55216d90c63b27cc897763ae71dab2fb857dab1 Mon Sep 17 00:00:00 2001 From: datang Date: Wed, 1 Jun 2022 16:46:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=80=9A=E7=9F=A5=E5=85=AC?= =?UTF-8?q?=E5=91=8A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/build.gradle | 74 ++++----- lib/models/message/notice_model.dart | 73 +++++++++ lib/models/message/notice_model.g.dart | 17 +++ lib/new_ui/new_home/new_home_page.dart | 31 ++-- lib/ui/home/messages/announce_card.dart | 113 ++++++++++++++ lib/ui/home/messages/announce_view.dart | 194 ++++++++++++++++++++++++ lib/ui/home/messages/notice_page.dart | 22 +++ pubspec.lock | 7 + pubspec.yaml | 2 + 9 files changed, 482 insertions(+), 51 deletions(-) create mode 100644 lib/models/message/notice_model.dart create mode 100644 lib/models/message/notice_model.g.dart create mode 100644 lib/ui/home/messages/announce_card.dart create mode 100644 lib/ui/home/messages/announce_view.dart create mode 100644 lib/ui/home/messages/notice_page.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 4b781de..453ed67 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -27,10 +27,10 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystoreProperties = new Properties() - def keystorePropertiesFile = rootProject.file('key.properties') - if (keystorePropertiesFile.exists()) { - keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) - } +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} android { compileSdkVersion 31 @@ -48,51 +48,53 @@ android { minSdkVersion 21 targetSdkVersion 29 ndk { - abiFilters 'arm64-v8a' - abiFilters 'armeabi-v7a' + abiFilters 'arm64-v8a' + abiFilters 'armeabi-v7a' } manifestPlaceholders = [ - JPUSH_PKGNAME : applicationId, - JPUSH_APPKEY : "028adb7b9eda661fefdf3072", //极光开发平台上注册的包名对应的appkey. - JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可. + JPUSH_PKGNAME: applicationId, + JPUSH_APPKEY : "028adb7b9eda661fefdf3072", //极光开发平台上注册的包名对应的appkey. + JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可. ] versionCode flutterVersionCode.toInteger() versionName flutterVersionName } signingConfigs { - release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } - } - buildTypes { - release { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + buildTypes { + release { minifyEnabled true useProguard true multiDexEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig signingConfigs.release - } - debug { - minifyEnabled true - useProguard true - multiDexEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + ndk { abiFilters "armeabi" } + signingConfig signingConfigs.release - signingConfig signingConfigs.release - } - profile{ - minifyEnabled true - useProguard true - multiDexEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + debug { + minifyEnabled true + useProguard true + multiDexEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + ndk { abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86" } + signingConfig signingConfigs.release + } + profile { + minifyEnabled true + useProguard true + multiDexEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig signingConfigs.release - } - } + signingConfig signingConfigs.release + } + } } flutter { @@ -101,7 +103,7 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - // implementation platform('com.google.firebase:firebase-bom:27.0.0') + // implementation platform('com.google.firebase:firebase-bom:27.0.0') //implementation 'com.google.firebase:firebase-analytics' implementation 'com.amap.api:3dmap:latest.integration' implementation 'com.amap.api:location:5.2.0' diff --git a/lib/models/message/notice_model.dart b/lib/models/message/notice_model.dart new file mode 100644 index 0000000..e11906b --- /dev/null +++ b/lib/models/message/notice_model.dart @@ -0,0 +1,73 @@ +import 'package:common_utils/common_utils.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:equatable/equatable.dart'; + +part 'notice_model.g.dart'; + + +@JsonSerializable() +class NoticeModel extends Equatable { + final int id; + final int type; + final int status; + final String title; + final String content; + final String sendDate; + final int jumpId; + + DateTime? get sendDateDT => DateUtil.getDateTime(sendDate); + + int? get month => sendDateDT?.month; + + int? get year => sendDateDT?.year; + + factory NoticeModel.fromJson(Map json) => + _$NoticeModelFromJson(json); + + const NoticeModel({ + required this.id, + required this.type, + required this.status, + required this.title, + required this.content, + required this.sendDate, + required this.jumpId, + }); + + @override + List get props => + [id, type, status, title, content, sendDate, jumpId]; + + Map toMap() { + return { + 'id': this.id, + 'type': this.type, + 'status': this.status, + 'title': this.title, + 'content': this.content, + 'sendDate': this.sendDate, + 'jumpId': this.jumpId, + }; + } + + NoticeModel copyWith({ + int? id, + int? type, + int? status, + String? title, + String? content, + String? sendDate, + int? jumpId, + }) { + return NoticeModel( + id: id ?? this.id, + type: type ?? this.type, + content: content ?? this.content, + sendDate: sendDate ?? this.sendDate, + status: status ?? this.status, + title: title ?? this.title, + jumpId: jumpId ?? this.jumpId, + + ); + } +} \ No newline at end of file diff --git a/lib/models/message/notice_model.g.dart b/lib/models/message/notice_model.g.dart new file mode 100644 index 0000000..220e929 --- /dev/null +++ b/lib/models/message/notice_model.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'notice_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +NoticeModel _$NoticeModelFromJson(Map json) => NoticeModel( + id: ['id'] as int, + type: ['type'] as int, + status: ['status'] as int, + title: ['title'] as String, + content: ['content'] as String, + sendDate: ['sendDate'] as String, + jumpId: ['jumpId'] as int, +); \ No newline at end of file diff --git a/lib/new_ui/new_home/new_home_page.dart b/lib/new_ui/new_home/new_home_page.dart index 12b1845..4ee01aa 100644 --- a/lib/new_ui/new_home/new_home_page.dart +++ b/lib/new_ui/new_home/new_home_page.dart @@ -18,6 +18,8 @@ import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:velocity_x/velocity_x.dart'; +import '../../ui/home/messages/announce_view.dart'; +import '../../ui/home/messages/notice_page.dart'; import 'application_util.dart'; import 'home_swiper.dart'; @@ -89,21 +91,20 @@ class _NewHomePageState extends State { ), ), 24.w.widthBox, - //TODO:暂时隐藏 消息中心待做 - // SizedBox( - // height: 40.w, - // width: 40.w, - // child: IconButton( - // padding:EdgeInsets.zero, - // onPressed: () { - // Get.to(() => Message()); - // }, - // icon: Icon( - // CupertinoIcons.bell, - // size: 40.w, - // ), - // ), - // ) + SizedBox( + height: 40.w, + width: 40.w, + child: IconButton( + padding:EdgeInsets.zero, + onPressed: () { + Get.to(() => NoticePage()); + }, + icon: Icon( + CupertinoIcons.bell, + size: 40.w, + ), + ), + ), 24.w.widthBox, ], ), diff --git a/lib/ui/home/messages/announce_card.dart b/lib/ui/home/messages/announce_card.dart new file mode 100644 index 0000000..b61c5a4 --- /dev/null +++ b/lib/ui/home/messages/announce_card.dart @@ -0,0 +1,113 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'package:common_utils/common_utils.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; +import 'package:velocity_x/velocity_x.dart'; +import '../../../models/message/notice_model.dart'; +import 'announce_view.dart'; + +class AnnounceCard extends StatelessWidget { + final ListDateModel modelList; + final int index; + final bool visible; + + const AnnounceCard({ + Key? key, + required this.modelList, + required this.index, + required this.visible, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + !visible + ? SizedBox() + : Container( + padding: EdgeInsets.symmetric(horizontal: 32.w), + alignment: Alignment.centerLeft, + width: double.infinity, + height: 98.w, + child: '${modelList.year}年${modelList.month}月' + .text + .size(36.sp) + .black + .make(), + ), + ...modelList.models + .map((e) => _card(e)) + .toList() + + ], + ); + } + + Widget _card(NoticeModel model) { + return InkWell( + onTap: () { + //Get.to(() => NoticeDetailPage(id: model.id)); + }, + child: Container( + color: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 24.w), + margin: EdgeInsets.only(bottom: 16 .w), + child: Column( + + + + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + + '${DateUtil.formatDateStr(model.sendDate, format: 'dd日 HH:mm')}' + .text + .size(28.sp) + .color(Colors.black.withOpacity(0.25)) + .make(), + 32.w.heightBox, + // Container( + // width: double.infinity, + // height: 258.w, + // clipBehavior: Clip.antiAliasWithSaveLayer, + // decoration: BoxDecoration(borderRadius: BorderRadius.circular(16.w)), + // child: BeeImageNetwork( + // imgs: model.imgList, + // ), + // ), + // 32.w.heightBox, + + '${model.title}'.text.size(36.sp).black.bold.make(), + 32.w.heightBox, + '${model.content}'.text.maxLines(2).ellipsis.size(28.sp).color(Colors.black.withOpacity(0.25)).make(), + 40.w.heightBox, + Container( + height: 72.w, + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: Color(0xFF000000).withOpacity(0.06), + ), + ), + ), + child: Row( + children: [ + '查看详情'.text.size(24.w).color(Colors.black.withOpacity(0.25)).make(), + Spacer(), + Icon( + CupertinoIcons.chevron_right, + size: 20.w, + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/ui/home/messages/announce_view.dart b/lib/ui/home/messages/announce_view.dart new file mode 100644 index 0000000..b3c7306 --- /dev/null +++ b/lib/ui/home/messages/announce_view.dart @@ -0,0 +1,194 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_easyrefresh/easy_refresh.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:scroll_to_index/scroll_to_index.dart'; + +import '../../../const/saas_api.dart'; +import '../../../models/message/notice_model.dart'; +import '../../../utils/network/net_util.dart'; +import 'announce_card.dart'; + +class ListDateModel { + final String month; + final int index; + final String year; + final List models; + + ListDateModel(this.month, this.models, this.index, this.year); +} + +class AnnounceView extends StatefulWidget { + const AnnounceView({ + Key? key, + }) : super(key: key); + + @override + _AnnounceViewState createState() => _AnnounceViewState(); +} + +class _AnnounceViewState extends State { + EasyRefreshController _refreshController = EasyRefreshController(); + late AutoScrollController _autoScrollController; + + List _modelLists = []; + List _innerModelList = []; + String _headMonth = ''; + + void monthListDepart(List models) { + for (var item in models) { + var index = + _modelLists.indexWhere((element) => element.month == item.month); + if (index >= 0) { + _modelLists[index].models.add(item.copyWith()); + } else { + _modelLists.insert( + _modelLists.length, + ListDateModel(item.month.toString(), [item.copyWith()], + _modelLists.length, item.year.toString())); + } + } + } + + int _page = 1; + int _size = 5; + + bool visible(int index) { + if (index == 0) { + return true; + } else if (_modelLists[index].month == _modelLists[index - 1].month) { + return false; + } else { + return true; + } + } + + @override + void initState() { + _autoScrollController = AutoScrollController( + viewportBoundaryGetter: () => + Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.top + 130.w), + axis: Axis.vertical, + ); + + super.initState(); + } + + @override + void dispose() { + _refreshController.dispose(); + _autoScrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: EasyRefresh( + firstRefresh: true, + header: MaterialHeader(), + footer: MaterialFooter(), + scrollController: _autoScrollController, + controller: _refreshController, + onRefresh: () async { + _page = 1; + _modelLists.clear(); + _innerModelList.clear(); + var base = + await NetUtil().getList(SAASAPI.message.messageList, params: { + 'pageNum': _page, + 'size': _size, + 'type': 2, + }); + _innerModelList = + base.rows.map((e) => NoticeModel.fromJson(e)).toList(); + monthListDepart(_innerModelList); + if (_modelLists.isNotEmpty) { + _headMonth = _modelLists[0].month; + } + + setState(() {}); + }, + onLoad: () async { + _page++; + var base = + await NetUtil().getList(SAASAPI.message.messageList, params: { + 'pageNum': _page, + 'size': _size, + 'type': 2, + }); + if (base.total > _modelLists.length) { + _innerModelList = + base.rows.map((e) => NoticeModel.fromJson(e)).toList(); + monthListDepart(_innerModelList); + setState(() {}); + } else { + print('1111111'); + _refreshController.finishLoadCallBack!(noMore: true); + } + }, + child: _modelLists.isEmpty + ? Container() + : ListView.separated( + shrinkWrap: true, + controller: _autoScrollController, + itemBuilder: (context, index) { + return AutoScrollTag( + key: ValueKey(index), + index: index, + controller: _autoScrollController, + child: AnnounceCard( + modelList: _modelLists[index], + index: index, + visible: visible(index), + ), + ); + }, + separatorBuilder: (_, index) => SizedBox(), + // Container( + // padding: EdgeInsets.symmetric(horizontal: 32.w), + // alignment: Alignment.centerLeft, + // width: double.infinity, + // height: 98.w, + // child: _modelLists[index + 1] + // .month + // .text + // .size(36.sp) + // .black + // .make(), + // ), + itemCount: _modelLists.length), + ), + ), + ], + ); + } + + PopupMenuButton _popupMenuButton() { + return PopupMenuButton( + child: Icon( + CupertinoIcons.arrowtriangle_down_fill, + size: 24.w, + ), + itemBuilder: (context) { + return List.generate( + _modelLists.length, + (index) => PopupMenuItem( + child: Text(_modelLists[index].month), + value: _modelLists[index].index, + )); + }, + onSelected: (value) { + _headMonth = _modelLists[value].month; + print(value); + _autoScrollController.scrollToIndex(value, + preferPosition: AutoScrollPosition.end); + setState(() {}); + }, + ); + } +} diff --git a/lib/ui/home/messages/notice_page.dart b/lib/ui/home/messages/notice_page.dart new file mode 100644 index 0000000..567db05 --- /dev/null +++ b/lib/ui/home/messages/notice_page.dart @@ -0,0 +1,22 @@ +import 'package:flutter/cupertino.dart'; +import '../../../style/app_style.dart'; +import '../../widgets/common/aku_scaffold.dart'; +import 'announce_view.dart'; + +class NoticePage extends StatefulWidget { + const NoticePage({Key? key}) : super(key: key); + + @override + _NoticePageState createState() => _NoticePageState(); +} + +class _NoticePageState extends State { + @override + Widget build(BuildContext context) { + return AkuScaffold( + title: '通知公告', + titleStyle: AppStyle().barTitleStyle, + body: AnnounceView() + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 891a805..6b6c743 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -870,6 +870,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.0" + scroll_to_index: + dependency: "direct main" + description: + name: scroll_to_index + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" shelf: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8dc20eb..34b098e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -76,6 +76,8 @@ dependencies: equatable: ^2.0.0 #打开文件 open_file: ^3.2.1 + #跳转索引列表 + scroll_to_index: ^2.1.1 dev_dependencies: flutter_test: