Files
flutterApp/lib/features/home/presentation/widgets/work_params_card.dart

356 lines
12 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fpdart/fpdart.dart' hide State;
import 'package:maibu_satabot_v2/features/devices/domain/entities/device_entity.dart';
import 'package:maibu_satabot_v2/features/devices/domain/usecases/device_work_hostrirty_usecase.dart';
import 'package:maibu_satabot_v2/features/devices/domain/entities/device_run_hostrity_entity.dart';
import 'package:maibu_satabot_v2/features/devices/domain/errors/device_failure.dart';
import '../../../../core/di/injection.dart';
import '../../../devices/presentation/bloc/devices_cubit.dart';
class WorkParamsCard extends StatefulWidget {
const WorkParamsCard({super.key});
@override
State<WorkParamsCard> createState() => _WorkParamsCardState();
}
class _WorkParamsCardState extends State<WorkParamsCard> {
List<DeviceRunStatisticsEntity>? _statistics;
String? _errorMessage;
bool _isLoading = false; // 默认不加载
@override
Widget build(BuildContext context) {
final deviceState = context.watch<DevicesCubit>().state;
final currentDevice = deviceState.selectedDevice;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.02),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 4,
height: 16,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 8),
const Text(
'作业参数',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
],
),
GestureDetector(
onTap: () {
_handleInfoTap(currentDevice); // 包装在同步函数中
}, // 点击事件处理
child: Row(
children: [
Icon(Icons.info, size: 14, color: Colors.grey[400]),
const SizedBox(width: 4),
Text(
'查看详情',
style: TextStyle(fontSize: 12, color: Colors.grey[400]),
),
],
),
),
],
),
const SizedBox(height: 24),
IntrinsicHeight(
child: Row(
children: [
_buildParamItem('作业面积', '0', '亩'), // 默认值
_buildDivider(),
_buildParamItem('作业里程', '0', 'km'),
_buildDivider(),
_buildParamItem('作业时长', '0', 'h'),
],
),
),
],
),
);
}
// 点击事件处理
Future<void> _handleInfoTap(DeviceEntity? currentDevice) async {
print("点击触摸了历史作业");
setState(() {
_isLoading = true; // 开始加载
_errorMessage = null; // 清除错误信息
});
print("开始历史作业");
try {
final useCase = DeviceWorkHostrirty(sl());
print("发送获取历史作业记录开始");
//displayName
final deviceId = currentDevice?.deviceName.toString() ?? '';
final params = BindDeviceParams(deviceId, 'your_device_alias');
final result = await useCase(params);
print("发送获取历史作业记录结束");
result.fold(
(failure) {
setState(() {
_errorMessage = failure.message;
_isLoading = false;
});
},
(data) {
setState(() {
_statistics = data;
_isLoading = false;
});
_showDetailsDialog(context, _statistics!); // 展示弹窗
},
);
} catch (e) {
print("捕获异常: $e");
setState(() {
_errorMessage = '请求失败: $e';
_isLoading = false;
});
}
}
// 弹窗展示详情
// 弹窗展示详情(从底部弹出)
// 弹窗展示详情(从底部弹出,覆盖底部导航栏)
void _showDetailsDialog(
BuildContext context,
List<DeviceRunStatisticsEntity> data,
) {
showModalBottomSheet(
context: context,
isScrollControlled: true, // 支持全屏高度
useRootNavigator: true, // 覆盖底部导航栏
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)), // 顶部圆角
),
builder: (context) {
return Container(
height: MediaQuery.of(context).size.height * 0.75, // 占据屏幕 75% 高度
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 顶部拖拽指示器
Center(
child: Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(2),
),
),
),
const SizedBox(height: 16),
// 标题
const Text(
'历史记录详情',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
const SizedBox(height: 16),
// 内容区域
Expanded(
child: SingleChildScrollView(
child: Column(
children: data.map((item) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.05), // 浅蓝背景
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.blue.withOpacity(0.2),
width: 1,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDetailRow(
Icons.calendar_today,
'开始时间',
item.startTime,
),
_buildDetailRow(
Icons.calendar_today_outlined,
'结束时间',
item.endTime,
),
_buildDetailRow(
Icons.square_foot,
'工作面积',
'${item.workArea} 亩',
),
_buildDetailRow(
Icons.directions_car,
'工作距离',
'${item.distance?.toStringAsFixed(2) ?? '未计算'} km',
),
_buildDetailRow(
Icons.timer,
'花费时间',
'${item.time} 小时',
),
],
),
);
}).toList(),
),
),
),
const SizedBox(height: 16),
// 关闭按钮
Align(
alignment: Alignment.centerRight,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: const Text(
'关闭',
style: TextStyle(color: Colors.white),
),
),
),
],
),
);
},
);
}
// 构建详情行
Widget _buildDetailRow(IconData icon, String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Icon(icon, size: 16, color: Colors.blue),
const SizedBox(width: 8),
Text(
'$label: ',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
Expanded(
child: Text(
value,
style: const TextStyle(fontSize: 14, color: Colors.black54),
),
),
],
),
);
}
// 构建单个参数项
Widget _buildParamItem(String label, String value, String unit) {
return Expanded(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
label == '作业面积'
? Icons.aspect_ratio
: label == '作业里程'
? Icons.local_shipping_outlined
: Icons.access_time,
size: 14,
color: Colors.black38,
),
const SizedBox(width: 4),
Text(
label,
style: const TextStyle(fontSize: 12, color: Colors.black38),
),
],
),
const SizedBox(height: 12),
RichText(
text: TextSpan(
children: [
TextSpan(
text: value,
style: const TextStyle(
fontSize: 28,
fontWeight: FontWeight.w700,
color: Colors.black,
fontFamily: 'Inter',
),
),
TextSpan(
text: ' $unit',
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Colors.black54,
),
),
],
),
),
],
),
);
}
// 垂直分割线
Widget _buildDivider() {
return VerticalDivider(
color: Colors.black.withOpacity(0.05),
thickness: 1,
indent: 10,
endIndent: 10,
);
}
}