遗漏提交

This commit is contained in:
2026-05-29 14:14:19 +08:00
parent 335c468aac
commit 9154174614
2 changed files with 377 additions and 129 deletions

View File

@@ -1,15 +1,15 @@
import 'package:flutter/material.dart';
import '../../domain/entities/drone_station_entity.dart';
/// 无人机机场列表项卡片
class DroneStationItemCard extends StatelessWidget {
final String name;
final String id;
final DroneStationEntity station;
final VoidCallback onTap;
const DroneStationItemCard({
super.key,
required this.name,
required this.id,
required this.station,
required this.onTap,
});
@@ -18,100 +18,409 @@ class DroneStationItemCard extends StatelessWidget {
return GestureDetector(
onTap: onTap,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.white, const Color(0xFFF8F9FA)],
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Color(0x0D000000),
blurRadius: 8,
offset: Offset(0, 2),
color: Colors.black.withOpacity(0.08),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'机场状态',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Color(0xFF1D2129),
// 顶部标题栏
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xFF165DFF).withOpacity(0.05),
const Color(0xFF165DFF).withOpacity(0.02),
],
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: Row(
children: [
// 图标
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: const Color(0xFF165DFF).withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(
Icons.home_max_rounded,
color: Color(0xFF165DFF),
size: 24,
),
),
const SizedBox(width: 12),
// 名称
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
station.callsign.isNotEmpty
? station.callsign
: '未知机场',
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Color(0xFF1D2129),
),
),
const SizedBox(height: 2),
Text(
'SN: ${station.deviceSn}',
style: const TextStyle(
fontSize: 11,
color: Color(0xFF86909C),
),
),
],
),
),
// 机场状态徽章
_buildStatusBadge('机场', station.isOnline),
],
),
),
const Divider(height: 1, color: Color(0xFFE5E6EB)),
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 机场基础信息卡片
_buildSectionCard(
title: '机场信息',
icon: Icons.settings_rounded,
children: [
_buildInfoRowWithIcon(
Icons.tag_rounded,
'机场序列号',
station.deviceSn,
),
const SizedBox(height: 10),
_buildInfoRowWithIcon(
Icons.router_rounded,
'网关序列号',
station.gatewaySn,
),
// if (station.latitude != null || station.longitude != null) ...[
// const SizedBox(height: 10),
// _buildInfoRowWithIcon(
// Icons.location_on_rounded,
// '位置坐标',
// station.latitude != null && station.longitude != null
// ? '${station.latitude}, ${station.longitude}'
// : '未知',
// ),
// ],
],
),
//
// const SizedBox(height: 12),
//
// // 电量卡片
// _buildInfoCard(
// title: '电量状态',
// icon: Icons.battery_full_rounded,
// iconColor: _getBatteryColor(station.capacityPercent),
// value: station.capacityPercent != null ? '${station.capacityPercent}%' : '未知',
// progressValue: station.capacityPercent,
// ),
//
// const SizedBox(height: 12),
//
// // 环境信息卡片
// _buildSectionCard(
// title: '环境监测',
// icon: Icons.thermostat_rounded,
// children: [
// _buildInfoRowWithIcon(
// Icons.thermostat_rounded,
// '环境温度',
// station.environmentTemperature != null ? '${station.environmentTemperature}°C' : '未知',
// ),
// const SizedBox(height: 10),
// _buildInfoRowWithIcon(
// Icons.air_rounded,
// '风速',
// station.windSpeed != null ? '${station.windSpeed} m/s' : '未知',
// ),
// const SizedBox(height: 10),
// _buildInfoRowWithIcon(
// Icons.water_drop_rounded,
// '降雨量',
// station.rainfall != null ? '${station.rainfall} mm' : '未知',
// ),
// ],
// ),
//
// const SizedBox(height: 12),
//
// // 网络状态卡片
// _buildSectionCard(
// title: '网络状态',
// icon: Icons.wifi_rounded,
// children: [
// _buildInfoRowWithIcon(
// Icons.network_check_rounded,
// '网络状态',
// station.networkState != null ? '等级 ${station.networkState}' : '未知',
// ),
// const SizedBox(height: 10),
// _buildInfoRowWithIcon(
// Icons.gps_fixed_rounded,
// '位置状态',
// station.positionState != null ? '状态 ${station.positionState}' : '未知',
// ),
// ],
// ),
//
//
// // 摄像头信息
// if (station.gatewayCameraList != null && station.gatewayCameraList!.isNotEmpty) ...[
// const SizedBox(height: 12),
// _buildSectionCard(
// title: '网关摄像头',
// icon: Icons.videocam_rounded,
// children: [
// ...station.gatewayCameraList!.map((camera) => Padding(
// padding: const EdgeInsets.only(bottom: 8),
// child: _buildInfoRowWithIcon(
// Icons.camera_alt_rounded,
// '摄像头 ${camera.cameraIndex}',
// camera.cameraPosition,
// ),
// )),
// ],
// ),
// ],
],
),
),
const SizedBox(height: 16),
_buildStatusRow('机场编号', 'AIRPORT-01', status: '正常'),
const SizedBox(height: 12),
_buildStatusRow('位置', '升压站旁 - 无人机机场'),
const SizedBox(height: 12),
_buildStatusRow('舱门状态', '关闭', status: '正常'),
const SizedBox(height: 12),
_buildStatusRowWithProgress('充电状态', '充电中', '85%'),
const SizedBox(height: 12),
_buildWeatherRow(),
const SizedBox(height: 12),
_buildStatusRow('网络状态', '4G/5G 强'),
],
),
),
);
}
/// 状态行(带状态标签)
Widget _buildStatusRow(String label, String value, {String? status}) {
return Row(
children: [
Text(
label,
style: const TextStyle(
fontSize: 13,
color: Color(0xFF86909C),
),
/// 状态徽章
Widget _buildStatusBadge(String label, bool isOnline) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: isOnline
? [const Color(0xFF00B42A), const Color(0xFF23C343)]
: [const Color(0xFFF53F3F), const Color(0xFFF76560)],
),
const Spacer(),
Text(
value,
style: const TextStyle(
fontSize: 13,
color: Color(0xFF1D2129),
fontWeight: FontWeight.w500,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color:
(isOnline ? const Color(0xFF00B42A) : const Color(0xFFF53F3F))
.withOpacity(0.3),
blurRadius: 6,
offset: const Offset(0, 2),
),
),
if (status != null) ...[
const SizedBox(width: 8),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: const Color(0xFF00B42A).withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
width: 6,
height: 6,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Text(
status,
style: const TextStyle(
fontSize: 11,
color: Color(0xFF00B42A),
fontWeight: FontWeight.w500,
),
),
const SizedBox(width: 5),
Text(
'$label\n${isOnline ? '在线' : '离线'}',
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 10,
color: Colors.white,
fontWeight: FontWeight.w600,
height: 1.1,
),
),
],
),
);
}
/// 信息卡片(带进度条)
Widget _buildInfoCard({
required String title,
required IconData icon,
required Color iconColor,
required String value,
double? progressValue,
}) {
return Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, size: 18, color: iconColor),
const SizedBox(width: 6),
Text(
title,
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: Color(0xFF4E5969),
),
),
const Spacer(),
Text(
value,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: iconColor,
),
),
],
),
if (progressValue != null) ...[
const SizedBox(height: 10),
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: LinearProgressIndicator(
value: progressValue / 100,
backgroundColor: const Color(0xFFE5E6EB),
valueColor: AlwaysStoppedAnimation<Color>(iconColor),
minHeight: 8,
),
),
],
],
),
);
}
/// 区块卡片
Widget _buildSectionCard({
required String title,
required IconData icon,
required List<Widget> children,
}) {
return Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(icon, size: 18, color: const Color(0xFF165DFF)),
const SizedBox(width: 6),
Text(
title,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Color(0xFF1D2129),
),
),
],
),
const SizedBox(height: 12),
...children,
],
),
);
}
/// 信息行(带图标)
Widget _buildInfoRowWithIcon(IconData icon, String label, String value) {
return Row(
children: [
Icon(icon, size: 16, color: const Color(0xFF86909C)),
const SizedBox(width: 8),
SizedBox(
width: 70,
child: Text(
'$label:',
style: const TextStyle(fontSize: 11, color: Color(0xFF86909C)),
),
),
const SizedBox(width: 4),
Expanded(
child: Text(
value,
style: const TextStyle(
fontSize: 12,
color: Color(0xFF1D2129),
fontWeight: FontWeight.w500,
),
),
),
],
);
}
/// 带进度条的状态行
Widget _buildStatusRowWithProgress(String label, String value, String progress) {
/// 获取电量颜色
Color _getBatteryColor(double? percent) {
if (percent == null) return const Color(0xFF86909C);
if (percent >= 60) return const Color(0xFF00B42A);
if (percent >= 30) return const Color(0xFFFF7D00);
return const Color(0xFFF53F3F);
}
/// 信息行(旧版,保留兼容)
Widget _buildInfoRow(String label, String value) {
return Row(
children: [
Text(
label,
style: const TextStyle(
fontSize: 13,
color: Color(0xFF86909C),
),
style: const TextStyle(fontSize: 13, color: Color(0xFF86909C)),
),
const Spacer(),
Text(
@@ -122,67 +431,6 @@ class DroneStationItemCard extends StatelessWidget {
fontWeight: FontWeight.w500,
),
),
const SizedBox(width: 8),
Text(
progress,
style: const TextStyle(
fontSize: 13,
color: Color(0xFF165DFF),
fontWeight: FontWeight.w600,
),
),
const SizedBox(width: 4),
const Icon(
Icons.arrow_forward_ios,
size: 12,
color: Color(0xFF86909C),
),
],
);
}
/// 气象条件行
Widget _buildWeatherRow() {
return Row(
children: [
const Text(
'气象条件',
style: TextStyle(
fontSize: 13,
color: Color(0xFF86909C),
),
),
const Spacer(),
Row(
children: [
const Icon(Icons.wb_sunny, size: 16, color: Color(0xFFFF7D00)),
const SizedBox(width: 4),
const Text(
'晴',
style: TextStyle(
fontSize: 13,
color: Color(0xFF1D2129),
fontWeight: FontWeight.w500,
),
),
const SizedBox(width: 8),
const Text(
'25°C',
style: TextStyle(
fontSize: 13,
color: Color(0xFF1D2129),
),
),
const SizedBox(width: 8),
const Text(
'东南风 2级',
style: TextStyle(
fontSize: 13,
color: Color(0xFF1D2129),
),
),
],
),
],
);
}

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.1.2+2
version: 1.0.0+1
flutter_icons:
android: "launcher_icon"