迁移提交

This commit is contained in:
2026-08-25 11:34:32 +08:00
parent 83220869da
commit ca616faf11
28 changed files with 1166 additions and 1017 deletions

View File

@@ -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) {

View File

@@ -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,
),

View File

@@ -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,
);
}
}

View File

@@ -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),

View File

@@ -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),
],
),
),

View File

@@ -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,
),
),
],
),

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,
),
),

View File

@@ -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),
),
],
),

View File

@@ -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,
),
],
),

View File

@@ -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),
),
),
),

View File

@@ -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),
),
],
);

View File

@@ -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,
),
),

View File

@@ -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: () {},
),
),

View File

@@ -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,
),
],

View File

@@ -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,
),
),
),

View File

@@ -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,

View File

@@ -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(

View File

@@ -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,
),
),

View File

@@ -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,
),
),

View File

@@ -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: () {

View File

@@ -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),
),
],
),

View File

@@ -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),
),
],
),

View File

@@ -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,
),
),

View File

@@ -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,
),

View File

@@ -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,
),
),
],

View File

@@ -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),
),
],
),