添加通知公告功能

master
戴余标 2 years ago
parent 4061860309
commit c55216d90c

@ -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()) {
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
}
android {
compileSdkVersion 31
@ -52,9 +52,9 @@ android {
abiFilters 'armeabi-v7a'
}
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_PKGNAME: applicationId,
JPUSH_APPKEY : "028adb7b9eda661fefdf3072", //appkey.
JPUSH_CHANNEL : "developer-default", //.
JPUSH_CHANNEL: "developer-default", //.
]
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@ -74,17 +74,19 @@ android {
useProguard true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ndk { abiFilters "armeabi" }
signingConfig signingConfigs.release
}
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{
profile {
minifyEnabled true
useProguard true
multiDexEnabled true

@ -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<String, dynamic> 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<Object?> get props =>
[id, type, status, title, content, sendDate, jumpId];
Map<String, dynamic> 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,
);
}
}

@ -0,0 +1,17 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'notice_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
NoticeModel _$NoticeModelFromJson(Map<String, dynamic> 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,
);

@ -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<NewHomePage> {
),
),
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,
],
),

@ -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,
)
],
),
),
],
),
),
);
}
}

@ -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<NoticeModel> 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<AnnounceView> {
EasyRefreshController _refreshController = EasyRefreshController();
late AutoScrollController _autoScrollController;
List<ListDateModel> _modelLists = [];
List<NoticeModel> _innerModelList = [];
String _headMonth = '';
void monthListDepart(List<NoticeModel> 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(() {});
},
);
}
}

@ -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<NoticePage> {
@override
Widget build(BuildContext context) {
return AkuScaffold(
title: '通知公告',
titleStyle: AppStyle().barTitleStyle,
body: AnnounceView()
);
}
}

@ -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:

@ -76,6 +76,8 @@ dependencies:
equatable: ^2.0.0
#打开文件
open_file: ^3.2.1
#跳转索引列表
scroll_to_index: ^2.1.1
dev_dependencies:
flutter_test:

Loading…
Cancel
Save