diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index dce4021..533f5bb 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -9,7 +9,8 @@
-
+
+
createState() => _AppState();
+}
+
+class _AppState extends State {
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
@@ -48,20 +55,11 @@ class App extends StatelessWidget {
fallbackLocale: const Locale('zh', 'CN'),
// 必须设置 fallback 没有该语言时使用
getPages: AppPages.pages,
- initialRoute: _checkIsLogin(),
+ initialRoute: widget.initialRoute,
debugShowCheckedModeBanner: false,
builder: EasyLoading.init(),
);
},
);
}
-
- String _checkIsLogin() {
- var token = SharedPreferencesUtils.getString(CacheKeys.token);
- if (token != null && token.isNotEmpty) {
- return AppRoutes.main;
- } else {
- return AppRoutes.login;
- }
- }
}
diff --git a/lib/base/app_permission.dart b/lib/base/app_permission.dart
index 57a990c..2d02f33 100644
--- a/lib/base/app_permission.dart
+++ b/lib/base/app_permission.dart
@@ -20,4 +20,30 @@ class AppPermission {
}
return true;
}
+
+ static Future requestPermission({
+ required Permission permission,
+ }) async {
+ var status = await permission.request();
+ return status == PermissionStatus.granted;
+ }
+
+ static Future requestNotificationPermission() async {
+ final PermissionStatus status = await Permission.notification.request();
+
+ if (status == PermissionStatus.granted) {
+ print("通知权限已授予");
+ return true;
+ } else if (status == PermissionStatus.denied) {
+ // 第一次被拒绝,可以再次请求
+ return false;
+ } else if (status.isPermanentlyDenied) {
+ // 用户勾选了“不再提示”或被永久拒绝
+ print("权限被永久拒绝,跳转到设置页面");
+ openAppSettings(); // 跳转到应用设置页,手动开启
+ return false;
+ }
+
+ return false;
+ }
}
diff --git a/lib/common/constant/app_images.dart b/lib/common/constant/app_images.dart
new file mode 100644
index 0000000..c464f2d
--- /dev/null
+++ b/lib/common/constant/app_images.dart
@@ -0,0 +1,6 @@
+class AppImages{
+
+ static const String iconOneKeyDoor = 'assets/icon/icon_one_key_door.png';
+ static const String iconOneKeyDoorKey = 'assets/icon/icon_one_key_door_key.png';
+ static const String bgOneKeyDoor = 'assets/images/bg_one_key_door.png';
+}
\ No newline at end of file
diff --git a/lib/flavors.dart b/lib/flavors.dart
index 99d932f..e64b804 100644
--- a/lib/flavors.dart
+++ b/lib/flavors.dart
@@ -32,7 +32,7 @@ class F {
static String get apiHost {
switch (appFlavor) {
case Flavor.skyDev:
- return 'http://192.168.1.136/api';
+ return 'http://10.0.2.2/api';
case Flavor.skyPre:
return 'https://loacl.work.star-lock.cn/api';
case Flavor.skyRelease:
diff --git a/lib/main.dart b/lib/main.dart
index 6bc3646..2606b1a 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -3,6 +3,9 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:starwork_flutter/base/app_initialization.dart';
+import 'package:starwork_flutter/common/constant/cache_keys.dart';
+import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
+import 'package:starwork_flutter/routes/app_routes.dart';
import 'app.dart';
import 'flavors.dart';
@@ -14,5 +17,16 @@ void main() async {
await AppInitialization.initializeApp();
- runApp(const App());
+ var initRoute = await _handleInitialRoute();
+
+ runApp(App(initialRoute: initRoute));
+}
+
+Future _handleInitialRoute() async {
+ var token = await SharedPreferencesUtils.getString(CacheKeys.token);
+ if (token != null && token.isNotEmpty) {
+ return AppRoutes.main;
+ } else {
+ return AppRoutes.login;
+ }
}
diff --git a/lib/views/home/home_controller.dart b/lib/views/home/home_controller.dart
index a7f7638..69c0622 100644
--- a/lib/views/home/home_controller.dart
+++ b/lib/views/home/home_controller.dart
@@ -1,3 +1,5 @@
+import 'package:carousel_slider/carousel_controller.dart';
+import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:starwork_flutter/base/app_permission.dart';
@@ -6,11 +8,39 @@ import 'package:starwork_flutter/base/base_controller.dart';
class HomeController extends BaseController {
final isOpenNotificationPermission = false.obs;
+ var carouselCurrentIndex = 0.obs;
+
+ // 渐变颜色列表
+ final List gradientColors = [
+ const Color(0xFFBFCBEF), // #bfcbef
+ const Color(0xFFECBE9B), // 原来的颜色
+ const Color(0xFFD5F3D5), // 清新绿色
+ const Color(0xFFFFB6C1), // 温柔粉色
+ ];
+
+ // 当前渐变颜色
+ var currentGradientColor = const Color(0xFFBFCBEF).obs;
+
@override
void onInit() async {
super.onInit();
isOpenNotificationPermission.value = await AppPermission.checkPermission(
permission: Permission.notification,
);
+
+ // 监听轮播图切换,更新渐变颜色
+ carouselCurrentIndex.listen((index) {
+ updateGradientColor(index);
+ });
+ }
+
+ // 根据轮播图索引更新渐变颜色
+ void updateGradientColor(int index) {
+ if (index < gradientColors.length) {
+ currentGradientColor.value = gradientColors[index];
+ } else {
+ // 如果索引超出颜色数量,使用模运算轮环
+ currentGradientColor.value = gradientColors[index % gradientColors.length];
+ }
}
}
diff --git a/lib/views/home/home_view.dart b/lib/views/home/home_view.dart
index c43d8cb..e7e120b 100644
--- a/lib/views/home/home_view.dart
+++ b/lib/views/home/home_view.dart
@@ -1,86 +1,200 @@
+import 'package:carousel_slider/carousel_slider.dart';
+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:permission_handler/permission_handler.dart';
import 'package:starwork_flutter/base/app_permission.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 {
const HomeView({super.key});
+ static final GlobalKey _scaffoldKey =
+ GlobalKey();
+
@override
Widget build(BuildContext context) {
- return Scaffold(
- body: SafeArea(
- child: Container(
- width: 1.sw,
- padding: EdgeInsets.symmetric(horizontal: 15.w),
- child: Column(
- children: [
- _buildPageHead(),
- _buildSystemNotificationPermissionRow(),
+ 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: Scaffold(
+ key: _scaffoldKey,
+ backgroundColor: Colors.transparent,
+ body: SafeArea(
+ child: Container(
+ width: 1.sw,
+ padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 4.h),
+ child: Column(
+ children: [
+ // 固定的上半部分
+ _buildPageHead(context),
+ SizedBox(
+ height: 10.h,
+ ),
+ _buildSystemNotificationPermissionRow(),
+
+ // 可滚动的下半部分
+ Expanded(
+ child: SingleChildScrollView(
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ HomeCarouselAreaWidget(
+ carouselCurrentIndex:
+ controller.carouselCurrentIndex,
+ ),
+ HomeTeamNoticeRowWidget(),
+ HomeStatisticsRowWidget(
+ personCount: 12,
+ deviceCount: 1,
+ ),
+ SizedBox(height: 10.h),
+ HomeFunctionListAreaWidget(),
+ SizedBox(
+ height: 10.h,
+ ),
+ HomeOnButtonDoorOpeningWidget(
+ doorList: const [
+ '主门门禁',
+ '车库门禁',
+ '后门门禁',
+ '单元门门禁',
+ ],
+ ),
+ SizedBox(
+ height: 10.h,
+ ),
+ HomeAttendanceChartAreaWidget(),
+ SizedBox(
+ height: 10.h,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ drawer: HomeLeftDrawerWidget(
+ teamList: ['家庭群组', '测试团队1', '测试团队2'],
),
),
),
);
}
- _buildPageHead() {
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Row(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(
- '19104656的互联',
- style: TextStyle(
- fontSize: 18.sp,
- fontWeight: FontWeight.w500,
+ _buildPageHead(BuildContext context) {
+ return GestureDetector(
+ onTap: () {
+ _scaffoldKey.currentState?.openDrawer();
+ },
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ '19104656的互联',
+ style: TextStyle(
+ fontSize: 18.sp,
+ fontWeight: FontWeight.w500,
+ ),
),
- ),
- Icon(
- Icons.arrow_right_rounded,
- size: 24.sp,
- )
- ],
- ),
- Icon(
- Icons.add_circle_outline_rounded,
- size: 24.sp,
- ),
- ],
+ Icon(
+ Icons.arrow_right_rounded,
+ size: 22.sp,
+ )
+ ],
+ ),
+ Icon(
+ Icons.add_circle_outline,
+ size: 22.sp,
+ ),
+ ],
+ ),
);
}
_buildSystemNotificationPermissionRow() {
- return Visibility(
- visible: !controller.isOpenNotificationPermission.value,
- child: Container(
- decoration: const BoxDecoration(
- color: Color(0xFFfdefdf),
- ),
- child: Row(
- children: [
- Text(
- '系统通知未开启,报警消息无法通知'.tr,
- style: TextStyle(
- color: Color(0xFFea8720),
- ),
+ 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),
),
- Container(
- child: Text(
- '去开启'.tr,
+ ),
+ margin: EdgeInsets.symmetric(vertical: 8.h),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ '系统通知未开启,报警消息无法通知'.tr,
style: TextStyle(
- color: Colors.white,
+ 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,
+ ),
+ Icon(
+ Icons.cancel,
+ color: const Color(0xFFEE9846),
+ size: 18.sp,
+ )
+ ],
+ ),
),
),
);
diff --git a/lib/views/home/widget/home_attendance_chart_area_widget.dart b/lib/views/home/widget/home_attendance_chart_area_widget.dart
new file mode 100644
index 0000000..612a5e3
--- /dev/null
+++ b/lib/views/home/widget/home_attendance_chart_area_widget.dart
@@ -0,0 +1,243 @@
+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/common/constant/app_images.dart';
+import 'dart:math' as math;
+
+class HomeAttendanceChartAreaWidget extends StatefulWidget {
+ const HomeAttendanceChartAreaWidget({super.key});
+
+ @override
+ State createState() =>
+ _HomeAttendanceChartAreaWidgetState();
+}
+
+class _HomeAttendanceChartAreaWidgetState
+ extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8.r),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.1),
+ spreadRadius: 1,
+ blurRadius: 4,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ child: Column(
+ children: [
+ _buildTitle(),
+ SizedBox(height: 16.h),
+ _buildContent(),
+ SizedBox(height: 16.h),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildTitle() {
+ return Row(
+ children: [
+ Image.asset(
+ AppImages.iconOneKeyDoor,
+ width: 16.w,
+ height: 16.h,
+ ),
+ SizedBox(width: 8.w),
+ Text(
+ '考勤'.tr,
+ style: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ const Spacer(),
+ Icon(
+ Icons.arrow_forward_ios,
+ size: 14.sp,
+ color: const Color(0xFFBFBFBF),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildContent() {
+ return Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ // 左侧圆形进度图表
+ _buildCircularChart(),
+ SizedBox(width: 24.w),
+ // 右侧统计信息
+ _buildStatistics(),
+ ],
+ );
+ }
+
+ Widget _buildCircularChart() {
+ return SizedBox(
+ width: 80.w,
+ height: 80.w,
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ // 背景圆环
+ CustomPaint(
+ size: Size(80.w, 80.w),
+ painter: CircleProgressPainter(
+ progress: 0.5, // 0% 进度
+ strokeWidth: 8.w,
+ backgroundColor: const Color(0xFFF5F5F5),
+ progressColor: const Color(0xFF4A90E2),
+ ),
+ ),
+ // 中心文字
+ Text(
+ '50%',
+ style: TextStyle(
+ fontSize: 20.sp,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xFF333333),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildStatistics() {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // 今日出勤率
+ Row(
+ children: [
+ Text(
+ '今日出勤率:',
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: const Color(0xFF333333),
+ ),
+ ),
+ Text(
+ '0/14',
+ style: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xFF333333),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 12.h),
+ // 未打卡和迟到统计
+ Row(
+ children: [
+ // 未打卡
+ Row(
+ children: [
+ Text(
+ '未打卡:',
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: const Color(0xFF666666),
+ ),
+ ),
+ Text(
+ '14',
+ style: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xFFFF9500),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(width: 24.w),
+ // 迟到
+ Row(
+ children: [
+ Text(
+ '迟到:',
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: const Color(0xFF666666),
+ ),
+ ),
+ Text(
+ '0',
+ style: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ color: const Color(0xFFFF4D4F),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ );
+ }
+}
+
+// 自定义圆形进度画笔
+class CircleProgressPainter extends CustomPainter {
+ final double progress;
+ final double strokeWidth;
+ final Color backgroundColor;
+ final Color progressColor;
+
+ CircleProgressPainter({
+ required this.progress,
+ required this.strokeWidth,
+ required this.backgroundColor,
+ required this.progressColor,
+ });
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final center = Offset(size.width / 2, size.height / 2);
+ final radius = (size.width - strokeWidth) / 2;
+
+ // 绘制背景圆环
+ final backgroundPaint = Paint()
+ ..color = backgroundColor
+ ..strokeWidth = strokeWidth
+ ..style = PaintingStyle.stroke
+ ..strokeCap = StrokeCap.round;
+
+ canvas.drawCircle(center, radius, backgroundPaint);
+
+ // 绘制进度圆弧
+ if (progress > 0) {
+ final progressPaint = Paint()
+ ..color = progressColor
+ ..strokeWidth = strokeWidth
+ ..style = PaintingStyle.stroke
+ ..strokeCap = StrokeCap.round;
+
+ final sweepAngle = 2 * math.pi * progress;
+ canvas.drawArc(
+ Rect.fromCircle(center: center, radius: radius),
+ -math.pi / 2, // 从顶部开始
+ sweepAngle,
+ false,
+ progressPaint,
+ );
+ }
+ }
+
+ @override
+ bool shouldRepaint(CustomPainter oldDelegate) {
+ return oldDelegate != this;
+ }
+}
diff --git a/lib/views/home/widget/home_carousel_area_widget.dart b/lib/views/home/widget/home_carousel_area_widget.dart
new file mode 100644
index 0000000..41511f4
--- /dev/null
+++ b/lib/views/home/widget/home_carousel_area_widget.dart
@@ -0,0 +1,96 @@
+import 'package:carousel_slider/carousel_slider.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class HomeCarouselAreaWidget extends StatefulWidget {
+ const HomeCarouselAreaWidget({
+ super.key,
+ required this.carouselCurrentIndex,
+ });
+
+ final RxInt carouselCurrentIndex;
+
+ @override
+ State createState() => _HomeCarouselAreaWidgetState();
+}
+
+class _HomeCarouselAreaWidgetState extends State {
+ final List imgList = [
+ 'assets/images/mockImage.jpg',
+ 'assets/images/mockImage.jpg',
+ 'assets/images/mockImage.jpg',
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ CarouselSlider(
+ options: CarouselOptions(
+ height: 68.h,
+ autoPlay: true,
+ autoPlayInterval: const Duration(seconds: 5),
+ autoPlayAnimationDuration: const Duration(milliseconds: 800),
+ viewportFraction: 1.0,
+ onPageChanged: (index, reason) {
+ widget.carouselCurrentIndex.value = index;
+ },
+ ),
+ items: imgList.map(
+ (i) {
+ return Builder(
+ builder: (BuildContext context) {
+ return ClipRRect(
+ borderRadius: BorderRadius.circular(8.0),
+ child: Image.asset(
+ width: double.infinity,
+ height: 68.h,
+ i,
+ fit: BoxFit.fill,
+ ),
+ );
+ },
+ );
+ },
+ ).toList(),
+ ),
+ // 分段横线指示器
+ Positioned(
+ left: 10.w,
+ bottom: 6.h,
+ child: Obx(
+ () => Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: imgList.asMap().entries.map((entry) {
+ int index = entry.key;
+ int length = imgList.length;
+
+ // 判断是否为第一个或最后一个
+ bool isFirst = index == 0;
+ bool isLast = index == length - 1;
+ return Container(
+ width: 8.w,
+ height: 2.0.h,
+ decoration: BoxDecoration(
+ color: widget.carouselCurrentIndex.value == index
+ ? Colors.white
+ : Colors.grey[400],
+ // 精确控制圆角
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(isFirst ? 2.0 : 0),
+ bottomLeft: Radius.circular(isFirst ? 2.0 : 0),
+ topRight: Radius.circular(isLast ? 2.0 : 0),
+ bottomRight: Radius.circular(isLast ? 2.0 : 0),
+ ),
+ ),
+ );
+ }).toList(),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/views/home/widget/home_function_list_area_widget.dart b/lib/views/home/widget/home_function_list_area_widget.dart
new file mode 100644
index 0000000..79dea13
--- /dev/null
+++ b/lib/views/home/widget/home_function_list_area_widget.dart
@@ -0,0 +1,245 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+class HomeFunctionListAreaWidget extends StatefulWidget {
+ HomeFunctionListAreaWidget({super.key});
+
+ @override
+ State createState() =>
+ _HomeFunctionListAreaWidgetState();
+}
+
+class _HomeFunctionListAreaWidgetState extends State
+ with SingleTickerProviderStateMixin {
+ late TabController _tabController;
+
+ @override
+ void initState() {
+ super.initState();
+ _tabController = TabController(length: 6, vsync: this);
+ }
+
+ @override
+ void dispose() {
+ _tabController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 10.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.all(
+ Radius.circular(8.r),
+ ),
+ ),
+ child: Column(
+ children: [
+ _buildTabBar(),
+ SizedBox(height: 12.h),
+ _buildTabBarView(),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildTabBar() {
+ final List functionOptionList = [
+ '人员通行',
+ '考勤',
+ '审批',
+ '可视对讲',
+ '信息发布',
+ '其他应用',
+ ];
+
+ return Row(
+ children: [
+ Expanded(
+ child: TabBar(
+ controller: _tabController,
+ isScrollable: true,
+ labelColor: Colors.black87,
+ unselectedLabelColor: Colors.grey,
+ labelStyle: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ unselectedLabelStyle: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w400,
+ ),
+ indicatorColor: Colors.black87,
+ indicatorWeight: 0.5.h,
+ indicatorSize: TabBarIndicatorSize.label,
+ labelPadding: EdgeInsets.only(right: 16.w),
+ // 只保留右边距,左边紧贴
+ tabAlignment: TabAlignment.start,
+ // 从左边开始排列
+ padding: EdgeInsets.zero,
+ // 移除TabBar的默认内边距
+ dividerColor: Colors.transparent,
+ // 移除灰色下边框
+ tabs: functionOptionList.map((title) => Tab(text: title)).toList(),
+ ),
+ ),
+ // 右侧固定菜单图标
+ Container(
+ padding: EdgeInsets.only(
+ left: 8.w,
+ ),
+ child: GestureDetector(
+ onTap: () {
+ // 处理菜单点击事件
+ print('菜单被点击');
+ },
+ child: Icon(
+ Icons.menu,
+ size: 18.sp,
+ color: Colors.grey[600],
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildTabBarView() {
+ final List functionOptionList = [
+ '人员通行',
+ '考勤',
+ '审批',
+ '可视对讲',
+ '信息发布',
+ '其他应用',
+ ];
+
+ // 每个分类对应的功能列表
+ final Map>> functionData = {
+ '人员通行': [
+ {'icon': Icons.door_front_door, 'title': '门禁管理'},
+ {'icon': Icons.people, 'title': '门禁授权'},
+ {'icon': Icons.access_time, 'title': '一键开门'},
+ {'icon': Icons.card_membership, 'title': '密码开门'},
+ {'icon': Icons.face, 'title': '我的访客'},
+ {'icon': Icons.fingerprint, 'title': '访客统计'},
+ {'icon': Icons.security, 'title': '访客邀约'},
+ ],
+ '考勤': [
+ {'icon': Icons.schedule, 'title': '考勤设置'},
+ {'icon': Icons.assignment, 'title': '审批记录'},
+ {'icon': Icons.broadcast_on_personal, 'title': '广播'},
+ {'icon': Icons.announcement, 'title': '信息发布'},
+ {'icon': Icons.bar_chart, 'title': '统计报表'},
+ {'icon': Icons.calendar_today, 'title': '排班管理'},
+ {'icon': Icons.access_alarm, 'title': '打卡记录'},
+ {'icon': Icons.person_add, 'title': '添加常用'},
+ ],
+ '审批': [
+ {'icon': Icons.approval, 'title': '待审批'},
+ {'icon': Icons.check_circle, 'title': '已审批'},
+ {'icon': Icons.pending, 'title': '审批中'},
+ {'icon': Icons.history, 'title': '审批历史'},
+ {'icon': Icons.rule, 'title': '审批规则'},
+ {'icon': Icons.group, 'title': '审批流程'},
+ {'icon': Icons.notifications, 'title': '审批提醒'},
+ {'icon': Icons.analytics, 'title': '审批统计'},
+ ],
+ '可视对讲': [
+ {'icon': Icons.call, 'title': '对讲设备'},
+ {'icon': Icons.call_received, 'title': '呼叫记录'},
+ {'icon': Icons.video_call, 'title': '视频通话'},
+ {'icon': Icons.volume_up, 'title': '广播通知'},
+ {'icon': Icons.settings_phone, 'title': '设备设置'},
+ {'icon': Icons.group_add, 'title': '群组管理'},
+ {'icon': Icons.record_voice_over, 'title': '语音留言'},
+ {'icon': Icons.emergency, 'title': '紧急呼叫'},
+ ],
+ '信息发布': [
+ {'icon': Icons.campaign, 'title': '发布信息'},
+ {'icon': Icons.list_alt, 'title': '信息列表'},
+ {'icon': Icons.schedule_send, 'title': '定时发布'},
+ {'icon': Icons.group, 'title': '目标群体'},
+ {'icon': Icons.image, 'title': '多媒体'},
+ {'icon': Icons.analytics, 'title': '发布统计'},
+ {'icon': Icons.edit, 'title': '编辑模板'},
+ {'icon': Icons.history, 'title': '发布历史'},
+ ],
+ '其他应用': [
+ {'icon': Icons.apps, 'title': '应用中心'},
+ {'icon': Icons.extension, 'title': '插件管理'},
+ {'icon': Icons.download, 'title': '下载中心'},
+ {'icon': Icons.update, 'title': '应用更新'},
+ {'icon': Icons.settings, 'title': '应用设置'},
+ {'icon': Icons.help, 'title': '帮助中心'},
+ {'icon': Icons.feedback, 'title': '意见反馈'},
+ {'icon': Icons.info, 'title': '关于我们'},
+ ],
+ };
+
+ return SizedBox(
+ height: 100.h, // 设置适合的高度
+ child: TabBarView(
+ controller: _tabController,
+ children: functionOptionList.map((category) {
+ final currentFunctions = functionData[category] ?? [];
+ return GridView.builder(
+ physics: const NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 4,
+ childAspectRatio: 1.6,
+ ),
+ itemCount: currentFunctions.length,
+ itemBuilder: (context, index) {
+ final function = currentFunctions[index];
+ return _buildFunctionItem(
+ icon: function['icon'],
+ title: function['title'],
+ );
+ },
+ );
+ }).toList(),
+ ),
+ );
+ }
+
+ Widget _buildFunctionItem({required IconData icon, required String title}) {
+ return GestureDetector(
+ onTap: () {
+ print('点击了: $title');
+ // 处理功能项点击事件
+ },
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min, // 重要:让Column最小化
+ children: [
+ Icon(
+ icon,
+ size: 20.sp, // 稍微减小图标
+ color: Colors.blue.shade600,
+ ),
+ SizedBox(height: 4.h), // 减少间距
+ Flexible(
+ // 使用Flexible而不是Expanded
+ child: Text(
+ title,
+ style: TextStyle(
+ fontSize: 12.sp, // 稍微减小字体
+ color: Colors.black87,
+ fontWeight: FontWeight.w400,
+ ),
+ textAlign: TextAlign.center,
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/home/widget/home_left_drawer_widget.dart b/lib/views/home/widget/home_left_drawer_widget.dart
new file mode 100644
index 0000000..5661320
--- /dev/null
+++ b/lib/views/home/widget/home_left_drawer_widget.dart
@@ -0,0 +1,280 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+class HomeLeftDrawerWidget extends StatefulWidget {
+ HomeLeftDrawerWidget({
+ super.key,
+ required this.teamList,
+ this.selectedTeam,
+ this.onTeamSelected,
+ });
+
+ final List teamList;
+ final String? selectedTeam;
+ final Function(String)? onTeamSelected;
+
+ @override
+ State createState() => _HomeLeftDrawerWidgetState();
+}
+
+class _HomeLeftDrawerWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Drawer(
+ width: 0.85.sw,
+ shape: const RoundedRectangleBorder(
+ borderRadius: BorderRadius.zero, // 去掉圆角
+ ),
+ child: Container(
+ color: const Color(0xFFF6F7FB),
+ child: SafeArea(
+ child: Column(
+ children: [
+ // 头部标题栏
+ Container(
+ padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ '我的团队',
+ style: TextStyle(
+ fontSize: 18.sp,
+ fontWeight: FontWeight.w600,
+ color: Colors.black,
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ Navigator.pop(context);
+ },
+ child: Container(
+ width: 28.w,
+ height: 28.w,
+ decoration: BoxDecoration(
+ color: Colors.grey[300],
+ shape: BoxShape.circle,
+ ),
+ child: Icon(
+ Icons.refresh,
+ size: 18.sp,
+ color: Colors.grey[600],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+
+ // 团队列表
+ Expanded(
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 16.w),
+ child: ListView.builder(
+ itemCount: widget.teamList.length,
+ itemBuilder: (context, index) {
+ final team = widget.teamList[index];
+ final isSelected = team == widget.selectedTeam;
+
+ return Container(
+ margin: EdgeInsets.only(bottom: 8.h),
+ padding: EdgeInsets.all(16.w),
+ decoration: BoxDecoration(
+ color: isSelected
+ ? const Color(0xFFE3F2FD) // 选中状态:蓝色背景
+ : Colors.white, // 未选中状态:白色背景
+ borderRadius: BorderRadius.circular(12.r),
+ border: isSelected
+ ? Border.all(color: const Color(0xFF2196F3), width: 1)
+ : Border.all(color: Colors.grey[200]!, width: 1),
+ ),
+ child: GestureDetector(
+ onTap: () {
+ // 处理团队选择
+ if (widget.onTeamSelected != null) {
+ widget.onTeamSelected!(team);
+ }
+ },
+ child: Row(
+ children: [
+ // 用户图标
+ Container(
+ width: 40.w,
+ height: 40.w,
+ decoration: BoxDecoration(
+ color: isSelected
+ ? const Color(0xFF2196F3)
+ : Colors.grey[400],
+ borderRadius: BorderRadius.circular(8.r),
+ ),
+ child: Icon(
+ Icons.person,
+ color: Colors.white,
+ size: 24.sp,
+ ),
+ ),
+ SizedBox(width: 12.w),
+
+ // 团队信息
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ team, // 使用teamList中的元素作为团队昵称
+ style: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w500,
+ color: isSelected
+ ? const Color(0xFF2196F3)
+ : Colors.black,
+ ),
+ ),
+ SizedBox(height: 4.h),
+ Row(
+ children: [
+ Icon(
+ isSelected
+ ? Icons.check_circle
+ : Icons.check_circle_outline,
+ size: 14.sp,
+ color: isSelected
+ ? const Color(0xFF2196F3)
+ : Colors.grey[400],
+ ),
+ SizedBox(width: 4.w),
+ Text(
+ isSelected ? '已选中' : '未选中',
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: isSelected
+ ? const Color(0xFF2196F3)
+ : Colors.grey[600],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+
+ // 设置图标
+ GestureDetector(
+ onTap: () {
+ // 处理设置点击事件
+ Navigator.pop(context);
+ },
+ child: Container(
+ padding: EdgeInsets.all(8.w),
+ child: Icon(
+ Icons.settings,
+ size: 20.sp,
+ color: isSelected
+ ? const Color(0xFF2196F3)
+ : Colors.grey[600],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
+ ),
+ ),
+
+ // 底部按钮区域
+ Container(
+ padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h),
+ child: Column(
+ children: [
+ // 创建团队和加入团队按钮
+ Row(
+ children: [
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ // 处理创建团队
+ Navigator.pop(context);
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 12.h),
+ decoration: BoxDecoration(
+ border: Border(
+ right: BorderSide(
+ color: Colors.grey[300]!,
+ width: 0.5,
+ ),
+ ),
+ ),
+ child: Text(
+ '创建团队',
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16.sp,
+ color: Colors.black87,
+ ),
+ ),
+ ),
+ ),
+ ),
+ Expanded(
+ child: GestureDetector(
+ onTap: () {
+ // 处理加入团队
+ Navigator.pop(context);
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 12.h),
+ child: Text(
+ '加入团队',
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16.sp,
+ color: Colors.black87,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+
+ // 分割线
+ Container(
+ margin: EdgeInsets.symmetric(vertical: 8.h),
+ height: 0.5,
+ color: Colors.grey[300],
+ ),
+
+ // 快捷添加我的设备按钮
+ GestureDetector(
+ onTap: () {
+ // 处理快捷添加设备
+ Navigator.pop(context);
+ },
+ child: Container(
+ width: double.infinity,
+ padding: EdgeInsets.symmetric(vertical: 12.h),
+ child: Text(
+ '快捷添加我的设备',
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16.sp,
+ color: Colors.black87,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/views/home/widget/home_one_button_door_opening_widget.dart b/lib/views/home/widget/home_one_button_door_opening_widget.dart
new file mode 100644
index 0000000..aa70ab1
--- /dev/null
+++ b/lib/views/home/widget/home_one_button_door_opening_widget.dart
@@ -0,0 +1,194 @@
+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/common/constant/app_images.dart';
+
+class HomeOnButtonDoorOpeningWidget extends StatefulWidget {
+ final List doorList; // 门禁列表,最多显示4个
+
+ const HomeOnButtonDoorOpeningWidget({
+ super.key,
+ required this.doorList,
+ });
+
+ @override
+ State createState() =>
+ _HomeOnButtonDoorOpeningWidgetState();
+}
+
+class _HomeOnButtonDoorOpeningWidgetState
+ extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8.r),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.1),
+ spreadRadius: 1,
+ blurRadius: 4,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ child: Column(
+ children: [
+ _buildTitle(),
+ SizedBox(height: 4.h),
+ _buildDoorCards(),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildTitle() {
+ return Row(
+ children: [
+ Image.asset(
+ AppImages.iconOneKeyDoor,
+ width: 16.w,
+ height: 16.h,
+ ),
+ SizedBox(width: 8.w),
+ Text(
+ '一键开门'.tr,
+ style: TextStyle(
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ const Spacer(),
+ Icon(
+ Icons.arrow_forward_ios,
+ size: 14.sp,
+ color: const Color(0xFFBFBFBF),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildDoorCards() {
+ // 限制最多4个元素
+ final displayList = widget.doorList.take(4).toList();
+
+ if (displayList.isEmpty) {
+ return const SizedBox.shrink(); // 如果没有数据则不显示
+ }
+
+ List rows = [];
+
+ // 按照每行2个的方式组织数据
+ for (int i = 0; i < displayList.length; i += 2) {
+ List rowChildren = [];
+
+ // 第一个元素
+ rowChildren.add(_buildDoorCard(i, displayList[i]));
+
+ // 第二个元素(如果存在)
+ if (i + 1 < displayList.length) {
+ rowChildren.add(_buildDoorCard(i + 1, displayList[i + 1]));
+ } else {
+ // 如果只有一个元素,添加空白占位
+ rowChildren.add(SizedBox(width: 150.w));
+ }
+
+ rows.add(
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: rowChildren,
+ ),
+ );
+ }
+
+ return Column(
+ children: rows,
+ );
+ }
+
+ Widget _buildDoorCard(int index, String doorName) {
+ return Container(
+ width: 150.w, // 增大宽度以适应一行两个的布局
+ height: 80.h, // 增加高度
+ margin: EdgeInsets.only(top: 12.h),
+ child: Stack(
+ children: [
+ // 背景图片
+ Container(
+ width: 150.w,
+ height: 80.h,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8.r),
+ image: const DecorationImage(
+ image: AssetImage(AppImages.bgOneKeyDoor),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ // 播放按钮
+ Positioned(
+ top: 12.h,
+ right: 12.w,
+ child: Container(
+ width: 20.w,
+ height: 20.w,
+ decoration: BoxDecoration(
+ color: Colors.white.withOpacity(0.5),
+ borderRadius: BorderRadius.circular(8.r),
+ ),
+ child: Icon(
+ Icons.play_arrow_rounded,
+ size: 14.sp,
+ color: const Color(0xFF515057),
+ ),
+ ),
+ ),
+ // 左下角内容
+ Positioned(
+ left: 12.w,
+ top: 8.h,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // 圆形钥匙图标
+ Container(
+ width: 34.w,
+ height: 34.h,
+ decoration: BoxDecoration(
+ color: Colors.black.withOpacity(0.3),
+ shape: BoxShape.circle,
+ ),
+ child: Center(
+ child: Image.asset(
+ AppImages.iconOneKeyDoorKey,
+ width: 18.w,
+ height: 18.h,
+ ),
+ ),
+ ),
+ SizedBox(height: 16.h),
+ // 文本
+ SizedBox(
+ width: 80.w, // 增加文本宽度
+ child: Text(
+ doorName,
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w500,
+ fontSize: 14.sp,
+ ),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/home/widget/home_statistics_row_widget.dart b/lib/views/home/widget/home_statistics_row_widget.dart
new file mode 100644
index 0000000..44b3b7e
--- /dev/null
+++ b/lib/views/home/widget/home_statistics_row_widget.dart
@@ -0,0 +1,128 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class HomeStatisticsRowWidget extends StatelessWidget {
+ final int personCount;
+ final int deviceCount;
+
+ const HomeStatisticsRowWidget({
+ super.key,
+ this.personCount = 0,
+ this.deviceCount = 0,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ children: [
+ _buildStatisticsCard(
+ count: personCount,
+ unit: '人',
+ label: '人员总数',
+ backgroundColor: const Color(0xFFCEF2F5),
+ textColor: const Color(0xFF134347),
+ buttonText: '人员管理',
+ ),
+ SizedBox(width: 8.w), // 卡片之间的间距
+ _buildStatisticsCard(
+ count: deviceCount,
+ unit: '台',
+ label: '设备总数',
+ backgroundColor: const Color(0xFFD4E0FF),
+ textColor: const Color(0xFF172A5B),
+ buttonText: '设备管理',
+ ),
+ ],
+ );
+ }
+
+ Widget _buildStatisticsCard({
+ required int count,
+ required String unit,
+ required String label,
+ required Color backgroundColor,
+ required Color textColor,
+ required String buttonText,
+ }) {
+ return Expanded(
+ // 使用Expanded让卡片自适应宽度
+ child: Container(
+ height: 62.h,
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
+ decoration: BoxDecoration(
+ color: backgroundColor,
+ borderRadius: BorderRadius.circular(8.r),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.grey.withOpacity(0.1),
+ spreadRadius: 1,
+ blurRadius: 4,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // 上半部分:数字 + 单位 + 管理按钮
+ Row(
+ children: [
+ // 数字和单位
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.baseline,
+ // 使用baseline对齐
+ textBaseline: TextBaseline.alphabetic,
+ // 设置文本基线
+ children: [
+ Text(
+ count.toString(),
+ style: TextStyle(
+ fontSize: 20.sp, // text-5
+ fontWeight: FontWeight.bold,
+ color: textColor,
+ ),
+ ),
+ Text(
+ unit,
+ style: TextStyle(
+ fontSize: 12.sp, // text-3
+ color: textColor,
+ ),
+ ),
+ ],
+ ),
+ const Spacer(),
+ // 管理按钮
+ Container(
+ padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 4.h),
+ decoration: BoxDecoration(
+ color: Colors.white.withOpacity(0.5),
+ borderRadius: BorderRadius.circular(4.r),
+ ),
+ child: Text(
+ buttonText,
+ style: TextStyle(
+ fontSize: 10.sp, // text-2.5
+ fontWeight: FontWeight.w600,
+ color: textColor,
+ ),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 4.h), // mt-1
+ // 下半部分:标签
+ Text(
+ label,
+ style: TextStyle(
+ fontSize: 10.sp, // text-2.5
+ color: textColor,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/views/home/widget/home_team_notice_row_widget.dart b/lib/views/home/widget/home_team_notice_row_widget.dart
new file mode 100644
index 0000000..bb48a0f
--- /dev/null
+++ b/lib/views/home/widget/home_team_notice_row_widget.dart
@@ -0,0 +1,101 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class HomeTeamNoticeRowWidget extends StatefulWidget {
+ const HomeTeamNoticeRowWidget({super.key});
+
+ @override
+ State createState() => _HomeTeamNoticeRowWidgetState();
+}
+
+class _HomeTeamNoticeRowWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.symmetric(vertical: 10.h),
+ alignment: Alignment.center,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.all(
+ Radius.circular(8.r),
+ ),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.h),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ RichText(
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: '团队'.tr,
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ TextSpan(
+ text: '公告'.tr,
+ style: TextStyle(
+ color: Colors.red,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ WidgetSpan(
+ alignment: PlaceholderAlignment.middle,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: 10.w),
+ child: Icon(
+ Icons.brightness_1,
+ size: 6.sp,
+ ),
+ ),
+ ),
+ TextSpan(
+ text: '公告标题'.tr,
+ style: TextStyle(
+ color: Colors.black,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w400,
+ ),
+ ),
+ ],
+ ),
+ ),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ RichText(
+ text: TextSpan(
+ children: [
+ TextSpan(
+ text: '全部'.tr,
+ style: TextStyle(
+ color: Colors.grey,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w400,
+ ),
+ ),
+ ],
+ ),
+ ),
+ SizedBox(
+ width: 4.w,
+ ),
+ Icon(
+ Icons.arrow_forward_ios_rounded,
+ color: Colors.grey,
+ size: 12.sp,
+ )
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/views/login/inputVerificationCode/input_verification_code_controller.dart b/lib/views/login/inputVerificationCode/input_verification_code_controller.dart
index e933f29..a5f8cf1 100644
--- a/lib/views/login/inputVerificationCode/input_verification_code_controller.dart
+++ b/lib/views/login/inputVerificationCode/input_verification_code_controller.dart
@@ -70,12 +70,29 @@ class InputVerificationCodeController extends BaseController {
}
// 校验验证码
- void checkVerificationCode(String pin) {
+ void checkVerificationCode(String pin) async {
if (previousRoute.value.contains(AppRoutes.login)) {
- Get.offAllNamed(AppRoutes.main);
+ showLoading();
+ var validationCodeLoginResult = await userApi.validationCodeLogin(
+ request: ValidationCodeLoginRequest(
+ platId: int.parse(PlatformType.app.value),
+ phone: rawPhone.value,
+ verificationCode: pin,
+ ),
+ );
+ if (validationCodeLoginResult.isSuccess) {
+ await SharedPreferencesUtils.setString(
+ CacheKeys.token,
+ validationCodeLoginResult.data!.token,
+ );
+ Get.offAllNamed(AppRoutes.main);
+ } else {
+ showError(message: validationCodeLoginResult.errorMsg!);
+ }
} else if (previousRoute.value.contains(AppRoutes.forgotPassword)) {
Get.toNamed(AppRoutes.setNewPassword);
}
+ hideLoading();
}
void _handleSeedVerificationCode({
diff --git a/pubspec.lock b/pubspec.lock
index 37d5265..beb4685 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -33,6 +33,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
+ carousel_slider:
+ dependency: "direct main"
+ description:
+ name: carousel_slider
+ sha256: bcc61735345c9ab5cb81073896579e735f81e35fd588907a393143ea986be8ff
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.1.1"
characters:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index adfa556..eb8960a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -34,6 +34,8 @@ dependencies:
flutter_spinkit: 5.2.1
# 骨架屏
skeletonizer: ^1.4.3
+ # 轮播图
+ carousel_slider: ^5.1.1
dev_dependencies:
@@ -45,4 +47,8 @@ dev_dependencies:
flutter:
uses-material-design: true
+ assets:
+ - assets/images/
+ - assets/logo/
+ - assets/icon/