机器状态 优化

This commit is contained in:
mmc
2026-03-04 10:09:58 +08:00
parent 34b4c2bcbc
commit d44493b256
2 changed files with 143 additions and 105 deletions

View File

@@ -39,7 +39,7 @@ class AuthCubit extends Cubit<AuthState> {
if (user != null) {
// 1. 建立 TCP 连接 (远程控制)
tcp.connect(host: TCPConsts.TCP_IP, port: TCPConsts.TCP_PORT);
await _authTcpDatasource.sendAuthPacket();//包括发送认证包和获取列表和切换函数
//await _authTcpDatasource.sendAuthPacket();//包括发送认证包和获取列表和切换函数
// 2. 同步全局 App 状态
appCubit.setAuth(user);
// 3. 进入已登录状态

View File

@@ -9,8 +9,8 @@ import '../../../../core/di/injection.dart';
import '../../../../core/network/net_message_dispatcher.dart';
import '../../../../core/network/protocol_decoder.dart';
import '../../../devices/presentation/bloc/devices_cubit.dart';
import '../../../devices/presentation/bloc/device_status_bloc.dart'; // 👈 新增导入
import '../../../devices/presentation/bloc/device_status_state.dart'; // 👈 新增导入
import '../../../devices/presentation/bloc/device_status_bloc.dart';
import '../../../devices/presentation/bloc/device_status_state.dart';
class RunningStatusPage extends StatefulWidget {
const RunningStatusPage({super.key});
@@ -20,18 +20,33 @@ class RunningStatusPage extends StatefulWidget {
}
class _RunningStatusPageState extends State<RunningStatusPage> {
// 视图切换状态
bool _isCardView = true;
// 解析定位质量数值为文字描述
String _parseLocationQuality(int locationValue) {
switch (locationValue) {
case 0:
return '无效';
case 1:
return 'GPS 单点定位';
case 2:
return 'DGPS 伪距差分或 SBAS';
case 4:
return 'RTK 固定解';
case 5:
return 'RTK 浮点解';
default:
return '未知($locationValue)'; // 处理未定义的数值,避免显示空值
}
}
@override
Widget build(BuildContext context) {
final deviceState = context.read<DevicesCubit>().state;
final currentDevice = deviceState.selectedDevice;
if (currentDevice == null) {
return const Scaffold(
body: Center(child: Text("加载中...")),
);
return const Scaffold(body: Center(child: Text("加载中...")));
}
return Scaffold(
@@ -39,7 +54,6 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
body: CustomScrollView(
physics: const BouncingScrollPhysics(),
slivers: [
// 1. 顶部导航栏
SliverAppBar(
backgroundColor: const Color(0xFF1677FF),
pinned: true,
@@ -55,21 +69,21 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
),
),
// 2. 状态信息行(动态更新)- 使用 BlocBuilder 监听
BlocBuilder<DeviceStatusBloc, DeviceStatusState>(
builder: (context, state) {
String yaw = '--';
String qual = '--';
String satelliteCnt = '--';
String headingStatus = "--";
if (state is DeviceStatusUpdated) {
yaw = state.status.yaw.toStringAsFixed(2);
qual = state.status.qual.toString();
headingStatus = state.status.headingStatus == 0 ? '未初始化' : '已初始化';
qual = _parseLocationQuality(state.status.qual);
qual = int.parse(state.status.qual.toString());
satelliteCnt = state.status.satelliteCnt.toString();
} else if (state is DeviceStatusError) {
yaw = '错误';
qual = '-';
satelliteCnt = '-';
headingStatus = '-';
}
return SliverToBoxAdapter(
@@ -79,7 +93,7 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("航向角状态:$yaw°", style: const TextStyle(fontSize: 14)),
Text("航向角状态:$headingStatus", style: const TextStyle(fontSize: 14)),
Text("定位质量:$qual", style: const TextStyle(fontSize: 14)),
Text("卫星数:$satelliteCnt", style: const TextStyle(fontSize: 14)),
],
@@ -89,7 +103,6 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
},
),
// 3. 选项卡 + 刷新按钮
SliverToBoxAdapter(
child: Container(
color: Colors.white,
@@ -98,7 +111,6 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 切换选项卡
Row(
children: [
GestureDetector(
@@ -112,7 +124,6 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
),
],
),
// 刷新按钮
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF1677FF),
@@ -128,16 +139,12 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
),
),
// 4. 内容区域 - 使用 BlocBuilder 监听
SliverFillRemaining(
child: BlocBuilder<DeviceStatusBloc, DeviceStatusState>(
builder: (context, state) {
return Container(
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: _isCardView ? _buildCardContentView(state) : _buildChartContentView(),
);
},
@@ -153,7 +160,7 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
title,
style: TextStyle(
color: isActive ? const Color(0xFF1677FF) : const Color(0xFF666666),
fontSize: 16,
fontSize: 18,
fontWeight: isActive ? FontWeight.bold : FontWeight.normal,
decoration: isActive ? TextDecoration.underline : null,
decorationColor: const Color(0xFF1677FF),
@@ -162,90 +169,123 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
);
}
Widget _buildCardItem(String title, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title, style: const TextStyle(fontSize: 16, color: Color(0xFF333333))),
Text(value, style: const TextStyle(fontSize: 16, color: Color(0xFF666666))),
],
// 电机参数表格
Widget _buildMotorTable(DeviceStatusUpdated state) {
final status = state.status;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Text("电机参数", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
),
Table(
border: TableBorder.all(color: const Color(0xFFE5E5E5)),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(
decoration: const BoxDecoration(color: Color(0xFFF5F5F5)),
children: [const SizedBox(), _buildTableCell("左轮", isHeader: true), _buildTableCell("右轮", isHeader: true)],
),
TableRow(
children: [
_buildTableCell("目标速度\n(rpm)"),
_buildTableCell(status.leftTargetSpeed.toStringAsFixed(2)),
_buildTableCell(status.rightTargetSpeed.toStringAsFixed(2)),
],
),
TableRow(
children: [
_buildTableCell("测量速度\n(rpm)"),
_buildTableCell(status.leftTargetSpeed.toStringAsFixed(2)),
_buildTableCell(status.rightTargetSpeed.toStringAsFixed(2)),
//_buildTableCell(status.leftMeasuredSpeed.toStringAsFixed(2)),
//_buildTableCell(status.rightMeasuredSpeed.toStringAsFixed(2)),
],
),
TableRow(
children: [
_buildTableCell("电流(A)"),
_buildTableCell(status.leftCurrent.toStringAsFixed(2)),
_buildTableCell(status.rightCurrent.toStringAsFixed(2)),
],
),
TableRow(
children: [
_buildTableCell("电机温度(°C)"),
_buildTableCell(status.leftMotorTemp.toStringAsFixed(2)),
_buildTableCell(status.rightMotorTemp.toStringAsFixed(2)),
],
),
],
),
],
);
}
// 其他参数表格
Widget _buildOtherParamsTable(DeviceStatusUpdated state) {
final status = state.status;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Text("其他参数", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
),
Table(
border: TableBorder.all(color: const Color(0xFFE5E5E5)),
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
children: [
TableRow(
decoration: const BoxDecoration(color: Color(0xFFF5F5F5)),
children: [_buildTableCell("名称", isHeader: true), _buildTableCell("数值", isHeader: true)],
),
TableRow(children: [_buildTableCell("俯仰角(°)"), _buildTableCell(status.pitch.toStringAsFixed(2))]),
TableRow(children: [_buildTableCell("翻滚角(°)"), _buildTableCell(status.roll.toStringAsFixed(2))]),
TableRow(children: [_buildTableCell("航向角(°)"), _buildTableCell(status.yaw.toStringAsFixed(2))]),
TableRow(children: [_buildTableCell("电量(%)"), _buildTableCell(status.battery)]),
TableRow(children: [_buildTableCell("芯片温度(°C)"), _buildTableCell(status.chipTemp.toStringAsFixed(2))]),
TableRow(children: [_buildTableCell("割刀速度(rpm)"), _buildTableCell(status.knifeCuttingSpeed)]),
TableRow(children: [_buildTableCell("纬度(°)"), _buildTableCell(status.latitude.toStringAsFixed(6))]),
],
),
],
);
}
Widget _buildTableCell(String text, {bool isHeader = false}) {
return TableCell(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 8),
child: Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: isHeader ? const Color(0xFF333333) : const Color(0xFF666666),
fontWeight: isHeader ? FontWeight.bold : FontWeight.normal,
),
),
),
);
}
Widget _buildCardContentView(DeviceStatusState state) {
// 从 Bloc 状态中提取数据
String voltage = '--';
String leftSpeed = '--';
String rightSpeed = '--';
String yaw = '--';
String pitch = '--';
String roll = '--';
String satelliteCnt = '--';
String qual = '--';
String latitude = '--';
String longitude = '--';
String timeStamp = '--';
String knifeCuttingSpeed = '--';
String controlMode = '--';
String workingArea = '--';
String battery = '--';
String obstacleFlag = '--';
if (state is DeviceStatusUpdated) {
final status = state.status;
voltage = status.voltage.toStringAsFixed(2);
leftSpeed = status.leftTargetSpeed.toStringAsFixed(2);
rightSpeed = status.rightTargetSpeed.toStringAsFixed(2);
yaw = status.yaw.toStringAsFixed(2);
pitch = status.pitch.toStringAsFixed(2);
roll = status.roll.toStringAsFixed(2);
satelliteCnt = status.satelliteCnt.toString();
qual = status.qual.toString();
latitude = status.latitude.toStringAsFixed(8);
longitude = status.longitude.toStringAsFixed(8);
timeStamp = '${status.latitude} ${status.longitude}';
knifeCuttingSpeed = status.knifeCuttingSpeed;
controlMode = status.controlMode;
workingArea = status.workingArea;
battery = status.battery;
obstacleFlag = status.obstacleFlag;
return SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(children: [_buildMotorTable(state), const SizedBox(height: 20), _buildOtherParamsTable(state)]),
);
} else if (state is DeviceStatusError) {
voltage = '错误';
return const Center(
child: Text("数据加载失败", style: TextStyle(color: Colors.red, fontSize: 16)),
);
} else {
return const Center(child: CircularProgressIndicator());
}
return Padding(
padding: const EdgeInsets.all(20.0),child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("设备实时状态", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
_buildCardItem("电压", "$voltage V"),
_buildCardItem("左轮速度", "$leftSpeed rpm"),
_buildCardItem( "右轮速度", "$rightSpeed rpm"),
_buildCardItem( "航向角", "$yaw°"),
_buildCardItem( "俯仰角", "$pitch°"),
_buildCardItem( "翻滚角", "$roll°"),
_buildCardItem( "卫星数", satelliteCnt),
_buildCardItem( "定位质量", qual),
_buildCardItem( "纬度", latitude),
_buildCardItem( "经度", longitude),
/* //_buildCardItem( "时间戳", timeStamp),*/
_buildCardItem( "割刀速度", "$knifeCuttingSpeed rpm"),
_buildCardItem( "控制模式", controlMode),
_buildCardItem( "作业面积", "$workingArea m²"),
_buildCardItem( "电量", "$battery%"),
_buildCardItem( "障碍物标志", obstacleFlag),
],
),
),
);
}
Widget _buildChartContentView() {
@@ -266,13 +306,11 @@ class _RunningStatusPageState extends State<RunningStatusPage> {
final currentDevice = deviceState.selectedDevice;
if (currentDevice != null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("数据刷新成功!"), duration: Duration(seconds: 1)),
);
// 这里可以触发 Bloc 事件来刷新数据
// context.read<DeviceStatusBloc>().add(RefreshDeviceStatus(deviceId: currentDevice.id));
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("数据刷新成功!"), duration: Duration(seconds: 1)));
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("暂无设备,无法刷新"), duration: Duration(seconds: 1)),
);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("暂无设备,无法刷新"), duration: Duration(seconds: 1)));
}
}
}