遗漏提交
This commit is contained in:
@@ -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,
|
||||
// 顶部标题栏
|
||||
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: 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: [
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF86909C),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFF1D2129),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
if (status != null) ...[
|
||||
const SizedBox(width: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF00B42A).withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
status,
|
||||
'SN: ${station.deviceSn}',
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFF00B42A),
|
||||
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,
|
||||
// ),
|
||||
// )),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 状态徽章
|
||||
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)],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color:
|
||||
(isOnline ? const Color(0xFF00B42A) : const Color(0xFFF53F3F))
|
||||
.withOpacity(0.3),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user