fix:调整操作记录中UI(未完成)
This commit is contained in:
parent
477f4f21be
commit
c32f052cb0
11
lib/main/lockDetail/doorLockLog/date_time_extensions.dart
Normal file
11
lib/main/lockDetail/doorLockLog/date_time_extensions.dart
Normal file
@ -0,0 +1,11 @@
|
||||
extension DateTimeExtensions on DateTime {
|
||||
/// 返回一个新的 DateTime,只保留年月日,时间部分设为 00:00:00.000
|
||||
DateTime get withoutTime {
|
||||
return DateTime(year, month, day);
|
||||
}
|
||||
|
||||
/// 判断两个日期是否是同一天(忽略时间)
|
||||
bool isSameDate(DateTime other) {
|
||||
return year == other.year && month == other.month && day == other.day;
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@ import 'package:flutter_blue_plus/flutter_blue_plus.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/apm/apm_helper.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart';
|
||||
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart';
|
||||
@ -235,7 +236,7 @@ class DoorLockLogLogic extends BaseGetXController {
|
||||
lockId: state.keyInfos.value.lockId!,
|
||||
lockEventType: state.dropdownValue.value,
|
||||
pageNo: pageNo,
|
||||
pageSize: int.parse(pageSize),
|
||||
pageSize: 1000,
|
||||
startDate: state.startDate.value,
|
||||
endDate: state.endDate.value);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
|
||||
@ -5,10 +5,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:star_lock/appRouters.dart';
|
||||
import 'package:star_lock/app_settings/app_settings.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_logic.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_state.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/exportRecordDialog/exportRecordDialog_page.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/week_calendar_view.dart';
|
||||
import 'package:star_lock/main/lockDetail/videoLog/videoLog/videoLog_entity.dart';
|
||||
import 'package:star_lock/main/lockDetail/videoLog/widget/full_screenImage_page.dart';
|
||||
import 'package:star_lock/main/lockDetail/videoLog/widget/video_thumbnail_image.dart';
|
||||
@ -97,12 +100,6 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
topAdvancedCalendarWidget(),
|
||||
Divider(
|
||||
height: 1,
|
||||
color: AppColors.greyLineColor,
|
||||
indent: 30.w,
|
||||
endIndent: 30.w,
|
||||
),
|
||||
eventDropDownWidget(),
|
||||
Expanded(child: timeLineView())
|
||||
],
|
||||
@ -152,88 +149,14 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
}
|
||||
}
|
||||
|
||||
// switch (value) {
|
||||
// case "读取记录".tr:
|
||||
// {
|
||||
// logic.mockNetworkDataRequest(isRefresh: true);
|
||||
// }
|
||||
// break;
|
||||
// case '清空记录'.tr:
|
||||
// {
|
||||
// ShowCupertinoAlertView().showClearOperationRecordAlert(
|
||||
// clearClick: () {
|
||||
// logic.clearOperationRecordRequest();
|
||||
// });
|
||||
// }
|
||||
// break;
|
||||
// case '导出记录':
|
||||
// {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) {
|
||||
// return ExportRecordDialog(
|
||||
// onExport: (String filePath) {
|
||||
// Get.toNamed(Routers.exportSuccessPage,
|
||||
// arguments: <String, String>{'filePath': filePath});
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
//顶部日历小部件
|
||||
Widget topAdvancedCalendarWidget() {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return Theme(
|
||||
data: theme.copyWith(
|
||||
textTheme: theme.textTheme.copyWith(
|
||||
titleMedium: theme.textTheme.titleMedium!.copyWith(
|
||||
fontSize: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
bodyLarge: theme.textTheme.bodyLarge!.copyWith(
|
||||
fontSize: 14,
|
||||
color: Colors.black54,
|
||||
),
|
||||
bodyMedium: theme.textTheme.bodyMedium!.copyWith(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
primaryColor: AppColors.mainColor,
|
||||
highlightColor: Colors.yellow,
|
||||
disabledColor: Colors.grey,
|
||||
),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
AdvancedCalendar(
|
||||
controller: state.calendarControllerCustom,
|
||||
events: state.events,
|
||||
weekLineHeight: 48.0,
|
||||
startWeekDay: 1,
|
||||
innerDot: true,
|
||||
keepLineSize: true,
|
||||
calendarTextStyle: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1.3125,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 8.0,
|
||||
right: 8.0,
|
||||
child: Obx(() => Text(
|
||||
'${state.currentSelectDate.value.year}${'年'.tr}${state.currentSelectDate.value.month}${'月'.tr}',
|
||||
style: theme.textTheme.titleMedium!.copyWith(
|
||||
fontSize: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
)),
|
||||
),
|
||||
return Container(
|
||||
margin: EdgeInsets.only(top: 20.h, left: 30.w, bottom: 10.h, right: 20.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildWeekCalendar(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -325,7 +248,8 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'密码'.tr +
|
||||
'开锁'.tr +
|
||||
'(${'昵称'.tr}:${item.username})'+'(${'密码'.tr}:${item.keyboardPwd})';
|
||||
'(${'昵称'.tr}:${item.username})' +
|
||||
'(${'密码'.tr}:${item.keyboardPwd})';
|
||||
case 30:
|
||||
return '${formatTimestampToHHmm(item.operateDate!)} ' +
|
||||
'卡'.tr +
|
||||
@ -622,4 +546,44 @@ class _DoorLockLogPageState extends State<DoorLockLogPage> with RouteAware {
|
||||
}
|
||||
state.ifCurrentScreen.value = false;
|
||||
}
|
||||
|
||||
List<DateTime> getCurrentWeekDates() {
|
||||
final now = DateTime.now();
|
||||
// weekday: 1=周一, 2=周二, ..., 7=周日
|
||||
// 计算距离上一个周日相差的天数
|
||||
// 如果今天是周日,weekday == 7,偏移为 0
|
||||
final int daysSinceSunday = now.weekday % 7; // 周一=1 -> %7=1, 周日=7 -> %7=0
|
||||
|
||||
final List<DateTime> weekDates = [];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
final DateTime day = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day - daysSinceSunday + i, // 从周日开始累加
|
||||
);
|
||||
weekDates.add(day);
|
||||
}
|
||||
|
||||
return weekDates;
|
||||
}
|
||||
|
||||
Widget _buildWeekCalendar() {
|
||||
return Obx(() {
|
||||
final list = state.lockLogItemList.value;
|
||||
final dateSet = list
|
||||
.map((e) => DateTime.fromMillisecondsSinceEpoch(e.operateDate!))
|
||||
.map((dt) => dt.withoutTime) // 转为年月日
|
||||
.toSet(); // 用 Set 提升查找性能
|
||||
AppLog.log('dateSet:${dateSet}');
|
||||
return WeekCalendarView(
|
||||
hasData: (DateTime date) {
|
||||
return dateSet.contains(date.withoutTime);
|
||||
},
|
||||
onDateSelected: (DateTime date) {},
|
||||
onWeekChanged: (DateTime start, DateTime end) {
|
||||
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/doorLockLog_entity.dart';
|
||||
@ -13,10 +12,13 @@ class DoorLockLogState {
|
||||
DoorLockLogState() {
|
||||
keyInfos.value = Get.arguments['keyInfo'];
|
||||
}
|
||||
|
||||
final Rx<DoorLockLogEntity> lockLogEntity = DoorLockLogEntity().obs;
|
||||
final Rx<LockListInfoItemEntity> keyInfos = LockListInfoItemEntity().obs;
|
||||
final RxList<DoorLockLogDataItem> lockLogItemList =
|
||||
<DoorLockLogDataItem>[].obs;
|
||||
final RxList<DoorLockLogDataItem> eventList =
|
||||
<DoorLockLogDataItem>[].obs;
|
||||
final AdvancedCalendarController calendarControllerToday =
|
||||
AdvancedCalendarController.today();
|
||||
final AdvancedCalendarController calendarControllerCustom =
|
||||
@ -26,13 +28,14 @@ class DoorLockLogState {
|
||||
DateTime(2024, 10, 10),
|
||||
];
|
||||
|
||||
final RxInt startDate =
|
||||
DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day)
|
||||
.millisecondsSinceEpoch
|
||||
.obs;
|
||||
// 获取当前月份的第一天 00:00:00.000
|
||||
final RxInt startDate = DateTime(DateTime.now().year, DateTime.now().month, 1)
|
||||
.millisecondsSinceEpoch
|
||||
.obs;
|
||||
|
||||
// 获取当前月份的最后一天 23:59:59.999
|
||||
final RxInt endDate = DateTime(
|
||||
DateTime.now().year, DateTime.now().month, DateTime.now().day + 1)
|
||||
.subtract(const Duration(milliseconds: 1))
|
||||
DateTime.now().year, DateTime.now().month + 1, 0, 23, 59, 59, 999)
|
||||
.millisecondsSinceEpoch
|
||||
.obs;
|
||||
|
||||
|
||||
220
lib/main/lockDetail/doorLockLog/week_calendar_view.dart
Normal file
220
lib/main/lockDetail/doorLockLog/week_calendar_view.dart
Normal file
@ -0,0 +1,220 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:star_lock/app_settings/app_colors.dart';
|
||||
import 'package:star_lock/main/lockDetail/doorLockLog/date_time_extensions.dart';
|
||||
|
||||
class WeekCalendarView extends StatefulWidget {
|
||||
// 用于判断某一天是否有数据(激活状态)
|
||||
final bool Function(DateTime date)? hasData;
|
||||
final void Function(DateTime date)? onDateSelected; // 新增:选中日期回调
|
||||
final void Function(DateTime start, DateTime end)? onWeekChanged;
|
||||
|
||||
const WeekCalendarView({
|
||||
Key? key,
|
||||
this.hasData,
|
||||
this.onDateSelected,
|
||||
this.onWeekChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_WeekCalendarViewState createState() => _WeekCalendarViewState();
|
||||
}
|
||||
|
||||
class _WeekCalendarViewState extends State<WeekCalendarView> {
|
||||
final PageController _pageController = PageController(initialPage: 500);
|
||||
int _currentPage = 500;
|
||||
|
||||
// 当前选中的日期(以 DateTime 格式存储)
|
||||
late DateTime _selectedDate;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedDate = DateTime.now().withoutTime; // 默认选中今天
|
||||
}
|
||||
|
||||
// 获取指定 page 对应的一周日期
|
||||
List<DateTime> _getWeekDatesForPage(int page) {
|
||||
final now = DateTime.now();
|
||||
final baseSunday =
|
||||
DateTime(now.year, now.month, now.day - (now.weekday % 7));
|
||||
final daysOffset = (page - 500) * 7;
|
||||
final targetSunday = baseSunday.add(Duration(days: daysOffset));
|
||||
return List.generate(
|
||||
7,
|
||||
(i) => DateTime(
|
||||
targetSunday.year, targetSunday.month, targetSunday.day + i));
|
||||
}
|
||||
|
||||
// 判断是否为今天
|
||||
bool _isToday(DateTime date) {
|
||||
final now = DateTime.now();
|
||||
return date.year == now.year &&
|
||||
date.month == now.month &&
|
||||
date.day == now.day;
|
||||
}
|
||||
|
||||
// 判断是否为选中日期
|
||||
bool _isSelected(DateTime date) {
|
||||
return date.year == _selectedDate.year &&
|
||||
date.month == _selectedDate.month &&
|
||||
date.day == _selectedDate.day;
|
||||
}
|
||||
|
||||
// 判断是否有数据(激活状态)
|
||||
bool _hasData(DateTime date) {
|
||||
return widget.hasData?.call(date.withoutTime) ?? false;
|
||||
}
|
||||
|
||||
void _onDateSelected(DateTime date) {
|
||||
setState(() {
|
||||
_selectedDate = date.withoutTime;
|
||||
});
|
||||
// 触发回调,通知父组件
|
||||
widget.onDateSelected?.call(date);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 当前周范围提示
|
||||
_buildWeekRangeLabel(_currentPage),
|
||||
|
||||
SizedBox(height: 10.h),
|
||||
|
||||
SizedBox(
|
||||
height: 100.h,
|
||||
child: PageView.builder(
|
||||
controller: _pageController,
|
||||
itemCount: 1000,
|
||||
itemBuilder: (context, page) {
|
||||
final weekDates = _getWeekDatesForPage(page);
|
||||
return Row(
|
||||
children: weekDates.asMap().entries.map((entry) {
|
||||
final int index = entry.key;
|
||||
final DateTime date = entry.value;
|
||||
final bool isSelected = _isSelected(date);
|
||||
final bool hasData = _hasData(date);
|
||||
final bool isToday = _isToday(date);
|
||||
|
||||
// 确定文字颜色
|
||||
Color textColor;
|
||||
if (isSelected) {
|
||||
textColor = Colors.white; // 选中时文字为白色
|
||||
} else if (hasData) {
|
||||
textColor = Colors.black; // 有数据:黑色
|
||||
} else if (isToday) {
|
||||
textColor = Colors.black; // 今天:黑色
|
||||
} else {
|
||||
textColor = Colors.grey; // 默认:灰色
|
||||
}
|
||||
|
||||
// 确定背景颜色
|
||||
Color? bgColor;
|
||||
if (isSelected) {
|
||||
bgColor = AppColors.mainColor; // 选中用主题色
|
||||
}
|
||||
// 其他状态无背景
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => _onDateSelected(date),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(4.w),
|
||||
width: 75.w,
|
||||
height: 75.w,
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: BorderRadius.circular(50.r),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
[
|
||||
'简写周日',
|
||||
'简写周一',
|
||||
'简写周二',
|
||||
'简写周三',
|
||||
'简写周四',
|
||||
'简写周五',
|
||||
'简写周六'
|
||||
][index]
|
||||
.tr,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: textColor,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
date.day.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 26.sp,
|
||||
color: textColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
if (isToday && !isSelected) // 今天但未选中
|
||||
SizedBox(height: 2.h),
|
||||
if (isToday && !isSelected)
|
||||
Container(
|
||||
width: 6.w,
|
||||
height: 6.w,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.mainColor,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
_currentPage = page;
|
||||
});
|
||||
// ✅ 获取当前页对应的周的起止日期
|
||||
final dates = _getWeekDatesForPage(page);
|
||||
final startOfWeek = dates.first;
|
||||
final endOfWeek = dates.last;
|
||||
|
||||
// ✅ 触发回调,可用于请求接口
|
||||
widget.onWeekChanged?.call(startOfWeek, endOfWeek);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWeekRangeLabel(int page) {
|
||||
final dates = _getWeekDatesForPage(page);
|
||||
final start = dates[0];
|
||||
final end = dates[6];
|
||||
|
||||
String label;
|
||||
|
||||
if (start.year == end.year) {
|
||||
// 同一年:显示为 "2025年8月18日 - 8月24日"
|
||||
label =
|
||||
'${start.year}${'年'.tr}${start.month}${'月'.tr}${start.day}${'日'.tr} - ${end.month}${'月'.tr}${end.day}${'日'.tr}';
|
||||
} else {
|
||||
// 跨年:显示为 "2024年12月31日 - 2025年1月6日"
|
||||
label =
|
||||
'${start.year}${'年'.tr}${start.month}${'月'.tr}${start.day}${'日'.tr} - ${end.year}${'年'.tr}${end.month}${'月'.tr}${end.day}${'日'.tr}';
|
||||
}
|
||||
|
||||
return Text(
|
||||
label,
|
||||
style: TextStyle(fontSize: 24.sp, fontWeight: FontWeight.w600),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user