迁移提交
This commit is contained in:
@@ -2504,7 +2504,8 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔥 新增:步骤2.5 - 调用 getTaskPath 接口获取完整路径数据
|
||||
// 🔥 暂时注释:步骤2.5 - 调用 getTaskPath 接口获取完整路径数据(后端接口未联调,待后续启用)
|
||||
/*
|
||||
debugPrint('📍 [开始作业] 步骤2.5: 调用 getTaskPath 接口获取路径数据');
|
||||
final currentTaskId = taskCubit.state.currentTaskId;
|
||||
bool pathFetchSuccess = false;
|
||||
@@ -2583,6 +2584,7 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
debugPrint('🎯 [开始作业] 步骤4: 任务就绪, currentTaskId=${taskCubit.state.currentTaskId}');
|
||||
setState(() {
|
||||
@@ -3735,6 +3737,21 @@ class _MapPageEnterpriseState extends State<MapPageEnterprise> {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// 🔥 修复:旧路径生成API已废弃,弓字模式直接用打点坐标,打开保存框
|
||||
debugPrint(
|
||||
'📌 [生成路径] 弓字模式: path点数=${_markedPoints.length}, outer=打点坐标, planModel=0',
|
||||
);
|
||||
setState(() {
|
||||
_saveBoxOpen = true;
|
||||
_isWorkAreaCompleted = true;
|
||||
_currentObstaclePoints.clear();
|
||||
_robotModeObsWgsPoints.clear();
|
||||
gcjPathPoints = List.from(_markedPoints);
|
||||
typedPathList = [];
|
||||
});
|
||||
_saveDataToLocal();
|
||||
moveMapToPointsCenter(gcjPathPoints);
|
||||
} catch (e) {
|
||||
debugPrint('路径生成异常:$e');
|
||||
if (showTips) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:maibu_satabot_v2/core/di/injection.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
import '../cubit/bind_device_cubit.dart';
|
||||
import '../cubit/bind_device_state.dart';
|
||||
@@ -44,24 +45,24 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'绑定智能装备',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -69,21 +70,23 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
body: BlocBuilder<BindDeviceCubit, BindDeviceState>(
|
||||
builder: (context, state) {
|
||||
if (state.isLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
);
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -102,17 +105,17 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
vertical: 14,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: const Color(0xFFE5E6EB),
|
||||
color: context.appColors.divider,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
widget.scanResult,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -151,19 +154,19 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
),
|
||||
side: const BorderSide(
|
||||
color: Color(0xFFE5E6EB),
|
||||
side: BorderSide(
|
||||
color: context.appColors.divider,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
height: 1.0,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -178,7 +181,7 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
? null
|
||||
: _handleSubmit,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
@@ -243,20 +246,23 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: const Color(0xFFE5E6EB)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: DropdownButtonFormField<int>(
|
||||
value: validValue,
|
||||
decoration: _dropdownDecoration(enabled, '请选择'),
|
||||
icon: const Icon(Icons.expand_more, color: Color(0xFF86909C)),
|
||||
icon: Icon(Icons.expand_more, color: context.appColors.textTertiary),
|
||||
items: state.orgList.map((org) {
|
||||
return DropdownMenuItem<int>(
|
||||
value: org.id,
|
||||
child: Text(
|
||||
org.name,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
@@ -285,20 +291,23 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: const Color(0xFFE5E6EB)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: DropdownButtonFormField<int>(
|
||||
value: validValue,
|
||||
decoration: _dropdownDecoration(enabled, hintText),
|
||||
icon: const Icon(Icons.expand_more, color: Color(0xFF86909C)),
|
||||
icon: Icon(Icons.expand_more, color: context.appColors.textTertiary),
|
||||
items: state.siteList.map((site) {
|
||||
return DropdownMenuItem<int>(
|
||||
value: site.id,
|
||||
child: Text(
|
||||
site.name,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
@@ -327,20 +336,23 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: const Color(0xFFE5E6EB)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: DropdownButtonFormField<int>(
|
||||
value: validValue,
|
||||
decoration: _dropdownDecoration(enabled, hintText),
|
||||
icon: const Icon(Icons.expand_more, color: Color(0xFF86909C)),
|
||||
icon: Icon(Icons.expand_more, color: context.appColors.textTertiary),
|
||||
items: state.userList.map((user) {
|
||||
return DropdownMenuItem<int>(
|
||||
value: user.id,
|
||||
child: Text(
|
||||
user.name,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
@@ -365,15 +377,15 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFE8F3FF),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(color: const Color(0xFF165DFF), width: 0.5),
|
||||
border: Border.all(color: context.appColors.primary, width: 0.5),
|
||||
),
|
||||
child: Text(
|
||||
'当前角色:$roleLabel($roleKey)',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -384,20 +396,23 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: const Color(0xFFE5E6EB)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const Icon(Icons.lock, size: 16, color: Color(0xFFC9CDD4)),
|
||||
Icon(Icons.lock, size: 16, color: context.appColors.textTertiary),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -411,7 +426,10 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
enabledBorder: InputBorder.none,
|
||||
focusedBorder: InputBorder.none,
|
||||
hintText: hintText,
|
||||
hintStyle: const TextStyle(color: Color(0xFF86909C), fontSize: 14),
|
||||
hintStyle: TextStyle(
|
||||
color: context.appColors.textTertiary,
|
||||
fontSize: 14,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -422,18 +440,18 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
const TextSpan(
|
||||
TextSpan(
|
||||
text: '* ',
|
||||
style: TextStyle(
|
||||
color: Color(0xFFF53F3F),
|
||||
color: context.appColors.danger,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: label,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF1D2129),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textPrimary,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
@@ -453,8 +471,8 @@ class _BindDevicePageState extends State<BindDevicePage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF1D2129),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textPrimary,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'dart:developer' as developer;
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -235,7 +236,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(error),
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: context.appColors.danger,
|
||||
duration: const Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
@@ -413,7 +414,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
final scanResult = widget.scanResult;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
elevation: 0,
|
||||
@@ -454,11 +455,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -472,12 +473,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.bluetooth,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
@@ -488,18 +489,18 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'${widget.device.remoteId}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -509,7 +510,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Divider(height: 1, color: Color(0xFFE5E6EB)),
|
||||
Divider(height: 1, color: context.appColors.divider),
|
||||
const SizedBox(height: 12),
|
||||
_buildInfoRow('设备名称', name),
|
||||
_buildInfoRow('设备ID', '${widget.device.remoteId}'),
|
||||
@@ -540,12 +541,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFF7D00).withOpacity(0.15),
|
||||
color: context.appColors.warning.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
'连接中 ${_connectingCountdown}s',
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFFFF7D00)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.warning),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -553,24 +554,24 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00B42A).withOpacity(0.15),
|
||||
color: context.appColors.success.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'已连接',
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF00B42A)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.success),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF86909C).withOpacity(0.15),
|
||||
color: context.appColors.textTertiary.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'未连接',
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -585,13 +586,13 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
width: 80,
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -603,11 +604,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -616,12 +617,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'操作',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -634,8 +635,8 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
backgroundColor: _isConnected
|
||||
? const Color(0xFFF53F3F)
|
||||
: const Color(0xFF165DFF),
|
||||
? context.appColors.danger
|
||||
: context.appColors.primary,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -662,11 +663,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -675,12 +676,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'服务列表',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -695,7 +696,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
margin: const EdgeInsets.only(bottom: 10),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
@@ -703,15 +704,15 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Icon(Icons.widgets, size: 16, color: Color(0xFF165DFF)),
|
||||
Icon(Icons.widgets, size: 16, color: context.appColors.primary),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
service.uuid.toString().toUpperCase(),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -719,8 +720,8 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: service.isPrimary
|
||||
? const Color(0xFF165DFF).withOpacity(0.1)
|
||||
: const Color(0xFF86909C).withOpacity(0.1),
|
||||
? context.appColors.primary.withOpacity(0.1)
|
||||
: context.appColors.textTertiary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
@@ -728,8 +729,8 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: service.isPrimary
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF86909C),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -741,14 +742,14 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
padding: const EdgeInsets.only(left: 24, top: 4),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.code, size: 14, color: Color(0xFF00B42A)),
|
||||
Icon(Icons.code, size: 14, color: context.appColors.success),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
child: Text(
|
||||
c.uuid.toString().toUpperCase(),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -779,12 +780,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
margin: const EdgeInsets.only(left: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: Text(
|
||||
p,
|
||||
style: const TextStyle(fontSize: 10, color: Color(0xFF165DFF)),
|
||||
style: TextStyle(fontSize: 10, color: context.appColors.primary),
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -796,11 +797,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -809,12 +810,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'发送指令',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -825,7 +826,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
icon: const Icon(Icons.settings, size: 18),
|
||||
label: const Text('读配置'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -844,11 +845,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -859,12 +860,12 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'数据推送',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
if (pushes.isNotEmpty) ...[
|
||||
@@ -872,7 +873,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
@@ -891,21 +892,21 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
});
|
||||
BleManager.instance.clearReceivedPackets();
|
||||
},
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'清空',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF165DFF)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.primary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (pushes.isEmpty)
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'等待接收数据...',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -969,7 +970,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
'${p.time.hour.toString().padLeft(2, '0')}:'
|
||||
'${p.time.minute.toString().padLeft(2, '0')}:'
|
||||
'${p.time.second.toString().padLeft(2, '0')}',
|
||||
style: const TextStyle(fontSize: 11, color: Color(0xFFC9CDD4)),
|
||||
style: TextStyle(fontSize: 11, color: context.appColors.textTertiary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -984,7 +985,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
width: 68,
|
||||
child: Text(
|
||||
f.label,
|
||||
style: const TextStyle(fontSize: 11, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 11, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
@@ -992,7 +993,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
f.value,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 11, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 11, color: context.appColors.textPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1005,10 +1006,10 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
p.hex,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontFamily: 'monospace',
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1038,11 +1039,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -1053,13 +1054,13 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
Expanded(
|
||||
child: Text(
|
||||
'设备配置 (0x05)',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1084,7 +1085,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -1096,7 +1097,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const Divider(height: 1, color: Color(0xFFE5E6EB)),
|
||||
Divider(height: 1, color: context.appColors.divider),
|
||||
const SizedBox(height: 8),
|
||||
// 每个属性一行:label 左对齐,值右对齐,可换行
|
||||
...fieldMap.entries.map((entry) {
|
||||
@@ -1132,8 +1133,8 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: editable
|
||||
? const Color(0xFF4E5969)
|
||||
: const Color(0xFF86909C),
|
||||
? context.appColors.textSecondary
|
||||
: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1148,19 +1149,19 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
children: [
|
||||
TextSpan(
|
||||
text: mod.oldValue,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFC9CDD4),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textTertiary,
|
||||
decoration: TextDecoration.lineThrough,
|
||||
),
|
||||
),
|
||||
const TextSpan(
|
||||
TextSpan(
|
||||
text: ' | ',
|
||||
style: TextStyle(color: Color(0xFFE5E6EB)),
|
||||
style: TextStyle(color: context.appColors.divider),
|
||||
),
|
||||
TextSpan(
|
||||
text: mod.newValue,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF165DFF),
|
||||
style: TextStyle(
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -1173,19 +1174,19 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: editable
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF1D2129),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (editable)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 4),
|
||||
child: Icon(
|
||||
Icons.edit,
|
||||
size: 14,
|
||||
color: Color(0xFFC9CDD4),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1218,7 +1219,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
hintText: '输入新值',
|
||||
border: const OutlineInputBorder(),
|
||||
suffixText: '当前: $currentValue',
|
||||
suffixStyle: const TextStyle(fontSize: 11, color: Color(0xFF86909C)),
|
||||
suffixStyle: TextStyle(fontSize: 11, color: context.appColors.textTertiary),
|
||||
errorText: errorText,
|
||||
),
|
||||
),
|
||||
@@ -1272,10 +1273,10 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
final chipUid = readConfigPacket?.configEntity?.chipUid ?? '';
|
||||
if (chipUid.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
SnackBar(
|
||||
content: Text('未获取到设备序列号,请先读配置'),
|
||||
backgroundColor: Colors.orange,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: context.appColors.warning,
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
setState(() => _writeConfigLoading = false);
|
||||
@@ -1287,10 +1288,10 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
if (!mounted) return;
|
||||
if (!hasPermission) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
SnackBar(
|
||||
content: Text('权限校验未通过,无法写入配置'),
|
||||
backgroundColor: Colors.red,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: context.appColors.danger,
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
setState(() => _writeConfigLoading = false);
|
||||
@@ -1302,11 +1303,11 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (dialogCtx) => AlertDialog(
|
||||
title: const Row(
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.check_circle, color: Colors.green, size: 28),
|
||||
SizedBox(width: 8),
|
||||
Text('权限通过'),
|
||||
Icon(Icons.check_circle, color: context.appColors.success, size: 28),
|
||||
const SizedBox(width: 8),
|
||||
const Text('权限通过'),
|
||||
],
|
||||
),
|
||||
content: const Text('您有权限操作此设备'),
|
||||
@@ -1381,9 +1382,9 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
|
||||
if (readbackPayload == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
SnackBar(
|
||||
content: Text('回读超时,请手动读配置确认'),
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -1437,7 +1438,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
content: Text(
|
||||
'校验不一致: ${mismatched.join('、')},已恢复为设备实际值',
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
duration: const Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
@@ -1465,9 +1466,9 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
_configModifications = {};
|
||||
});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
SnackBar(
|
||||
content: Text('写配置成功,已回读确认'),
|
||||
backgroundColor: Color(0xFF00B42A),
|
||||
backgroundColor: context.appColors.success,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1476,7 +1477,7 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('写配置异常: $e'),
|
||||
backgroundColor: Colors.red,
|
||||
backgroundColor: context.appColors.danger,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
@@ -1491,39 +1492,20 @@ class _BleDeviceDetailPageState extends State<BleDeviceDetailPage> {
|
||||
|
||||
/// 卡片配色按命令类型区分
|
||||
_CardColors _cardColors(int command) {
|
||||
const colors = [
|
||||
_CardColors(
|
||||
bg: Color(0xFFF0F5FF),
|
||||
border: Color(0xFFADC6FF),
|
||||
badge: Color(0xFF165DFF),
|
||||
fg: Color(0xFF165DFF),
|
||||
),
|
||||
_CardColors(
|
||||
bg: Color(0xFFF0FFF4),
|
||||
border: Color(0xFFB7EB8F),
|
||||
badge: Color(0xFF00B42A),
|
||||
fg: Color(0xFF00B42A),
|
||||
),
|
||||
_CardColors(
|
||||
bg: Color(0xFFFFF7E6),
|
||||
border: Color(0xFFFFD591),
|
||||
badge: Color(0xFFFF7D00),
|
||||
fg: Color(0xFFFF7D00),
|
||||
),
|
||||
_CardColors(
|
||||
bg: Color(0xFFFFF0F6),
|
||||
border: Color(0xFFFFADD2),
|
||||
badge: Color(0xFFF5319D),
|
||||
fg: Color(0xFFF5319D),
|
||||
),
|
||||
_CardColors(
|
||||
bg: Color(0xFFF9F0FF),
|
||||
border: Color(0xFFD3ADF7),
|
||||
badge: Color(0xFF722ED1),
|
||||
fg: Color(0xFF722ED1),
|
||||
),
|
||||
final accents = [
|
||||
context.appColors.primary,
|
||||
context.appColors.success,
|
||||
context.appColors.warning,
|
||||
const Color(0xFFF5319D),
|
||||
const Color(0xFF722ED1),
|
||||
];
|
||||
return colors[command % colors.length];
|
||||
final accent = accents[command % accents.length];
|
||||
return _CardColors(
|
||||
bg: accent.withOpacity(0.1),
|
||||
border: accent.withOpacity(0.3),
|
||||
badge: accent,
|
||||
fg: accent,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
|
||||
/// 清洗/除草机器人任务详情页
|
||||
@@ -15,26 +16,26 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
: AppLocalizations.of(context).translate('device_list_v2.weeding_robot') + ' ' + AppLocalizations.of(context).translate('device_list_v2.task');
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.edit_outlined, color: context.appColors.textPrimary),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
@@ -45,29 +46,29 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
_buildTaskInfoCard(isCleaning),
|
||||
_buildTaskInfoCard(context, isCleaning),
|
||||
const SizedBox(height: 12),
|
||||
_buildProgressCard(isCleaning),
|
||||
_buildProgressCard(context, isCleaning),
|
||||
const SizedBox(height: 12),
|
||||
_buildDeviceStatusCard(isCleaning),
|
||||
_buildDeviceStatusCard(context, isCleaning),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildBottomButtons(),
|
||||
_buildBottomButtons(context),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTaskInfoCard(bool isCleaning) {
|
||||
Widget _buildTaskInfoCard(BuildContext context, bool isCleaning) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -81,24 +82,24 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
isCleaning ? '清洗任务-组件清洗A区' : '除草任务-光伏板除草B区',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'进行中',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -112,10 +113,10 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildInfoRow('任务编号', isCleaning ? 'CL-2025052001' : 'WD-2025052001'),
|
||||
_buildInfoRow('作业区域', isCleaning ? '清洗区A区-01' : '除草区B区-02'),
|
||||
_buildInfoRow('开始时间', '05-20 09:20'),
|
||||
_buildInfoRow('预计完成', '05-20 14:30'),
|
||||
_buildInfoRow(context, '任务编号', isCleaning ? 'CL-2025052001' : 'WD-2025052001'),
|
||||
_buildInfoRow(context, '作业区域', isCleaning ? '清洗区A区-01' : '除草区B区-02'),
|
||||
_buildInfoRow(context, '开始时间', '05-20 09:20'),
|
||||
_buildInfoRow(context, '预计完成', '05-20 14:30'),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -136,23 +137,23 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoRow(String label, String value) {
|
||||
Widget _buildInfoRow(BuildContext context, String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'$label:',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -161,15 +162,15 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProgressCard(bool isCleaning) {
|
||||
Widget _buildProgressCard(BuildContext context, bool isCleaning) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -178,12 +179,12 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'作业进度',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -192,27 +193,27 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
'覆盖面积',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
isCleaning ? '8,230 m² / 15,000 m²' : '5,600 m² / 12,000 m²',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
isCleaning ? '55%' : '47%',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -222,27 +223,27 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: isCleaning ? 0.55 : 0.47,
|
||||
backgroundColor: const Color(0xFFF2F3F5),
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF165DFF)),
|
||||
backgroundColor: context.appColors.fillBackground,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(context.appColors.primary),
|
||||
minHeight: 8,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'预计完成时间',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'14:30(剩余 2h10m)',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -253,15 +254,15 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeviceStatusCard(bool isCleaning) {
|
||||
Widget _buildDeviceStatusCard(BuildContext context, bool isCleaning) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -270,52 +271,52 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'设备状态',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildStatusRow('电量', '68%', 0.68),
|
||||
_buildStatusRow(context, '电量', '68%', 0.68),
|
||||
const SizedBox(height: 12),
|
||||
if (isCleaning) ...[
|
||||
_buildStatusRow('水箱水位', '62%', 0.62),
|
||||
_buildStatusRow(context, '水箱水位', '62%', 0.62),
|
||||
const SizedBox(height: 12),
|
||||
_buildStatusRowWithBadge('喷淋压力', '0.45 MPa', '正常'),
|
||||
_buildStatusRowWithBadge(context, '喷淋压力', '0.45 MPa', '正常'),
|
||||
const SizedBox(height: 12),
|
||||
_buildStatusRowWithBadge('刷头状态', '正常', '正常'),
|
||||
_buildStatusRowWithBadge(context, '刷头状态', '正常', '正常'),
|
||||
] else ...[
|
||||
_buildStatusRow('燃油量', '75%', 0.75),
|
||||
_buildStatusRow(context, '燃油量', '75%', 0.75),
|
||||
const SizedBox(height: 12),
|
||||
_buildStatusRowWithBadge('刀片状态', '正常', '正常'),
|
||||
_buildStatusRowWithBadge(context, '刀片状态', '正常', '正常'),
|
||||
const SizedBox(height: 12),
|
||||
_buildStatusRowWithBadge('导航状态', '正常', '正常'),
|
||||
_buildStatusRowWithBadge(context, '导航状态', '正常', '正常'),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusRow(String label, String value, double progress) {
|
||||
Widget _buildStatusRow(BuildContext context, String label, String value, double progress) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -325,9 +326,9 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: progress,
|
||||
backgroundColor: const Color(0xFFF2F3F5),
|
||||
backgroundColor: context.appColors.fillBackground,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
progress > 0.5 ? const Color(0xFF00B42A) : const Color(0xFFFF7D00),
|
||||
progress > 0.5 ? context.appColors.success : context.appColors.warning,
|
||||
),
|
||||
minHeight: 6,
|
||||
),
|
||||
@@ -337,36 +338,36 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusRowWithBadge(String label, String value, String badgeText) {
|
||||
Widget _buildStatusRowWithBadge(BuildContext context, String label, String value, String badgeText) {
|
||||
return Row(
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00B42A).withOpacity(0.1),
|
||||
color: context.appColors.success.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
badgeText,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -375,7 +376,7 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBottomButtons() {
|
||||
Widget _buildBottomButtons(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 20),
|
||||
child: Row(
|
||||
@@ -384,7 +385,7 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -406,7 +407,7 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFFFF7D00),
|
||||
backgroundColor: context.appColors.warning,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -428,8 +429,8 @@ class CleaningWeedingRobotTaskPage extends StatelessWidget {
|
||||
child: OutlinedButton(
|
||||
onPressed: () {},
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: const Color(0xFF4E5969),
|
||||
side: const BorderSide(color: Color(0xFFC9CDD4)),
|
||||
foregroundColor: context.appColors.textSecondary,
|
||||
side: BorderSide(color: context.appColors.textTertiary),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../../../../../core/consts/http_api_consts.dart';
|
||||
import '../../../../../core/managers/drone_task_state_manager.dart';
|
||||
@@ -55,20 +56,20 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'创建航线任务',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -212,17 +213,17 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
child: OutlinedButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
side: BorderSide(color: context.appColors.divider),
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'取消',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -236,7 +237,7 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _onCreateTask,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
padding: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -275,9 +276,9 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -288,22 +289,22 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
keyboardType: keyboardType,
|
||||
decoration: InputDecoration(
|
||||
hintText: hint,
|
||||
hintStyle: const TextStyle(fontSize: 13, color: Color(0xFFC9CDD4)),
|
||||
hintStyle: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFF165DFF)),
|
||||
borderSide: BorderSide(color: context.appColors.primary),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFF2F3F5)),
|
||||
borderSide: BorderSide(color: context.appColors.fillBackground),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -328,9 +329,9 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -340,9 +341,9 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
hint: hint != null
|
||||
? Text(
|
||||
hint,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFFC9CDD4),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
@@ -353,15 +354,15 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFF165DFF)),
|
||||
borderSide: BorderSide(color: context.appColors.primary),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -531,7 +532,7 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
@@ -544,12 +545,12 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'选择航线',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
@@ -581,14 +582,14 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
subtitle: waylineUuid.isNotEmpty
|
||||
? Text(
|
||||
waylineUuid,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
trailing: _selectedWaylineName == waylineName
|
||||
? const Icon(Icons.check, color: Color(0xFF165DFF))
|
||||
? Icon(Icons.check, color: context.appColors.primary)
|
||||
: null,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
@@ -623,9 +624,9 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -635,7 +636,7 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: const Color(0xFFE5E6EB)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Row(
|
||||
@@ -646,12 +647,12 @@ class _CreateTaskPageState extends State<CreateTaskPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: value != null
|
||||
? const Color(0xFF1D2129)
|
||||
: const Color(0xFFC9CDD4),
|
||||
? context.appColors.textPrimary
|
||||
: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Icon(Icons.arrow_drop_down, color: Color(0xFF86909C)),
|
||||
Icon(Icons.arrow_drop_down, color: context.appColors.textTertiary),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import '../../../../../core/di/injection.dart';
|
||||
import '../../../../../core/app/app_user_cubit.dart';
|
||||
import '../../../../../core/bluetooth/ble_manager.dart';
|
||||
@@ -130,13 +131,14 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: const SystemUiOverlayStyle(
|
||||
value: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
statusBarIconBrightness: isDark ? Brightness.light : Brightness.dark,
|
||||
),
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF7F7F7),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
body: SafeArea(
|
||||
child:
|
||||
BlocConsumer<
|
||||
@@ -152,7 +154,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
content: Text(state.message),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -184,16 +186,16 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
children: [
|
||||
const Flexible(child: SiteSelectorWidget(compact: true)),
|
||||
const SizedBox(width: 8),
|
||||
Container(width: 1, height: 20, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 20, color: context.appColors.divider),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.title'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -226,14 +228,14 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: const Color(0xFFE5E6EB),
|
||||
color: context.appColors.divider,
|
||||
width: 1,
|
||||
),
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
@@ -257,13 +259,13 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
hintText: AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.search_hint'),
|
||||
hintStyle: const TextStyle(
|
||||
color: Color(0xFF86909C),
|
||||
hintStyle: TextStyle(
|
||||
color: context.appColors.textTertiary,
|
||||
fontSize: 14,
|
||||
),
|
||||
prefixIcon: const Icon(
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
size: 24,
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
@@ -274,32 +276,32 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
),
|
||||
);
|
||||
},
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF2F3F5),
|
||||
fillColor: context.appColors.fillBackground,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
borderSide: const BorderSide(
|
||||
color: Color(0xFFE5E6EB),
|
||||
borderSide: BorderSide(
|
||||
color: context.appColors.divider,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
borderSide: const BorderSide(
|
||||
color: Color(0xFFE5E6EB),
|
||||
borderSide: BorderSide(
|
||||
color: context.appColors.divider,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
borderSide: const BorderSide(
|
||||
color: Color(0xFF165DFF),
|
||||
borderSide: BorderSide(
|
||||
color: context.appColors.primary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -308,7 +310,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 14, color: context.appColors.textPrimary),
|
||||
onSubmitted: (value) {
|
||||
context.read<DeviceListBloc.DeviceStatusBloc>().add(
|
||||
DeviceListEvent.DeviceStatusSearch(value),
|
||||
@@ -339,11 +341,11 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.bluetooth,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
@@ -411,8 +413,8 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: isSelected
|
||||
? const Color(0xFF135BFF)
|
||||
: const Color(0xFF666666),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textSecondary,
|
||||
fontWeight: isSelected
|
||||
? FontWeight.w600
|
||||
: FontWeight.normal,
|
||||
@@ -424,7 +426,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
height: 2,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? const Color(0xFF0D57FF)
|
||||
? context.appColors.primary
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
),
|
||||
@@ -467,8 +469,8 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
DeviceListState.DeviceStatusState state,
|
||||
) {
|
||||
if (state is DeviceListState.DeviceStatusLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(color: context.appColors.primary),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -517,7 +519,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
const DeviceListEvent.DeviceStatusRefresh(),
|
||||
);
|
||||
},
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
children: [
|
||||
@@ -569,7 +571,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
content: Text(state.message),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -578,10 +580,12 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
debugPrint('🔍 [EmbeddedRobotList] 当前状态: ${state.runtimeType}');
|
||||
|
||||
if (state is RobotListLoading) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.all(32),
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
child: CircularProgressIndicator(
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -677,13 +681,20 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.location_off, size: 48, color: Color(0xFF86909C)),
|
||||
Icon(
|
||||
Icons.location_off,
|
||||
size: 48,
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.select_site_first'),
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -703,15 +714,15 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
content: Text(state.message),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is DroneStationLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(color: context.appColors.primary),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -730,9 +741,9 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.no_drone_stations'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -744,7 +755,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
DroneStationRefresh(selectedSite.id),
|
||||
);
|
||||
},
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: embedded,
|
||||
physics: embedded
|
||||
@@ -802,13 +813,13 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -819,35 +830,35 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.total_devices'),
|
||||
dotColor: const Color(0xFF86909C),
|
||||
textColor: const Color(0xFF86909C),
|
||||
dotColor: context.appColors.textTertiary,
|
||||
textColor: context.appColors.textTertiary,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatItem(
|
||||
value: onlineCount.toString(),
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.online'),
|
||||
dotColor: const Color(0xFF00B42A),
|
||||
textColor: const Color(0xFF00B42A),
|
||||
dotColor: context.appColors.success,
|
||||
textColor: context.appColors.success,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatItem(
|
||||
value: exceptionCount.toString(),
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.alarm'),
|
||||
dotColor: const Color(0xFFFF7D00),
|
||||
textColor: const Color(0xFFFF7D00),
|
||||
dotColor: context.appColors.warning,
|
||||
textColor: context.appColors.warning,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatItem(
|
||||
value: offlineCount.toString(),
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
).translate('device_list_v2.offline'),
|
||||
dotColor: const Color(0xFFF53F3F),
|
||||
textColor: const Color(0xFFF53F3F),
|
||||
dotColor: context.appColors.danger,
|
||||
textColor: context.appColors.danger,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -868,7 +879,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: textColor ?? const Color(0xFF1D2129),
|
||||
color: textColor ?? context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -889,7 +900,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: textColor ?? const Color(0xFF4E5969),
|
||||
color: textColor ?? context.appColors.textSecondary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -921,9 +932,9 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
right: 16,
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: Colors.white,
|
||||
color: ctx.appColors.cardBackground,
|
||||
elevation: 8,
|
||||
shadowColor: Colors.black26,
|
||||
shadowColor: ctx.appColors.cardShadow,
|
||||
child: SizedBox(
|
||||
width: 150,
|
||||
child: Column(
|
||||
@@ -950,7 +961,7 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
}
|
||||
},
|
||||
),
|
||||
const Divider(height: 1, color: Color(0xFFF2F3F5)),
|
||||
Divider(height: 1, color: ctx.appColors.divider),
|
||||
_buildMenuOption(
|
||||
ctx,
|
||||
icon: Icons.add_circle_outline,
|
||||
@@ -983,11 +994,14 @@ class _DeviceStatusViewState extends State<DeviceStatusView> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(icon, color: const Color(0xFF4E5969), size: 20),
|
||||
Icon(icon, color: context.appColors.textSecondary, size: 20),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 15, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import '../../../../../core/consts/http_api_consts.dart';
|
||||
@@ -349,26 +350,26 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'无人机任务与航线控制',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.settings, color: context.appColors.textPrimary),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
@@ -396,20 +397,27 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
|
||||
Widget _buildMissionInfoCard() {
|
||||
if (_isLoading) {
|
||||
return const Center(
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(32),
|
||||
child: CircularProgressIndicator(),
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
context.appColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final task = _detailTask;
|
||||
if (task == null) {
|
||||
return const Center(
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(32),
|
||||
child: Text('暂无数据', style: TextStyle(color: Color(0xFF86909C))),
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Text(
|
||||
'暂无数据',
|
||||
style: TextStyle(color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -417,11 +425,11 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -430,12 +438,12 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'任务信息',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -509,13 +517,13 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
Color _getStatusColor(String status) {
|
||||
switch (status.toLowerCase()) {
|
||||
case 'success':
|
||||
return const Color(0xFF00B42A);
|
||||
return context.appColors.success;
|
||||
case 'failed':
|
||||
return const Color(0xFFF53F3F);
|
||||
return context.appColors.danger;
|
||||
case 'running':
|
||||
return const Color(0xFF165DFF);
|
||||
return context.appColors.primary;
|
||||
default:
|
||||
return const Color(0xFF86909C);
|
||||
return context.appColors.textTertiary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,11 +577,11 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
return Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -594,11 +602,11 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -609,27 +617,27 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'航点列表',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.map, size: 20, color: Color(0xFF86909C)),
|
||||
icon: Icon(Icons.map, size: 20, color: context.appColors.textTertiary),
|
||||
onPressed: () {},
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
size: 20,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
onPressed: () {},
|
||||
padding: EdgeInsets.zero,
|
||||
@@ -665,8 +673,8 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFF165DFF),
|
||||
decoration: BoxDecoration(
|
||||
color: context.appColors.primary,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
@@ -684,24 +692,24 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
Expanded(
|
||||
child: Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'H: $height',
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
action,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textSecondary),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.download_outlined, size: 18, color: Color(0xFF165DFF)),
|
||||
Icon(Icons.download_outlined, size: 18, color: context.appColors.primary),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -709,14 +717,14 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
Widget _buildActionButtons() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 20),
|
||||
decoration: const BoxDecoration(color: Color(0xFFF5F6F8)),
|
||||
decoration: BoxDecoration(color: context.appColors.pageBackground),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: _executeTask,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -736,8 +744,8 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
onPressed: _isPaused ? _resumeTask : _pauseTask,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: _isPaused
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFFFF7D00),
|
||||
? context.appColors.primary
|
||||
: context.appColors.warning,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -760,12 +768,12 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
onPressed: _isReturning ? null : _returnHome,
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: _isReturning
|
||||
? const Color(0xFF86909C)
|
||||
: const Color(0xFF4E5969),
|
||||
? context.appColors.textTertiary
|
||||
: context.appColors.textSecondary,
|
||||
side: BorderSide(
|
||||
color: _isReturning
|
||||
? const Color(0xFFE5E6EB)
|
||||
: const Color(0xFFC9CDD4),
|
||||
? context.appColors.divider
|
||||
: context.appColors.divider,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
@@ -794,16 +802,16 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
width: 100,
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
softWrap: true,
|
||||
@@ -819,14 +827,14 @@ class _DroneMissionControlPageState extends State<DroneMissionControlPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
softWrap: true,
|
||||
@@ -901,12 +909,12 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'创建航线任务',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
@@ -1051,7 +1059,7 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
OutlinedButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
style: OutlinedButton.styleFrom(
|
||||
side: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
side: BorderSide(color: context.appColors.divider),
|
||||
minimumSize: const Size(80, 36),
|
||||
),
|
||||
child: const Text('取消'),
|
||||
@@ -1060,7 +1068,7 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
ElevatedButton(
|
||||
onPressed: _onCreateTask,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
minimumSize: const Size(100, 36),
|
||||
),
|
||||
child: const Text('确认创建'),
|
||||
@@ -1088,9 +1096,9 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -1101,22 +1109,22 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
keyboardType: keyboardType,
|
||||
decoration: InputDecoration(
|
||||
hintText: hint,
|
||||
hintStyle: const TextStyle(fontSize: 13, color: Color(0xFFC9CDD4)),
|
||||
hintStyle: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFF165DFF)),
|
||||
borderSide: BorderSide(color: context.appColors.primary),
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFF2F3F5)),
|
||||
borderSide: BorderSide(color: context.appColors.fillBackground),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
@@ -1141,9 +1149,9 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -1153,9 +1161,9 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
hint: hint != null
|
||||
? Text(
|
||||
hint,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFFC9CDD4),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
@@ -1166,15 +1174,15 @@ class _CreateTaskDialogState extends State<CreateTaskDialog> {
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFFE5E6EB)),
|
||||
borderSide: BorderSide(color: context.appColors.divider),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
borderSide: const BorderSide(color: Color(0xFF165DFF)),
|
||||
borderSide: BorderSide(color: context.appColors.primary),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../../../core/di/injection.dart';
|
||||
import '../../../../../core/managers/drone_task_state_manager.dart';
|
||||
@@ -273,20 +274,20 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
return BlocProvider.value(
|
||||
value: _bloc,
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'无人机机场详情',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -295,8 +296,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
listener: (context, state) {},
|
||||
builder: (context, state) {
|
||||
if (state is UAVDetailLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(color: context.appColors.primary),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -305,17 +306,17 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.error_outline,
|
||||
size: 48,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
state.message,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -329,7 +330,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
),
|
||||
child: const Text('重试'),
|
||||
),
|
||||
@@ -354,7 +355,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: _handleRefresh,
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
@@ -526,47 +527,47 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
}
|
||||
|
||||
String coverStr = '未知';
|
||||
Color coverColor = const Color(0xFF86909C);
|
||||
Color coverColor = context.appColors.textTertiary;
|
||||
if (coverState != null) {
|
||||
// 🔥 像 DroneStationOsdCard 一样解析,支持多种数据格式
|
||||
final state = coverState is int ? coverState : int.tryParse(coverState.toString()) ?? -1;
|
||||
if (state == 1) {
|
||||
coverStr = '开启';
|
||||
coverColor = const Color(0xFFFF7D00);
|
||||
coverColor = context.appColors.warning;
|
||||
} else if (state == 0) {
|
||||
coverStr = '关闭';
|
||||
coverColor = const Color(0xFF00B42A);
|
||||
coverColor = context.appColors.success;
|
||||
}
|
||||
}
|
||||
|
||||
String droneDockStr = '未知';
|
||||
Color droneDockColor = const Color(0xFF86909C);
|
||||
Color droneDockColor = context.appColors.textTertiary;
|
||||
if (droneInDock != null) {
|
||||
// 🔥 像 DroneStationOsdCard 一样解析
|
||||
final state = droneInDock is int ? droneInDock : int.tryParse(droneInDock.toString()) ?? -1;
|
||||
if (state == 1) {
|
||||
droneDockStr = '在库内';
|
||||
droneDockColor = const Color(0xFF00B42A);
|
||||
droneDockColor = context.appColors.success;
|
||||
} else if (state == 0) {
|
||||
droneDockStr = '出库';
|
||||
droneDockColor = const Color(0xFFFF7D00);
|
||||
droneDockColor = context.appColors.warning;
|
||||
}
|
||||
}
|
||||
|
||||
String acStr = '未知';
|
||||
Color acColor = const Color(0xFF86909C);
|
||||
Color acColor = context.appColors.textTertiary;
|
||||
if (acState != null) {
|
||||
// 🔥 增强兼容性:支持多种数据格式和更多状态值
|
||||
final acValue = acState is int ? acState : int.tryParse(acState.toString()) ?? -1;
|
||||
if (acValue == 1) {
|
||||
acStr = '开启';
|
||||
acColor = const Color(0xFF00B42A);
|
||||
acColor = context.appColors.success;
|
||||
} else if (acValue == 0) {
|
||||
acStr = '关闭';
|
||||
acColor = const Color(0xFF86909C);
|
||||
acColor = context.appColors.textTertiary;
|
||||
} else if (acValue == 2) {
|
||||
acStr = '待机';
|
||||
acColor = const Color(0xFFFF7D00);
|
||||
acColor = context.appColors.warning;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,11 +580,11 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -594,12 +595,12 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'机场状态',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -638,8 +639,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: detail.isOnline
|
||||
? const Color(0xFF00B42A).withOpacity(0.1)
|
||||
: const Color(0xFFF53F3F).withOpacity(0.1),
|
||||
? context.appColors.success.withOpacity(0.1)
|
||||
: context.appColors.danger.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
@@ -647,8 +648,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: detail.isOnline
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFF53F3F),
|
||||
? context.appColors.success
|
||||
: context.appColors.danger,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -674,10 +675,10 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
? '${detail.capacityPercent}%'
|
||||
: '未知',
|
||||
),
|
||||
_buildInfoRowColor('环境温度', envTempStr, const Color(0xFF165DFF)),
|
||||
_buildInfoRowColor('湿度', humidityStr, const Color(0xFF00B42A)),
|
||||
_buildInfoRowColor('环境温度', envTempStr, context.appColors.primary),
|
||||
_buildInfoRowColor('湿度', humidityStr, context.appColors.success),
|
||||
_buildInfoRowColor('风速', windStr, const Color(0xFF722ED1)),
|
||||
_buildInfoRowColor('降雨量', rainfallStr, const Color(0xFF00B42A)),
|
||||
_buildInfoRowColor('降雨量', rainfallStr, context.appColors.success),
|
||||
_buildInfoRowColor('机库舱门', coverStr, coverColor),
|
||||
_buildInfoRowColor('无人机位置', droneDockStr, droneDockColor),
|
||||
_buildInfoRowColor('空调状态', acStr, acColor),
|
||||
@@ -698,13 +699,13 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
width: 80,
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Text(
|
||||
Text(
|
||||
':',
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFFC0C4CC)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
@@ -736,15 +737,15 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const Spacer(),
|
||||
Flexible(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
@@ -792,11 +793,11 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -807,12 +808,12 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'无人机状态',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -823,8 +824,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: detail.isDroneOnline
|
||||
? const Color(0xFF00B42A).withOpacity(0.1)
|
||||
: const Color(0xFFF53F3F).withOpacity(0.1),
|
||||
? context.appColors.success.withOpacity(0.1)
|
||||
: context.appColors.danger.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
@@ -832,8 +833,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: detail.isDroneOnline
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFF53F3F),
|
||||
? context.appColors.success
|
||||
: context.appColors.danger,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -884,11 +885,11 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -897,12 +898,12 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'快捷操作',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -912,7 +913,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.flight_takeoff,
|
||||
label: '开舱',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -921,7 +922,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.flight,
|
||||
label: '起飞准备',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -930,7 +931,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.home,
|
||||
label: '返航',
|
||||
color: const Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -939,7 +940,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.task,
|
||||
label: '任务下发',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {
|
||||
_showFlightTaskSelector();
|
||||
},
|
||||
@@ -968,6 +969,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
builder: (context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -995,7 +997,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Row(
|
||||
@@ -1037,8 +1039,8 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
maxChildSize: 0.95,
|
||||
builder: (context, scrollController) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
decoration: BoxDecoration(
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
child: FlightTaskSelectorModal(
|
||||
@@ -1085,7 +1087,7 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textSecondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1102,21 +1104,21 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
width: 80,
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Text(
|
||||
Text(
|
||||
':',
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFFC0C4CC)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
@@ -1136,15 +1138,15 @@ class _DroneStationDetailPageState extends State<DroneStationDetailPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const Spacer(),
|
||||
Flexible(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../../../core/di/injection.dart';
|
||||
import '../../../../../core/managers/drone_task_state_manager.dart';
|
||||
@@ -99,10 +100,10 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
/// 显示无人机不在线提示
|
||||
void _showOfflineToast() {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
SnackBar(
|
||||
content: Text('无人机不在线,无法查看实时视频和轨迹'),
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: Color(0xFFFF7D00),
|
||||
duration: const Duration(seconds: 2),
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -130,32 +131,32 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
// 顶部导航栏
|
||||
SliverAppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
pinned: true,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: const Text(
|
||||
title: Text(
|
||||
'无人机机场与设备状态',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.notifications_none,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
@@ -197,11 +198,11 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -210,12 +211,12 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'机场状态',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -261,11 +262,11 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -276,12 +277,12 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'无人机状态',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -292,8 +293,8 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isOnline
|
||||
? const Color(0xFF00B42A).withOpacity(0.1)
|
||||
: const Color(0xFFFF7D00).withOpacity(0.1),
|
||||
? context.appColors.success.withOpacity(0.1)
|
||||
: context.appColors.warning.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
@@ -301,8 +302,8 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: isOnline
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFFF7D00),
|
||||
? context.appColors.success
|
||||
: context.appColors.warning,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -325,10 +326,10 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
children: [
|
||||
Text(
|
||||
_uavDetail?.droneCallsign ?? '无人机 - 01',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -343,8 +344,8 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
Icons.keyboard_arrow_right,
|
||||
size: 16,
|
||||
color: isOnline
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFFC9CDD4),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textTertiary,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -352,8 +353,8 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: isOnline
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF86909C),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -369,11 +370,11 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -382,12 +383,12 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'快捷操作',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -397,7 +398,7 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.flight_takeoff,
|
||||
label: '开舱',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -406,7 +407,7 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.flight,
|
||||
label: '起飞准备',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -415,7 +416,7 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.home,
|
||||
label: '返航',
|
||||
color: const Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -424,7 +425,7 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
child: _buildQuickActionButton(
|
||||
icon: Icons.task,
|
||||
label: '任务下发',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -458,7 +459,7 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textSecondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -471,14 +472,14 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -487,14 +488,14 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00B42A).withOpacity(0.1),
|
||||
color: context.appColors.success.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
status,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -514,28 +515,28 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
progress,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(Icons.arrow_forward_ios, size: 12, color: Color(0xFF86909C)),
|
||||
Icon(Icons.arrow_forward_ios, size: 12, color: context.appColors.textTertiary),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -544,32 +545,32 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
Widget _buildWeatherRow() {
|
||||
return Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'气象条件',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: const [
|
||||
Icon(Icons.wb_sunny, size: 16, color: Color(0xFFFF7D00)),
|
||||
SizedBox(width: 4),
|
||||
children: [
|
||||
Icon(Icons.wb_sunny, size: 16, color: context.appColors.warning),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'晴',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'25°C',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textPrimary),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'东南风 2级',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textPrimary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -583,9 +584,9 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'电量',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
@@ -593,11 +594,11 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: LinearProgressIndicator(
|
||||
value: capacity / 100,
|
||||
backgroundColor: const Color(0xFFF2F3F5),
|
||||
backgroundColor: context.appColors.fillBackground,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
capacity > 20
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFFF7D00),
|
||||
? context.appColors.success
|
||||
: context.appColors.warning,
|
||||
),
|
||||
minHeight: 6,
|
||||
),
|
||||
@@ -609,8 +610,8 @@ class _DroneStationStatusPageState extends State<DroneStationStatusPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: capacity > 20
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFFF7D00),
|
||||
? context.appColors.success
|
||||
: context.appColors.warning,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:volc_engine_rtc/volc_engine_rtc.dart' as volc;
|
||||
@@ -658,24 +659,24 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return BlocProvider.value(
|
||||
value: _bloc,
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'无人机视频回传 / 远程控制',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
if (_effectiveCameraList.isNotEmpty ||
|
||||
@@ -697,11 +698,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
value: false,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
children: [
|
||||
Icon(
|
||||
Icons.flight,
|
||||
size: 16,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -715,11 +716,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
value: true,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
children: [
|
||||
Icon(
|
||||
Icons.home_work,
|
||||
size: 16,
|
||||
color: Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -737,9 +738,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
}
|
||||
},
|
||||
isDense: true,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -748,11 +749,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
DropdownButtonHideUnderline(
|
||||
child: DropdownButton<CameraInfo>(
|
||||
value: _currentCamera,
|
||||
hint: const Text(
|
||||
hint: Text(
|
||||
'选择摄像头',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
items: _effectiveCameraList.map((camera) {
|
||||
@@ -767,8 +768,8 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
: Icons.videocam,
|
||||
size: 16,
|
||||
color: _useBackupSource
|
||||
? const Color(0xFFFF7D00)
|
||||
: const Color(0xFF165DFF),
|
||||
? context.appColors.warning
|
||||
: context.appColors.primary,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -785,9 +786,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
}
|
||||
},
|
||||
isDense: true,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -799,7 +800,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
centerTitle: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.settings, color: context.appColors.textPrimary),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
@@ -927,7 +928,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
|
||||
Widget _buildTabBar() {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -954,8 +955,8 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFFF2F3F5),
|
||||
? context.appColors.primary
|
||||
: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
@@ -964,7 +965,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isSelected ? Colors.white : const Color(0xFF4E5969),
|
||||
color: isSelected
|
||||
? Colors.white
|
||||
: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1029,7 +1032,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
_currentLensType ?? UavLensType.wide,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF165DFF),
|
||||
backgroundColor: context.appColors.primary,
|
||||
),
|
||||
child: const Text('重试'),
|
||||
),
|
||||
@@ -1151,11 +1154,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -1182,15 +1185,15 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1202,11 +1205,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -1215,12 +1218,12 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'AI 识别结果',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -1237,24 +1240,24 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
onTap: () {},
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.warning_amber_rounded,
|
||||
color: Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 14, color: context.appColors.textPrimary),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
count,
|
||||
style: const TextStyle(fontSize: 14, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 14, color: context.appColors.textSecondary),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(Icons.chevron_right, color: Color(0xFF86909C), size: 20),
|
||||
Icon(Icons.chevron_right, color: context.appColors.textTertiary, size: 20),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -1270,9 +1273,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.grey.withOpacity(0.2)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -1325,9 +1328,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Transform.rotate(
|
||||
angle: (_currentHeading ?? 0) * pi / 180,
|
||||
alignment: Alignment.center,
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.flight,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 32,
|
||||
),
|
||||
),
|
||||
@@ -1344,7 +1347,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green,
|
||||
color: context.appColors.success,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1410,10 +1413,10 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
@@ -1427,8 +1430,8 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
label: _isPaused ? '恢复' : '暂停',
|
||||
icon: _isPaused ? Icons.play_arrow : Icons.pause,
|
||||
color: _isPaused
|
||||
? const Color(0xFF00B42A)
|
||||
: const Color(0xFFFF7D00),
|
||||
? context.appColors.success
|
||||
: context.appColors.warning,
|
||||
onTap: () {
|
||||
if (_isPaused) {
|
||||
_sendFlightCommand('flighttask_recovery');
|
||||
@@ -1442,7 +1445,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
_buildActionBtn(
|
||||
label: '返航',
|
||||
icon: Icons.flight_land,
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {
|
||||
_sendFlightCommand('return_home');
|
||||
},
|
||||
@@ -1544,9 +1547,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF7F8FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.grey.withOpacity(0.2)),
|
||||
border: Border.all(color: context.appColors.divider),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -1599,9 +1602,9 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Transform.rotate(
|
||||
angle: (_currentHeading ?? 0) * pi / 180,
|
||||
alignment: Alignment.center,
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.flight,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 32,
|
||||
),
|
||||
),
|
||||
@@ -1621,7 +1624,7 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.green,
|
||||
color: context.appColors.success,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Row(
|
||||
@@ -1689,11 +1692,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
child: Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -1706,17 +1709,17 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFC9CDD4),
|
||||
color: context.appColors.fillBackground,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 16,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.arrow_drop_up,
|
||||
size: 32,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
@@ -1724,10 +1727,10 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.arrow_drop_down,
|
||||
size: 32,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
@@ -1735,10 +1738,10 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
Positioned(
|
||||
left: 16,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.arrow_left,
|
||||
size: 32,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
@@ -1746,10 +1749,10 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
Positioned(
|
||||
right: 16,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
icon: Icon(
|
||||
Icons.arrow_right,
|
||||
size: 32,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
@@ -1766,11 +1769,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
@@ -1793,11 +1796,11 @@ class _DroneVideoControlPageState extends State<DroneVideoControlPage> {
|
||||
onTap: () {},
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, size: 28, color: const Color(0xFF4E5969)),
|
||||
Icon(icon, size: 28, color: context.appColors.textSecondary),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textSecondary),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import '../../../../../core/router/route_paths.dart';
|
||||
import '../widgets/robot_header_card.dart';
|
||||
import '../widgets/robot_status_bar.dart';
|
||||
@@ -17,12 +18,12 @@ class RobotControlPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F6F8),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Column(
|
||||
@@ -32,19 +33,19 @@ class RobotControlPage extends StatelessWidget {
|
||||
robot['alias'] != null && (robot['alias'] as String).isNotEmpty
|
||||
? robot['alias']
|
||||
: '暂无别名',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
robot['name'] ?? '', // 🔥 使用 name 字段(长序列号 deviceName)
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
@@ -55,7 +56,7 @@ class RobotControlPage extends StatelessWidget {
|
||||
centerTitle: true,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit_outlined, color: Color(0xFF1D2129)),
|
||||
icon: Icon(Icons.edit_outlined, color: context.appColors.textPrimary),
|
||||
onPressed: () {},
|
||||
),
|
||||
],
|
||||
@@ -107,13 +108,13 @@ class RobotControlPage extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -123,12 +124,12 @@ class RobotControlPage extends StatelessWidget {
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.route,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -137,12 +138,12 @@ class RobotControlPage extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'路径规划',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
@@ -150,16 +151,16 @@ class RobotControlPage extends StatelessWidget {
|
||||
'查看和编辑机器人巡检路径',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import '../../../../../core/di/injection.dart';
|
||||
import '../../../../../core/logging/i_logger_service.dart';
|
||||
import '../../../../devices/presentation/bloc/devices_cubit.dart';
|
||||
@@ -57,15 +58,15 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
content: Text(state.message),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is RobotListLoading) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(color: context.appColors.primary),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
onRefresh: () async {
|
||||
context.read<RobotListBloc>().add(const RobotListRefresh());
|
||||
},
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
children: [
|
||||
@@ -118,13 +119,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
margin: const EdgeInsets.fromLTRB(16, 16, 16, 12),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -153,10 +154,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: _selectedType == 'inspection'
|
||||
? const LinearGradient(
|
||||
? LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFFE8F4FF), Color(0xFFFFFFFF)],
|
||||
colors: [
|
||||
context.appColors.primary.withOpacity(0.1),
|
||||
context.appColors.cardBackground,
|
||||
],
|
||||
)
|
||||
: null,
|
||||
color: _selectedType != 'inspection'
|
||||
@@ -172,8 +176,8 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'inspection'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF1D2129),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -189,10 +193,10 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'${inspectionRobots.length}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -204,15 +208,15 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'inspection'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF00B42A),
|
||||
? context.appColors.primary
|
||||
: context.appColors.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(width: 1, height: 100, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 100, color: context.appColors.divider),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@@ -236,10 +240,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: _selectedType == 'cleaning'
|
||||
? const LinearGradient(
|
||||
? LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFFE8F4FF), Color(0xFFFFFFFF)],
|
||||
colors: [
|
||||
context.appColors.primary.withOpacity(0.1),
|
||||
context.appColors.cardBackground,
|
||||
],
|
||||
)
|
||||
: null,
|
||||
color: _selectedType != 'cleaning'
|
||||
@@ -255,8 +262,8 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'cleaning'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF1D2129),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -272,10 +279,10 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'${cleaningRobots.length}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -287,15 +294,15 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'cleaning'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF00B42A),
|
||||
? context.appColors.primary
|
||||
: context.appColors.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(width: 1, height: 100, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 100, color: context.appColors.divider),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@@ -317,10 +324,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: _selectedType == 'weeding'
|
||||
? const LinearGradient(
|
||||
? LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFFE8F4FF), Color(0xFFFFFFFF)],
|
||||
colors: [
|
||||
context.appColors.primary.withOpacity(0.1),
|
||||
context.appColors.cardBackground,
|
||||
],
|
||||
)
|
||||
: null,
|
||||
color: _selectedType != 'weeding'
|
||||
@@ -336,8 +346,8 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'weeding'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF1D2129),
|
||||
? context.appColors.primary
|
||||
: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -357,8 +367,8 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: _selectedType == 'weeding'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF00B42A),
|
||||
? context.appColors.primary
|
||||
: context.appColors.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -370,8 +380,8 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _selectedType == 'weeding'
|
||||
? const Color(0xFF165DFF)
|
||||
: const Color(0xFF00B42A),
|
||||
? context.appColors.primary
|
||||
: context.appColors.success,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -395,13 +405,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
margin: const EdgeInsets.fromLTRB(16, 0, 16, 12),
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -410,25 +420,25 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
_buildStatusItem(
|
||||
value: '$onlineCount',
|
||||
label: '在线设备',
|
||||
valueColor: const Color(0xFF165DFF),
|
||||
valueColor: context.appColors.primary,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
value: '$workingCount',
|
||||
label: '作业中',
|
||||
valueColor: const Color(0xFF00B42A),
|
||||
valueColor: context.appColors.success,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
value: '$standbyCount',
|
||||
label: '待命',
|
||||
valueColor: const Color(0xFFFF7D00),
|
||||
valueColor: context.appColors.warning,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
value: '$faultCount',
|
||||
label: '离线数',
|
||||
valueColor: const Color(0xFFF53F3F),
|
||||
valueColor: context.appColors.danger,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -454,7 +464,10 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -482,25 +495,25 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
margin: const EdgeInsets.fromLTRB(16, 0, 16, 12),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'当前任务',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -522,13 +535,13 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(
|
||||
Expanded(
|
||||
child: Text(
|
||||
'巡检任务-逆变器区巡检',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -538,14 +551,14 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'进行中',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -578,11 +591,11 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
children: [
|
||||
TextSpan(
|
||||
text: label,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
TextSpan(
|
||||
text: value,
|
||||
style: const TextStyle(fontSize: 13, color: Color(0xFF1D2129)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textPrimary),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -602,12 +615,12 @@ class _RobotListViewState extends State<RobotListView> {
|
||||
|
||||
if (filteredRobots.isEmpty) {
|
||||
return [
|
||||
const Center(
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(32),
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Text(
|
||||
'暂无机器人数据',
|
||||
style: TextStyle(fontSize: 14, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 14, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../domain/entities/device_entity.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
/// 设备列表项 Widget
|
||||
class DeviceItemWidget extends StatelessWidget {
|
||||
@@ -20,13 +21,13 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -46,25 +47,25 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
device.name,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'ID: ${device.deviceId}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// 状态标签
|
||||
_buildStatusTag(device.status),
|
||||
_buildStatusTag(context, device.status),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -117,26 +118,26 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusTag(String status) {
|
||||
Widget _buildStatusTag(BuildContext context, String status) {
|
||||
Color bgColor;
|
||||
Color textColor;
|
||||
|
||||
switch (status) {
|
||||
case '在线':
|
||||
bgColor = const Color(0xFFF0F9FF);
|
||||
textColor = const Color(0xFF00B42A);
|
||||
bgColor = context.appColors.success.withOpacity(0.1);
|
||||
textColor = context.appColors.success;
|
||||
break;
|
||||
case '离线':
|
||||
bgColor = const Color(0xFFF5F0FF);
|
||||
textColor = const Color(0xFFF53F3F);
|
||||
bgColor = context.appColors.danger.withOpacity(0.1);
|
||||
textColor = context.appColors.danger;
|
||||
break;
|
||||
case '异常':
|
||||
bgColor = const Color(0xFFFFF7E6);
|
||||
textColor = const Color(0xFFFF7D00);
|
||||
bgColor = context.appColors.warning.withOpacity(0.1);
|
||||
textColor = context.appColors.warning;
|
||||
break;
|
||||
default:
|
||||
bgColor = const Color(0xFFF5F5F5);
|
||||
textColor = const Color(0xFF86909C);
|
||||
bgColor = context.appColors.fillBackground;
|
||||
textColor = context.appColors.textTertiary;
|
||||
}
|
||||
|
||||
return Container(
|
||||
@@ -155,6 +156,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
if (device.type == 'inverter') {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.power}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.inverter')} | ${AppLocalizations.of(context).translate('device_list_v2.power')}',
|
||||
),
|
||||
@@ -162,6 +164,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
dataItems.add(const SizedBox(width: 16));
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.todayEnergy}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.today_energy')}',
|
||||
),
|
||||
@@ -170,6 +173,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
if (device.current != null) {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.current}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.current')}',
|
||||
),
|
||||
@@ -179,6 +183,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
if (device.temperature != null) {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.temperature}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.temperature')}',
|
||||
),
|
||||
@@ -187,6 +192,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
} else if (device.type == 'module') {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.power}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.power')}',
|
||||
),
|
||||
@@ -195,6 +201,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
if (device.radiation != null) {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'${device.radiation}',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.radiation')}',
|
||||
),
|
||||
@@ -203,6 +210,7 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
} else {
|
||||
dataItems.add(
|
||||
_buildDataItem(
|
||||
context,
|
||||
'--',
|
||||
'${AppLocalizations.of(context).translate('device_list_v2.data')}',
|
||||
),
|
||||
@@ -212,22 +220,22 @@ class DeviceItemWidget extends StatelessWidget {
|
||||
return Row(children: dataItems);
|
||||
}
|
||||
|
||||
Widget _buildDataItem(String value, String unit) {
|
||||
Widget _buildDataItem(BuildContext context, String value, String unit) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
unit,
|
||||
style: const TextStyle(fontSize: 12, color: Color(0xFF4E5969)),
|
||||
style: TextStyle(fontSize: 12, color: context.appColors.textSecondary),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
import '../../domain/entities/drone_station_entity.dart';
|
||||
|
||||
@@ -23,12 +24,15 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
colors: [Colors.white, const Color(0xFFF8F9FA)],
|
||||
colors: [
|
||||
context.appColors.cardBackground,
|
||||
context.appColors.fillBackground,
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.08),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
@@ -43,8 +47,8 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
const Color(0xFF165DFF).withOpacity(0.05),
|
||||
const Color(0xFF165DFF).withOpacity(0.02),
|
||||
context.appColors.primary.withOpacity(0.05),
|
||||
context.appColors.primary.withOpacity(0.02),
|
||||
],
|
||||
),
|
||||
borderRadius: const BorderRadius.only(
|
||||
@@ -58,12 +62,12 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.home_max_rounded,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
@@ -77,18 +81,18 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
station.callsign.isNotEmpty
|
||||
? station.callsign
|
||||
: '未知机场',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'SN: ${station.deviceSn}',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -100,7 +104,7 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
|
||||
const Divider(height: 1, color: Color(0xFFE5E6EB)),
|
||||
Divider(height: 1, color: context.appColors.divider),
|
||||
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -109,16 +113,19 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
children: [
|
||||
// 机场基础信息卡片
|
||||
_buildSectionCard(
|
||||
context,
|
||||
title: '机场信息',
|
||||
icon: Icons.settings_rounded,
|
||||
children: [
|
||||
_buildInfoRowWithIcon(
|
||||
context,
|
||||
Icons.tag_rounded,
|
||||
'无人机序列号',
|
||||
station.deviceSn,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
_buildInfoRowWithIcon(
|
||||
context,
|
||||
Icons.router_rounded,
|
||||
'机场序列号',
|
||||
station.gatewaySn,
|
||||
@@ -335,7 +342,8 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// 区块卡片
|
||||
Widget _buildSectionCard({
|
||||
Widget _buildSectionCard(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required IconData icon,
|
||||
required List<Widget> children,
|
||||
@@ -343,11 +351,11 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.04),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
@@ -358,14 +366,14 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 18, color: const Color(0xFF165DFF)),
|
||||
Icon(icon, size: 18, color: context.appColors.primary),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -378,25 +386,30 @@ class DroneStationItemCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// 信息行(带图标)
|
||||
Widget _buildInfoRowWithIcon(IconData icon, String label, String value) {
|
||||
Widget _buildInfoRowWithIcon(
|
||||
BuildContext context,
|
||||
IconData icon,
|
||||
String label,
|
||||
String value,
|
||||
) {
|
||||
return Row(
|
||||
children: [
|
||||
Icon(icon, size: 16, color: const Color(0xFF86909C)),
|
||||
Icon(icon, size: 16, color: context.appColors.textTertiary),
|
||||
const SizedBox(width: 8),
|
||||
SizedBox(
|
||||
width: 70,
|
||||
child: Text(
|
||||
'$label:',
|
||||
style: const TextStyle(fontSize: 11, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 11, color: context.appColors.textTertiary),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
/// 底部操作按钮
|
||||
class RobotActionButtons extends StatelessWidget {
|
||||
@@ -13,7 +14,7 @@ class RobotActionButtons extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _buildActionButton(
|
||||
label: '开始',
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -21,7 +22,7 @@ class RobotActionButtons extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _buildActionButton(
|
||||
label: '暂停',
|
||||
color: const Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
@@ -29,9 +30,9 @@ class RobotActionButtons extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _buildActionButton(
|
||||
label: '返航',
|
||||
color: Colors.white,
|
||||
borderColor: const Color(0xFFC9CDD4),
|
||||
textColor: const Color(0xFF4E5969),
|
||||
color: context.appColors.cardBackground,
|
||||
borderColor: context.appColors.textTertiary,
|
||||
textColor: context.appColors.textSecondary,
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
/// 检查清单
|
||||
class RobotChecklist extends StatelessWidget {
|
||||
@@ -11,39 +12,44 @@ class RobotChecklist extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'检查清单',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
_buildCheckItem('逆变器', true),
|
||||
_buildCheckItem('汇流箱', true),
|
||||
_buildCheckItem('支架结构', true),
|
||||
_buildCheckItem('线缆通道', false, isWarning: true),
|
||||
_buildCheckItem('环境与杂物', false),
|
||||
_buildCheckItem(context, '逆变器', true),
|
||||
_buildCheckItem(context, '汇流箱', true),
|
||||
_buildCheckItem(context, '支架结构', true),
|
||||
_buildCheckItem(context, '线缆通道', false, isWarning: true),
|
||||
_buildCheckItem(context, '环境与杂物', false),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildCheckItem(String label, bool isDone, {bool isWarning = false}) {
|
||||
Widget _buildCheckItem(
|
||||
BuildContext context,
|
||||
String label,
|
||||
bool isDone, {
|
||||
bool isWarning = false,
|
||||
}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 6),
|
||||
child: Row(
|
||||
@@ -51,28 +57,28 @@ class RobotChecklist extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isDone)
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.check_circle,
|
||||
color: Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
size: 20,
|
||||
)
|
||||
else if (isWarning)
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.error_outline,
|
||||
color: Color(0xFFFF7D00),
|
||||
color: context.appColors.warning,
|
||||
size: 20,
|
||||
)
|
||||
else
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.radio_button_unchecked,
|
||||
color: Color(0xFFC9CDD4),
|
||||
color: context.appColors.textTertiary,
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import '../../../../../../core/di/injection.dart';
|
||||
import '../../../../devices/presentation/bloc/devices_cubit.dart';
|
||||
import '../../../../devices/domain/entities/device_entity.dart';
|
||||
@@ -61,25 +62,25 @@ class RobotControlPanel extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'控制面板',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -96,29 +97,29 @@ class RobotControlPanel extends StatelessWidget {
|
||||
width: 120,
|
||||
height: 120,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF5F6F8),
|
||||
color: context.appColors.fillBackground,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
// 上
|
||||
Positioned(
|
||||
top: 8,
|
||||
child: _buildDirectionButton(Icons.arrow_upward, () {}),
|
||||
child: _buildDirectionButton(context, Icons.arrow_upward, () {}),
|
||||
),
|
||||
// 下
|
||||
Positioned(
|
||||
bottom: 8,
|
||||
child: _buildDirectionButton(Icons.arrow_downward, () {}),
|
||||
child: _buildDirectionButton(context, Icons.arrow_downward, () {}),
|
||||
),
|
||||
// 左
|
||||
Positioned(
|
||||
left: 8,
|
||||
child: _buildDirectionButton(Icons.arrow_back, () {}),
|
||||
child: _buildDirectionButton(context, Icons.arrow_back, () {}),
|
||||
),
|
||||
// 右
|
||||
Positioned(
|
||||
right: 8,
|
||||
child: _buildDirectionButton(Icons.arrow_forward, () {}),
|
||||
child: _buildDirectionButton(context, Icons.arrow_forward, () {}),
|
||||
),
|
||||
// 中心按钮
|
||||
Container(
|
||||
@@ -133,7 +134,7 @@ class RobotControlPanel extends StatelessWidget {
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.3),
|
||||
color: context.appColors.primary.withOpacity(0.3),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
@@ -146,18 +147,18 @@ class RobotControlPanel extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
// 速度档位
|
||||
const Text(
|
||||
Text(
|
||||
'速度档位',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFF86909C)),
|
||||
style: TextStyle(fontSize: 13, color: context.appColors.textTertiary),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildSpeedButton('低速', false, () {})),
|
||||
Expanded(child: _buildSpeedButton(context, '低速', false, () {})),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: _buildSpeedButton('中速', true, () {})),
|
||||
Expanded(child: _buildSpeedButton(context, '中速', true, () {})),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(child: _buildSpeedButton('高速', false, () {})),
|
||||
Expanded(child: _buildSpeedButton(context, '高速', false, () {})),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -166,35 +167,46 @@ class RobotControlPanel extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDirectionButton(IconData icon, VoidCallback onTap) {
|
||||
Widget _buildDirectionButton(
|
||||
BuildContext context,
|
||||
IconData icon,
|
||||
VoidCallback onTap,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
shape: BoxShape.circle,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Icon(icon, color: const Color(0xFF1D2129), size: 20),
|
||||
child: Icon(icon, color: context.appColors.textPrimary, size: 20),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSpeedButton(String label, bool isSelected, VoidCallback onTap) {
|
||||
Widget _buildSpeedButton(
|
||||
BuildContext context,
|
||||
String label,
|
||||
bool isSelected,
|
||||
VoidCallback onTap,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? const Color(0xFF165DFF) : const Color(0xFFF5F6F8),
|
||||
color: isSelected
|
||||
? context.appColors.primary
|
||||
: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
@@ -203,7 +215,9 @@ class RobotControlPanel extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isSelected ? Colors.white : const Color(0xFF4E5969),
|
||||
color: isSelected
|
||||
? Colors.white
|
||||
: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:maibu_satabot_v2/core/app/app_user_cubit.dart';
|
||||
import 'package:maibu_satabot_v2/core/app/app_user_state.dart'; // 🔥 导入 AppUserState
|
||||
import 'package:maibu_satabot_v2/core/consts/tcp_consts.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/remote_control/presentation/widgets/webrtc/webrtc_local_player.dart';
|
||||
import '../../../device_run_param/presentation/pages/robot_param_settings_page.dart';
|
||||
|
||||
@@ -91,13 +92,13 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -114,10 +115,10 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
(widget.robot['alias'] as String?)?.isNotEmpty == true
|
||||
? widget.robot['alias'] as String
|
||||
: '暂无别名',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -125,9 +126,9 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
widget.robot['name'] as String,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -142,14 +143,14 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
Icon(
|
||||
Icons.signal_cellular_alt,
|
||||
size: 16,
|
||||
color: const Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Text(
|
||||
Text(
|
||||
'强',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -160,14 +161,14 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00B42A).withOpacity(0.1),
|
||||
color: context.appColors.success.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'在线',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF00B42A),
|
||||
color: context.appColors.success,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
@@ -184,10 +185,10 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.settings,
|
||||
size: 20,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -264,11 +265,11 @@ class _RobotHeaderCardState extends State<RobotHeaderCard> {
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: isSelected
|
||||
? const Color(0xFF165DFF)
|
||||
: Colors.grey[200],
|
||||
? context.appColors.primary
|
||||
: context.appColors.fillBackground,
|
||||
foregroundColor: isSelected
|
||||
? Colors.white
|
||||
: Colors.grey[700],
|
||||
: context.appColors.textSecondary,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
/// 机器人卡片组件
|
||||
class RobotItemCard extends StatelessWidget {
|
||||
@@ -32,13 +33,13 @@ class RobotItemCard extends StatelessWidget {
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -53,7 +54,7 @@ class RobotItemCard extends StatelessWidget {
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: ClipRRect(
|
||||
@@ -74,10 +75,10 @@ class RobotItemCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
alias != null && alias!.isNotEmpty ? alias! : '暂无别名',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -85,9 +86,9 @@ class RobotItemCard extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
name, // 🔥 显示完整的长序列号 (deviceName)
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
@@ -96,7 +97,7 @@ class RobotItemCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
// 状态标签
|
||||
_buildStatusTag(status),
|
||||
_buildStatusTag(context, status),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -118,10 +119,10 @@ class RobotItemCard extends StatelessWidget {
|
||||
: Icons.battery_alert,
|
||||
size: 16,
|
||||
color: battery > 50
|
||||
? const Color(0xFF00B42A)
|
||||
? context.appColors.success
|
||||
: battery > 20
|
||||
? const Color(0xFFFF7D00)
|
||||
: const Color(0xFFF53F3F),
|
||||
? context.appColors.warning
|
||||
: context.appColors.danger,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
@@ -130,10 +131,10 @@ class RobotItemCard extends StatelessWidget {
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: battery > 50
|
||||
? const Color(0xFF00B42A)
|
||||
? context.appColors.success
|
||||
: battery > 20
|
||||
? const Color(0xFFFF7D00)
|
||||
: const Color(0xFFF53F3F),
|
||||
? context.appColors.warning
|
||||
: context.appColors.danger,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -145,7 +146,7 @@ class RobotItemCard extends StatelessWidget {
|
||||
).translate('device_list_v2.battery_level'),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -158,10 +159,10 @@ class RobotItemCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
task,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -173,7 +174,7 @@ class RobotItemCard extends StatelessWidget {
|
||||
).translate('device_list_v2.current_task'),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -187,18 +188,18 @@ class RobotItemCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusTag(String status) {
|
||||
Widget _buildStatusTag(BuildContext context, String status) {
|
||||
Color bgColor;
|
||||
Color textColor;
|
||||
|
||||
switch (status) {
|
||||
case '在线':
|
||||
bgColor = const Color(0xFFF0F9FF);
|
||||
textColor = const Color(0xFF00B42A);
|
||||
bgColor = context.appColors.success.withOpacity(0.1);
|
||||
textColor = context.appColors.success;
|
||||
break;
|
||||
default:
|
||||
bgColor = const Color(0xFFF5F0FF);
|
||||
textColor = const Color(0xFFF53F3F);
|
||||
bgColor = context.appColors.danger.withOpacity(0.1);
|
||||
textColor = context.appColors.danger;
|
||||
}
|
||||
|
||||
return Container(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import '../../../../../components/device_status_modal.dart';
|
||||
import '../../../../devices/presentation/bloc/device_status_bloc.dart';
|
||||
import '../../../../devices/presentation/bloc/device_status_state.dart';
|
||||
@@ -49,8 +50,8 @@ class RobotStatusBar extends StatelessWidget {
|
||||
String mode = '--';
|
||||
String battery = '--';
|
||||
String signal = '--';
|
||||
Color signalColor = const Color(0xFF86909C);
|
||||
Color batteryColor = const Color(0xFF86909C);
|
||||
Color signalColor = context.appColors.textTertiary;
|
||||
Color batteryColor = context.appColors.textTertiary;
|
||||
|
||||
if (state is DeviceStatusUpdated) {
|
||||
final s = state.status;
|
||||
@@ -61,38 +62,38 @@ class RobotStatusBar extends StatelessWidget {
|
||||
final qual = s.qual;
|
||||
if (qual >= 4) {
|
||||
signal = '强';
|
||||
signalColor = const Color(0xFF00B42A);
|
||||
signalColor = context.appColors.success;
|
||||
} else if (qual >= 2) {
|
||||
signal = '中';
|
||||
signalColor = const Color(0xFFFF7D00);
|
||||
signalColor = context.appColors.warning;
|
||||
} else if (qual >= 1) {
|
||||
signal = '弱';
|
||||
signalColor = const Color(0xFFF53F3F);
|
||||
signalColor = context.appColors.danger;
|
||||
} else {
|
||||
signal = '无';
|
||||
signalColor = const Color(0xFF86909C);
|
||||
signalColor = context.appColors.textTertiary;
|
||||
}
|
||||
|
||||
final batValue = int.tryParse(battery) ?? 0;
|
||||
if (batValue > 50) {
|
||||
batteryColor = const Color(0xFF00B42A);
|
||||
batteryColor = context.appColors.success;
|
||||
} else if (batValue > 20) {
|
||||
batteryColor = const Color(0xFFFF7D00);
|
||||
batteryColor = context.appColors.warning;
|
||||
} else if (batValue > 0) {
|
||||
batteryColor = const Color(0xFFF53F3F);
|
||||
batteryColor = context.appColors.danger;
|
||||
}
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -102,25 +103,29 @@ class RobotStatusBar extends StatelessWidget {
|
||||
child: Row(
|
||||
children: [
|
||||
_buildStatusItem(
|
||||
context,
|
||||
label: '转速',
|
||||
value: speed,
|
||||
unit: 'rpm',
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
context,
|
||||
label: '模式',
|
||||
value: mode,
|
||||
unit: '',
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
context,
|
||||
label: '电量',
|
||||
value: battery,
|
||||
unit: '%',
|
||||
valueColor: batteryColor,
|
||||
),
|
||||
Container(width: 1, height: 40, color: const Color(0xFFE5E6EB)),
|
||||
Container(width: 1, height: 40, color: context.appColors.divider),
|
||||
_buildStatusItem(
|
||||
context,
|
||||
label: '信号',
|
||||
value: signal,
|
||||
unit: '',
|
||||
@@ -130,10 +135,10 @@ class RobotStatusBar extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -143,7 +148,8 @@ class RobotStatusBar extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusItem({
|
||||
Widget _buildStatusItem(
|
||||
BuildContext context, {
|
||||
required String label,
|
||||
required String value,
|
||||
required String unit,
|
||||
@@ -154,9 +160,9 @@ class RobotStatusBar extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
@@ -169,7 +175,7 @@ class RobotStatusBar extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: valueColor ?? const Color(0xFF1D2129),
|
||||
color: valueColor ?? context.appColors.textPrimary,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -180,7 +186,7 @@ class RobotStatusBar extends StatelessWidget {
|
||||
unit,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: valueColor ?? const Color(0xFF1D2129),
|
||||
color: valueColor ?? context.appColors.textPrimary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
/// 当前任务信息
|
||||
class RobotTaskInfo extends StatelessWidget {
|
||||
@@ -11,25 +12,25 @@ class RobotTaskInfo extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
'当前任务',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
@@ -38,24 +39,24 @@ class RobotTaskInfo extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
robot['task'] ?? '逆变器区巡检',
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF165DFF).withOpacity(0.1),
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: const Text(
|
||||
child: Text(
|
||||
'进行中',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:maibu_satabot_v2/core/di/injection.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_bloc.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_event.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/presentation/bloc/home_v2_state.dart';
|
||||
@@ -39,7 +40,7 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF5F7FA),
|
||||
backgroundColor: context.appColors.pageBackground,
|
||||
body: BlocConsumer<HomeV2Bloc, HomeV2State>(
|
||||
listener: (context, state) {
|
||||
// 🔥 监听错误状态,显示友好提示
|
||||
@@ -49,7 +50,7 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
content: Text(state.message),
|
||||
duration: const Duration(seconds: 2),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.orange,
|
||||
backgroundColor: context.appColors.warning,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -61,15 +62,18 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.error_outline,
|
||||
size: 48,
|
||||
color: Colors.orange,
|
||||
color: context.appColors.warning,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
state.message,
|
||||
style: const TextStyle(fontSize: 14, color: Colors.grey),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
@@ -90,13 +94,13 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
elevation: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
background: Container(
|
||||
padding: const EdgeInsets.fromLTRB(16, 40, 16, 16),
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: SiteSelectorWidget()),
|
||||
@@ -124,25 +128,25 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
vertical: 8,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF2F3F5),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.cloud_queue,
|
||||
size: 16,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.weather'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF4E5969),
|
||||
color: context.appColors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -157,16 +161,16 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
vertical: 8,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFF0F0),
|
||||
color: context.appColors.danger.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.warning_amber_rounded,
|
||||
size: 16,
|
||||
color: Color(0xFFF53F3F),
|
||||
color: context.appColors.danger,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Expanded(
|
||||
@@ -174,17 +178,17 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.emergency_alarm'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFFF53F3F),
|
||||
color: context.appColors.danger,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 12,
|
||||
color: Color(0xFFF53F3F),
|
||||
color: context.appColors.danger,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -221,8 +225,8 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
}
|
||||
|
||||
// 🔥 Initial/Loading 状态显示加载指示器
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF165DFF)),
|
||||
return Center(
|
||||
child: CircularProgressIndicator(color: context.appColors.primary),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -262,7 +266,7 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: context.appColors.cardBackground,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
|
||||
),
|
||||
@@ -284,10 +288,10 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.select_site'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
@@ -310,9 +314,9 @@ class _HomeV2PageState extends State<HomeV2Page> {
|
||||
)
|
||||
: null,
|
||||
trailing: isSelected
|
||||
? const Icon(
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
)
|
||||
: null,
|
||||
onTap: () {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/domain/entities/home_entity.dart';
|
||||
|
||||
class PlantOverviewCard extends StatelessWidget {
|
||||
@@ -14,10 +15,10 @@ class PlantOverviewCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).translate('home_v2.plant_overview'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@@ -29,11 +30,11 @@ class PlantOverviewCard extends StatelessWidget {
|
||||
image: AssetImage(overview.backgroundImage),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/domain/entities/home_entity.dart';
|
||||
|
||||
class PowerCard extends StatelessWidget {
|
||||
@@ -24,11 +25,11 @@ class PowerCard extends StatelessWidget {
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/domain/entities/home_entity.dart';
|
||||
|
||||
class PowerTrendChart extends StatelessWidget {
|
||||
@@ -25,25 +26,27 @@ class PowerTrendChart extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).translate('home_v2.power_trend'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF5F7FA),
|
||||
color: context.appColors.fillBackground,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
_buildTypeButton(
|
||||
context,
|
||||
'day',
|
||||
AppLocalizations.of(context).translate('home_v2.day'),
|
||||
),
|
||||
_buildTypeButton(
|
||||
context,
|
||||
'month',
|
||||
AppLocalizations.of(context).translate('home_v2.month'),
|
||||
),
|
||||
@@ -57,13 +60,13 @@ class PowerTrendChart extends StatelessWidget {
|
||||
height: 220,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -76,13 +79,13 @@ class PowerTrendChart extends StatelessWidget {
|
||||
verticalInterval: 6,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: const Color(0xFFE5E6EB).withOpacity(0.3),
|
||||
color: context.appColors.divider.withOpacity(0.3),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
getDrawingVerticalLine: (value) {
|
||||
return FlLine(
|
||||
color: const Color(0xFFE5E6EB).withOpacity(0.3),
|
||||
color: context.appColors.divider.withOpacity(0.3),
|
||||
strokeWidth: 1,
|
||||
);
|
||||
},
|
||||
@@ -108,8 +111,8 @@ class PowerTrendChart extends StatelessWidget {
|
||||
}
|
||||
return Text(
|
||||
time,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF86909C),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textTertiary,
|
||||
fontSize: 12,
|
||||
),
|
||||
);
|
||||
@@ -126,8 +129,8 @@ class PowerTrendChart extends StatelessWidget {
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(
|
||||
value.toInt().toString(),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF86909C),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textTertiary,
|
||||
fontSize: 12,
|
||||
),
|
||||
);
|
||||
@@ -154,14 +157,14 @@ class PowerTrendChart extends StatelessWidget {
|
||||
.map((e) => FlSpot(e.key.toDouble(), e.value.power))
|
||||
.toList(),
|
||||
isCurved: true,
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
barWidth: 2,
|
||||
dotData: FlDotData(
|
||||
show: true,
|
||||
getDotPainter: (spot, percent, barData, index) {
|
||||
return FlDotCirclePainter(
|
||||
radius: 2,
|
||||
color: const Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -169,8 +172,8 @@ class PowerTrendChart extends StatelessWidget {
|
||||
show: true,
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
const Color(0xFF165DFF).withOpacity(0.2),
|
||||
const Color(0xFF165DFF).withOpacity(0.0),
|
||||
context.appColors.primary.withOpacity(0.2),
|
||||
context.appColors.primary.withOpacity(0.0),
|
||||
],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
@@ -185,7 +188,7 @@ class PowerTrendChart extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTypeButton(String type, String label) {
|
||||
Widget _buildTypeButton(BuildContext context, String type, String label) {
|
||||
final isSelected = trendType == type;
|
||||
return GestureDetector(
|
||||
onTap: () => onToggleType(type),
|
||||
@@ -193,14 +196,16 @@ class PowerTrendChart extends StatelessWidget {
|
||||
width: 50,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? const Color(0xFF165DFF) : Colors.transparent,
|
||||
color: isSelected ? context.appColors.primary : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: isSelected ? Colors.white : const Color(0xFF86909C),
|
||||
color: isSelected
|
||||
? Colors.white
|
||||
: context.appColors.textTertiary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
|
||||
class QuickEntryCard extends StatelessWidget {
|
||||
const QuickEntryCard({super.key});
|
||||
@@ -14,16 +15,16 @@ class QuickEntryCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).translate('home_v2.quick_entry'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -36,6 +37,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
children: [
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.upload_file,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -43,6 +45,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.qr_code_scanner,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -50,6 +53,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.assignment,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -57,6 +61,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.notifications_active,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -64,6 +69,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.map,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -71,6 +77,7 @@ class QuickEntryCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildQuickEntryCard(
|
||||
context,
|
||||
icon: Icons.devices,
|
||||
label: AppLocalizations.of(
|
||||
context,
|
||||
@@ -84,7 +91,11 @@ class QuickEntryCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildQuickEntryCard({required IconData icon, required String label}) {
|
||||
Widget _buildQuickEntryCard(
|
||||
BuildContext context, {
|
||||
required IconData icon,
|
||||
required String label,
|
||||
}) {
|
||||
return InkWell(
|
||||
onTap: () => print('点击:$label'),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@@ -94,26 +105,26 @@ class QuickEntryCard extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(icon, color: const Color(0xFF165DFF), size: 26),
|
||||
Icon(icon, color: context.appColors.primary, size: 26),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF4E5969),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textSecondary,
|
||||
fontSize: 12,
|
||||
height: 1.2,
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/domain/entities/home_entity.dart';
|
||||
|
||||
class StatsGrid extends StatelessWidget {
|
||||
@@ -19,21 +20,23 @@ class StatsGrid extends StatelessWidget {
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
_buildStatCard(
|
||||
context,
|
||||
title: AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.today_generation'),
|
||||
value: _formatNumber(data.todayGeneration),
|
||||
unit: 'kWh',
|
||||
valueColor: const Color(0xFF00B42A),
|
||||
valueColor: context.appColors.success,
|
||||
showArrow: false,
|
||||
),
|
||||
_buildStatCard(
|
||||
context,
|
||||
title: AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.equivalent_hours'),
|
||||
value: data.equivalentHours.toStringAsFixed(1),
|
||||
unit: 'h',
|
||||
valueColor: const Color(0xFF165DFF),
|
||||
valueColor: context.appColors.primary,
|
||||
showArrow: false,
|
||||
),
|
||||
_buildAlarmCard(context, data.alarmCount),
|
||||
@@ -42,7 +45,8 @@ class StatsGrid extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatCard({
|
||||
Widget _buildStatCard(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required String value,
|
||||
required String unit,
|
||||
@@ -52,13 +56,13 @@ class StatsGrid extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -71,22 +75,25 @@ class StatsGrid extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF4E5969),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textSecondary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
],
|
||||
)
|
||||
else
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(color: Color(0xFF4E5969), fontSize: 14),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textSecondary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
@@ -103,7 +110,10 @@ class StatsGrid extends StatelessWidget {
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
unit,
|
||||
style: const TextStyle(color: Color(0xFF4E5969), fontSize: 14),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textSecondary,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -116,13 +126,13 @@ class StatsGrid extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFFF0F0),
|
||||
color: context.appColors.danger.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -135,8 +145,8 @@ class StatsGrid extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).translate('home_v2.alarm_count'),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFF53F3F),
|
||||
style: TextStyle(
|
||||
color: context.appColors.danger,
|
||||
fontSize: 13,
|
||||
),
|
||||
maxLines: 1,
|
||||
@@ -145,8 +155,8 @@ class StatsGrid extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
count.toString(),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFF53F3F),
|
||||
style: TextStyle(
|
||||
color: context.appColors.danger,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -157,14 +167,14 @@ class StatsGrid extends StatelessWidget {
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFFFE8E8),
|
||||
decoration: BoxDecoration(
|
||||
color: context.appColors.danger.withOpacity(0.15),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.notifications_none,
|
||||
size: 24,
|
||||
color: Color(0xFFF53F3F),
|
||||
color: context.appColors.danger,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -176,13 +186,13 @@ class StatsGrid extends StatelessWidget {
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
color: context.appColors.cardBackground,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -197,8 +207,8 @@ class StatsGrid extends StatelessWidget {
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.pending_work_order'),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF4E5969),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textSecondary,
|
||||
fontSize: 13,
|
||||
),
|
||||
maxLines: 1,
|
||||
@@ -207,8 +217,8 @@ class StatsGrid extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
count.toString(),
|
||||
style: const TextStyle(
|
||||
color: Color(0xFF1D2129),
|
||||
style: TextStyle(
|
||||
color: context.appColors.textPrimary,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -219,14 +229,14 @@ class StatsGrid extends StatelessWidget {
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFE8F3FF),
|
||||
decoration: BoxDecoration(
|
||||
color: context.appColors.primary.withOpacity(0.1),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Icon(
|
||||
child: Icon(
|
||||
Icons.content_paste,
|
||||
size: 24,
|
||||
color: Color(0xFF165DFF),
|
||||
color: context.appColors.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
|
||||
import 'package:maibu_satabot_v2/core/theme/AppTheme.dart';
|
||||
import 'package:maibu_satabot_v2/features/v2/home/domain/entities/home_entity.dart';
|
||||
|
||||
class WorkOrderCard extends StatelessWidget {
|
||||
@@ -19,16 +20,16 @@ class WorkOrderCard extends StatelessWidget {
|
||||
AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.pending_work_order'),
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF1D2129),
|
||||
color: context.appColors.textPrimary,
|
||||
),
|
||||
),
|
||||
const Icon(
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 16,
|
||||
color: Color(0xFF86909C),
|
||||
color: context.appColors.textTertiary,
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -37,34 +38,37 @@ class WorkOrderCard extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildWorkOrderCard(
|
||||
context,
|
||||
title: AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.work_order_pending'),
|
||||
count: stats.pending,
|
||||
color: const Color(0xFFF53F3F),
|
||||
bgColor: Colors.white,
|
||||
color: context.appColors.danger,
|
||||
bgColor: context.appColors.cardBackground,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: _buildWorkOrderCard(
|
||||
context,
|
||||
title: AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.work_order_processing'),
|
||||
count: stats.processing,
|
||||
color: const Color(0xFFFF7D00),
|
||||
bgColor: const Color(0xFFFFF7E6),
|
||||
color: context.appColors.warning,
|
||||
bgColor: context.appColors.warning.withOpacity(0.1),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: _buildWorkOrderCard(
|
||||
context,
|
||||
title: AppLocalizations.of(
|
||||
context,
|
||||
).translate('home_v2.work_order_pending_acceptance'),
|
||||
count: stats.pendingAcceptance,
|
||||
color: const Color(0xFF1D2129),
|
||||
bgColor: Colors.white,
|
||||
color: context.appColors.textPrimary,
|
||||
bgColor: context.appColors.cardBackground,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -73,7 +77,8 @@ class WorkOrderCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildWorkOrderCard({
|
||||
Widget _buildWorkOrderCard(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required int count,
|
||||
required Color color,
|
||||
@@ -84,11 +89,11 @@ class WorkOrderCard extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x0D000000),
|
||||
color: context.appColors.cardShadow,
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user