381 lines
12 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:starwork_flutter/base/app_permission.dart';
import 'package:starwork_flutter/common/constant/app_view_parameter_keys.dart';
import 'package:starwork_flutter/routes/app_routes.dart';
import 'package:starwork_flutter/views/home/widget/home_not_device_area.dart';
import 'package:super_tooltip/super_tooltip.dart';
import 'package:starwork_flutter/views/home/widget/home_attendance_chart_area_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_carousel_area_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_function_list_area_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_left_drawer_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_one_button_door_opening_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_statistics_row_widget.dart';
import 'package:starwork_flutter/views/home/widget/home_team_notice_row_widget.dart';
import 'home_controller.dart';
class HomeView extends GetView<HomeController> {
HomeView({super.key});
// 气泡提示框控制器
final SuperTooltipController _tooltipController = SuperTooltipController();
@override
Widget build(BuildContext context) {
return Obx(
() => Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter, // 渐变起点:顶部中心
end: Alignment.bottomCenter, // 渐变终点:底部中心
colors: [
controller.currentGradientColor.value, // 动态颜色
const Color(0xFFF6F7FB), // 底部颜色保持不变
],
stops: const [0.1, 1.0], // 第一个颜色到10%然后第二个颜色开始直到100%
),
),
child: SafeArea(
child: Container(
width: 1.sw,
padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 4.h),
child: Column(
children: [
// 固定的上半部分
_buildPageHead(context),
Obx(
() => Visibility(
visible: controller.isOpenNotificationPermission.value,
child: SizedBox(
height: 10.h,
),
),
),
_buildSystemNotificationPermissionRow(),
// 可滚动的下半部分(带下拉刷新)
Expanded(
child: _buildRefreshableContent(),
),
],
),
),
),
),
);
}
_buildPageHead(BuildContext context) {
return GestureDetector(
onTap: () {
// 使用MainController的专用方法
controller.mainController.openDrawer();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
controller.mainController.selectedTeam.value.teamName ?? '----------------',
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.w500,
),
),
Icon(
Icons.arrow_right_rounded,
size: 22.sp,
),
],
),
SuperTooltip(
controller: _tooltipController,
popupDirection: TooltipDirection.down,
backgroundColor: Colors.white,
borderColor: Colors.transparent,
borderWidth: 0,
borderRadius: 8.0,
arrowLength: 8.0,
arrowBaseWidth: 12.0,
arrowTipDistance: 14.0.h,
hasShadow: false,
shadowColor: Colors.black26,
shadowBlurRadius: 8.0,
shadowSpreadRadius: 2.0,
touchThroughAreaShape: ClipAreaShape.rectangle,
barrierColor: Colors.transparent,
content: _buildTooltipContent(),
child: GestureDetector(
onTap: () {
_tooltipController.showTooltip();
},
child: Icon(
Icons.add_circle_outline,
size: 22.sp,
),
),
),
],
),
);
}
_buildSystemNotificationPermissionRow() {
return Obx(
() => Visibility(
visible: !controller.isOpenNotificationPermission.value,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h),
decoration: BoxDecoration(
color: const Color(0xFFFEF2E5),
borderRadius: BorderRadius.all(
Radius.circular(8.r),
),
),
margin: EdgeInsets.symmetric(vertical: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'系统通知未开启,报警消息无法通知'.tr,
style: TextStyle(
color: const Color(0xFFEE9846),
fontSize: 12.sp,
),
),
const Spacer(),
GestureDetector(
onTap: () async {
controller.isOpenNotificationPermission.value = await AppPermission.requestNotificationPermission();
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 4.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(4.r),
),
),
child: Text(
'去开启'.tr,
style: TextStyle(
color: const Color(0xFFEE9846),
fontSize: 12.sp,
),
),
),
),
SizedBox(
width: 14.w,
),
GestureDetector(
onTap: () {
controller.isOpenNotificationPermission.value = true;
},
child: Icon(
Icons.cancel,
color: const Color(0xFFEE9846),
size: 18.sp,
),
)
],
),
),
),
);
}
// 带下拉刷新的内容区域
Widget _buildRefreshableContent() {
return RefreshIndicator(
onRefresh: _onRefresh,
// 基础样式配置
color: const Color(0xFF4A90E2),
// 刷新指示器颜色
backgroundColor: Colors.white,
// 背景颜色
// 控制下拉触发距离的关键属性
displacement: 60.0,
// 刷新指示器距离顶部的距离
edgeOffset: 0.0,
// 边缘偏移量
// 控制下拉幅度的关键属性
triggerMode: RefreshIndicatorTriggerMode.onEdge,
// 触发模式
// 描边宽度
strokeWidth: 2.5,
// 刷新指示器的描边宽度
// 语义标签(用于无障碍功能)
semanticsLabel: '下拉刷新首页内容',
semanticsValue: '刷新中...',
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(
// 添加弹性滚动效果
parent: BouncingScrollPhysics(),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
HomeCarouselAreaWidget(
carouselCurrentIndex: controller.carouselCurrentIndex,
),
Visibility(
child: SizedBox(height: 10.h),
visible: controller.mainController.deviceCountSize.value == 0,
),
Visibility(
visible: controller.mainController.deviceCountSize.value == 0,
child: HomeNotDeviceArea(),
),
HomeTeamNoticeRowWidget(),
HomeStatisticsRowWidget(
personCount: controller.mainController.selectedTeamDetails.value.personCount ?? 0,
deviceCount: controller.mainController.deviceCountSize.value,
),
SizedBox(height: 10.h),
HomeFunctionListAreaWidget(),
SizedBox(height: 10.h),
HomeOnButtonDoorOpeningWidget(
doorList: const [
'主门门禁',
'车库门禁',
'后门门禁',
'单元门门禁',
],
),
SizedBox(height: 10.h),
HomeAttendanceChartAreaWidget(),
SizedBox(height: 10.h),
],
),
),
);
}
// 处理下拉刷新
Future<void> _onRefresh() async {
// 调用controller的刷新方法
await controller.refreshHome();
}
/// 构建气泡提示框内容
Widget _buildTooltipContent() {
final List<Map<String, dynamic>> menuItems = [
{
'title': '搜索设备',
'icon': Icons.sensors_rounded,
'onTap': () => _handleMenuTap(0),
},
{
'title': '邀请人员',
'icon': Icons.group_add,
'onTap': () => _handleMenuTap(1),
},
];
return Container(
width: 100.w,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: menuItems.asMap().entries.map((entry) {
final index = entry.key;
final item = entry.value;
return _buildMenuItem(
title: item['title'],
icon: item['icon'],
onTap: item['onTap'],
isLast: index == menuItems.length - 1,
);
}).toList(),
),
);
}
/// 构建单个菜单项
Widget _buildMenuItem({
required String title,
required IconData icon,
required VoidCallback onTap,
required bool isLast,
}) {
return GestureDetector(
onTap: () {
_tooltipController.hideTooltip();
onTap();
},
child: Container(
padding: EdgeInsets.all(8.w),
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
border: !isLast
? const Border(
bottom: BorderSide(
color: Colors.grey,
width: 0.5,
),
)
: null,
),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
icon,
size: 18.sp,
color: Colors.black87,
),
SizedBox(
width: 8.w,
),
Flexible(
child: Text(
title,
style: TextStyle(
fontSize: 14.sp,
color: Colors.black87,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
],
),
),
);
}
/// 处理菜单点击事件
void _handleMenuTap(int menuIndex) {
switch (menuIndex) {
case 0:
Get.toNamed(AppRoutes.searchDevice);
break;
case 1:
Get.toNamed(AppRoutes.teamInviteTeamMember, arguments: {
AppViewParameterKeys.teamInfo: controller.mainController.selectedTeam.value.toJson(),
});
break;
}
}
}