flutter_integrated_whb/lib/pages/home/home_page.dart

506 lines
15 KiB
Dart
Raw Normal View History

2025-07-11 11:03:21 +08:00
import 'dart:async';
2025-07-15 08:32:50 +08:00
import 'dart:convert';
2025-07-11 11:03:21 +08:00
import 'dart:ffi';
import 'package:flutter/material.dart';
import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart';
import 'package:qhd_prevention/pages/home/low_page.dart';
import 'package:qhd_prevention/pages/home/risk/riskControl_page.dart';
import 'package:qhd_prevention/pages/home/userInfo_page.dart';
import 'package:qhd_prevention/pages/home/work/danger_page.dart';
import 'package:qhd_prevention/pages/home/work/danger_wait_list_page.dart';
import 'package:qhd_prevention/pages/home/workSet_page.dart';
2025-07-15 08:32:50 +08:00
import '../../http/ApiService.dart';
2025-07-11 11:03:21 +08:00
import '../../tools/tools.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
2025-07-15 08:32:50 +08:00
final int _eight_work_count = 0;
final int _safetyEnvironmentalInspection = 0;
late final List<Map<String, dynamic>> buttonInfos;
/// 我的工作
List<Map<String, dynamic>> workInfos = [];
2025-07-11 11:03:21 +08:00
final List<Map<String, dynamic>> pcData = [
{
"index": 1,
"detail": {"jiancha": "2", "yinhuan": "20", "yanshou": "4"},
},
{
"index": 2,
"detail": {"jiancha": "4", "yinhuan": "10", "yanshou": "5"},
},
{
"index": 3,
"detail": {"jiancha": "3", "yinhuan": "23", "yanshou": "3"},
},
];
final List<List<String>> tagLabels = [
['', ''],
['', ''],
['', ''],
];
Future<void> _onRefresh() async {
// 模拟网络请求
await Future.delayed(const Duration(seconds: 2));
// 刷新数据逻辑,如 fetchData()
setState(() {
// TODO: 更新数据源
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
onRefresh: _onRefresh,
child: ListView(
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.all(10),
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset('assets/images/banner.jpg', fit: BoxFit.cover),
),
const SizedBox(height: 10),
_buildIconSection(context),
const SizedBox(height: 10),
_buildWorkSection(context),
const SizedBox(height: 10),
ListItemFactory.createBuildSimpleSection("隐患播报"),
const SizedBox(height: 10),
_buildPCDataSection(),
SizedBox(height: 50),
],
),
),
);
}
Widget _buildWorkSection(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// _widgetTopTip(title: "我的工作"),
ListItemFactory.createBuildSimpleSection("我的工作"),
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 10),
child: LayoutBuilder(
builder: (context, constraints) {
const spacing = 10.0;
final totalWidth = constraints.maxWidth;
final itemWidth = (totalWidth - spacing * 2) / 3;
return Wrap(
spacing: spacing,
runSpacing: spacing,
children:
workInfos.map((info) {
return SizedBox(
width: itemWidth,
child: _buildGridItem(
context,
icon: info["icon"]!,
title: info["num"]!,
subtitle: info["detail"]!,
index: info["index"]!,
),
);
}).toList(),
);
},
),
),
],
),
);
}
Widget _buildPCDataSection() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ListItemFactory.createBuildSimpleSection("排查数据"),
...pcData.map(_widgetPCDataItem),
],
),
);
}
2025-07-15 08:32:50 +08:00
/// 定义 item 宽度
double _itemWidth(BuildContext context) {
final screenW = MediaQuery.of(context).size.width;
return (screenW - 20) / 4;
}
Widget _buildIconSection(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Wrap(
runSpacing: 16,
children:
buttonInfos.asMap().entries.map((entry) {
final idx = entry.key;
final info = entry.value;
return _buildIconButton(
context: context,
iconPath: info["icon"] as String,
label: info["title"] as String,
unreadCount: info["unreadCount"] as int,
onPressed: () {
final index = entry.key;
// 你的导航逻辑
if (index == 0) {
pushPage(UserinfoPage(), context);
} else if (index == 1) {
pushPage(WorkSetPage(), context);
} else if (index == 2) {
pushPage(RiskControlPage(), context);
} else if (index == 3) {
pushPage(LowPage(), context);
}
},
);
}).toList(),
),
);
}
2025-07-11 11:03:21 +08:00
Widget _buildIconButton({
2025-07-15 08:32:50 +08:00
required BuildContext context,
required String iconPath,
2025-07-11 11:03:21 +08:00
required String label,
2025-07-15 08:32:50 +08:00
required VoidCallback onPressed,
int unreadCount = 0,
2025-07-11 11:03:21 +08:00
}) {
2025-07-15 08:32:50 +08:00
final w = _itemWidth(context);
2025-07-11 11:03:21 +08:00
return InkWell(
2025-07-15 08:32:50 +08:00
onTap: onPressed,
2025-07-11 11:03:21 +08:00
borderRadius: BorderRadius.circular(8),
2025-07-15 08:32:50 +08:00
child: SizedBox(
width: w,
child: Stack(
clipBehavior: Clip.none,
2025-07-11 11:03:21 +08:00
children: [
2025-07-15 08:32:50 +08:00
/// 中心对齐
Align(
alignment: Alignment.topCenter,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(iconPath, width: 40, height: 40),
const SizedBox(height: 5),
Text(label, style: const TextStyle(fontSize: 14)),
],
),
),
if (unreadCount > 0)
Positioned(
right: -4,
top: -4,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 4,
vertical: 2,
),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
constraints: const BoxConstraints(
minWidth: 16,
minHeight: 16,
),
child: Text(
unreadCount > 99 ? '99+' : '$unreadCount',
style: const TextStyle(
color: Colors.white,
fontSize: 10,
height: 1,
),
textAlign: TextAlign.center,
),
),
),
2025-07-11 11:03:21 +08:00
],
),
),
);
}
// 排查数据列表 item
Widget _widgetPCDataItem(Map<String, dynamic> item) {
final detail = item["detail"] as Map<String, String>;
final values = [detail["jiancha"]!, detail["yinhuan"]!, detail["yanshou"]!];
const labels = ["检查数", "发现隐患数", "已验收隐患数"];
const colors = [Color(0xFF3283FF), Color(0xFFF37B1D), Color(0xFF41B852)];
final int idx = int.tryParse(item["index"].toString())! - 1;
return Padding(
padding: const EdgeInsets.fromLTRB(15, 0, 10, 15),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (var i = 0; i < 3; i++)
Column(
children: [
Text(
values[i],
style: TextStyle(
color: colors[i],
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
Text(
labels[i],
style: TextStyle(color: Colors.black38, fontSize: 15),
),
],
),
Container(
color: idx == 0 ? Colors.red : Colors.blue,
width: 20,
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
tagLabels[idx][0],
style: TextStyle(color: Colors.white, fontSize: 12),
),
Text(
tagLabels[idx][1],
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
),
],
),
SizedBox(height: 10),
Divider(height: 1, color: Colors.black12),
],
),
);
}
// 构建灰色网格项
Widget _buildGridItem(
BuildContext context, {
required String icon,
required String title,
required String subtitle,
required int index,
}) {
return GestureDetector(
onTap: () {
if (index == 1) {
pushPage(DangerPage(), context);
} else if (index == 2) {
pushPage(DangerWaitListPage(DangerType.wait), context);
} else if (index == 3) {
pushPage(DangerWaitListPage(DangerType.expired), context);
2025-07-15 08:32:50 +08:00
} else if (index == 4) {
2025-07-11 11:03:21 +08:00
pushPage(DangerWaitListPage(DangerType.waitAcceptance), context);
2025-07-15 08:32:50 +08:00
} else if (index == 5) {
2025-07-11 11:03:21 +08:00
pushPage(DangerWaitListPage(DangerType.acceptance), context);
}
},
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xfbf9f9ff),
borderRadius: BorderRadius.circular(6),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(icon, width: 35, height: 35),
const SizedBox(width: 15),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
Text(
subtitle,
style: const TextStyle(fontSize: 14, color: Colors.black),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
),
);
}
2025-07-15 08:32:50 +08:00
void initState() {
super.initState();
buttonInfos = [
{
"icon": "assets/icon-apps/home-base.png",
"title": "人员信息",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-rili.png",
"title": "工作安排",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-risk.png",
"title": "风险布控",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-fl.png",
"title": "法律法规",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-gw.png",
"title": "特殊作业",
"unreadCount": _eight_work_count,
},
{
"icon": "assets/icon-apps/home-zdgcgl.jpg",
"title": "重点工程管理",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-cns.png",
"title": "安全承诺",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-study.png",
"title": "学习园地",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/home-base.png",
"title": "安全检查",
"unreadCount": _safetyEnvironmentalInspection,
},
{
"icon": "assets/icon-apps/home-speEquip.jpg",
"title": "设备巡检",
"unreadCount": 0,
},
{
"icon": "assets/icon-apps/safetymeeting.png",
"title": "安全例会",
"unreadCount": 0,
},
];
_fetchData(); // 初始化时请求
}
Future<void> _fetchData() async {
try {
// “我的工作” 数量
final raw = await ApiService.getWork();
// 如果拿到的是 String就 decode如果本来就是 Map就直接用
final Map<String, dynamic> data = raw is String
? json.decode(raw as String) as Map<String, dynamic>
: raw;
final hidCount = data['hidCount'] as Map<String, dynamic>;
print(hidCount);
setState(() {
workInfos = [
{
"icon": "assets/icon-apps/jobico1.png",
"index": 1,
"detail": "待排查",
"num": (hidCount['dpc'] ?? 0).toString(),
},
{
"icon": "assets/icon-apps/jobico2.png",
"index": 2,
"detail": "待整改",
"num": (hidCount['dzg'] ?? 0).toString(),
},
{
"icon": "assets/icon-apps/jobico3.png",
"index": 3,
"detail": "已超期",
"num": (hidCount['ycq'] ?? 0).toString(),
},
{
"icon": "assets/icon-apps/jobico4.png",
"index": 4,
"detail": "待验收",
"num": (hidCount['dys'] ?? 0).toString(),
},
{
"icon": "assets/icon-apps/jobico5.png",
"index": 5,
"detail": "已验收",
"num": (hidCount['yys'] ?? 0).toString(),
},
];
});
// // 特殊作业红点
// final redPointJson = await ApiService.getRedPoint();
// setState(() {
// eightWorkCount =
// int.parse(redPointJson['unreadCount'].toString());
// });
//
// // 安全检查数
// final checkJson =
// await ApiService.getSafetyEnvironmentalInspectionCount();
// setState(() {
// safetyCheckCount =
// int.parse(checkJson['count'].toString());
// });
} catch (e) {
// 出错时可以 Toast 或者在页面上显示错误状态
print('加载首页数据失败:$e');
}
}
2025-07-11 11:03:21 +08:00
}