状态样式

This commit is contained in:
2026-01-28 17:59:26 +08:00
parent 55569839a7
commit 79fe3257b5

View File

@@ -52,7 +52,7 @@ class SitePage extends GetView<SiteController> {
GestureDetector(
onTap: () {
Get.to(
() => HistoryPage(),
() => HistoryPage(),
arguments: {'stationName': controller.name},
);
},
@@ -78,6 +78,7 @@ class SitePage extends GetView<SiteController> {
],
),
SizedBox(height: 35.h,),
//第三部分
Container(
padding: const EdgeInsets.all(15),
@@ -141,7 +142,10 @@ class SitePage extends GetView<SiteController> {
borderRadius: BorderRadius.vertical(bottom: Radius.circular(20)),
),
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 10,
top: MediaQuery
.of(context)
.padding
.top + 10,
left: 20,
right: 20,
bottom: 25,
@@ -200,7 +204,8 @@ class SitePage extends GetView<SiteController> {
const SizedBox(height: 25),
Row(
children: [
_buildStatBox("剩余氢量", "remaining quantity", controller.leftHydrogen, "kg"),
_buildStatBox(
"剩余氢量", "remaining quantity", controller.leftHydrogen, "kg"),
SizedBox(width: 4.w),
_buildStatBox(
"今日加氢量",
@@ -364,7 +369,8 @@ class SitePage extends GetView<SiteController> {
children: [
Icon(Icons.inventory_2_outlined, size: 80, color: Colors.grey[300]),
const SizedBox(height: 16),
const Text('暂无预约数据', style: TextStyle(fontSize: 16, color: Colors.black54)),
const Text(
'暂无预约数据', style: TextStyle(fontSize: 16, color: Colors.black54)),
const SizedBox(height: 8),
const Text(
'点击右上角刷新按钮获取最新数据',
@@ -377,137 +383,292 @@ class SitePage extends GetView<SiteController> {
/// 构建“有预约数据”的列表视图
Widget _buildReservationListView() {
return Container(
color: Colors.white,
child: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
// 因为外层已有滚动,这里禁用内部滚动
itemCount: controller.reservationList.length,
padding: const EdgeInsets.all(12.0),
itemBuilder: (context, index) {
final item = controller.reservationList[index];
// 调用新的方法来构建每一项
return _buildReservationItem(index, item);
},
separatorBuilder: (context, index) => const SizedBox(height: 12), // 列表项之间的间距
),
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
// 因为外层已有滚动,这里禁用内部滚动
itemCount: controller.reservationList.length,
itemBuilder: (context, index) {
final item = controller.reservationList[index];
// 调用新的方法来构建每一项
return _buildReservationItem(index, item);
},
separatorBuilder: (context, index) => const SizedBox(height: 0), // 列表项之间的间距
);
}
Widget _buildReservationItem(int index, ReservationModel item) {
const kPrimaryGreen = Color(0xFF006D35); // 深绿
const kLineColor = Color(0xFFE0E6ED); // 线条颜色
return IntrinsicHeight(
// 保证左侧竖线能跟右侧内容高度对齐
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 1. 左侧样式区域(竖线 + 圆点)
SizedBox(
width: 20,
child: Column(
children: [
// 顶部的装饰圆点
Container(
margin: EdgeInsets.only(top: 3.w),
width: 8,
height: 8,
decoration: BoxDecoration(
color: kPrimaryGreen.withOpacity(0.5),
shape: BoxShape.circle,
),
),
// 延伸的竖线
Expanded(child: Container(width: 1, color: kLineColor)),
],
),
),
// 2. 右侧内容区域(时间 + 卡片数据)
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 10.w, bottom: 8.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 时间显示
Text(
item.time, // 格式如 "09:00 - 10:00"
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
const SizedBox(height: 10),
// 数据卡片
_buildInfoCard(item),
],
),
),
),
],
),
);
}
/// 右侧具体数据卡片
Widget _buildInfoCard(ReservationModel item) {
return Container(
padding: EdgeInsets.only(left: 16.w, top: 8.5, bottom: 8.5, right: 16.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
border: Border.all(color: Colors.grey[200]!, width: 1.0),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFF0F0F0)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 3,
offset: const Offset(0, 2),
color: Colors.black.withOpacity(0.04),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 顶部:序号、车牌号、状态
Padding(
padding: const EdgeInsets.fromLTRB(8, 12, 16, 12),
child: Row(
children: [
// 序号
Container(
width: 24,
height: 24,
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: Text(
"${index + 1}",
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
// 车牌与状态标签
Row(
children: [
Text(
item.plateNumber,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
const SizedBox(width: 8),
const Icon(Icons.directions_car, color: Colors.black54),
const SizedBox(width: 4),
// 车牌号
Expanded(
child: Text(
item.plateNumber,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: AppTheme.themeColor,
),
),
),
// 状态标签
_buildStatusChip(item.status),
],
),
),
const Divider(height: 1),
// 中部:详细信息
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
child: Column(
children: [
_buildDetailRow(
Icons.local_gas_station,
'加氢量',
item.amount,
valueColor: Colors.red,
),
const SizedBox(height: 8),
_buildDetailRow(Icons.access_time, '预约时间', item.time),
const SizedBox(height: 8),
_buildDetailRow(Icons.person, '联系人', item.contactPerson),
const SizedBox(height: 8),
_buildDetailRow(
Icons.phone,
'联系电话',
item.contactPhone,
valueColor: AppTheme.themeColor,
),
],
),
),
// 底部:操作按钮 (仅在待处理时显示)
if (item.status == ReservationStatus.pending)
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
child: Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () => controller.confirmReservation(item.id),
style: ElevatedButton.styleFrom(backgroundColor: Colors.blue),
child: const Text('确认'),
),
),
const SizedBox(width: 16),
Expanded(
child: ElevatedButton(
onPressed: () => controller.rejectReservation(item.id),
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
child: const Text('拒绝'),
),
),
],
),
const SizedBox(width: 8),
_buildStatusTag(item.status),
Spacer(),
Text(
"预约量:${item.amount}",
style: TextStyle(
color: Color(0xFF00A870),
fontSize: 12.sp,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 8),
// 联系信息
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"${item.contactPerson} | ${item.contactPhone}",
style: TextStyle(
color: Color(0xFF999999),
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
),
],
),
//操作按钮(仅在待处理状态显示)
if (item.status == ReservationStatus.pending) ...[
const SizedBox(height: 15),
const Divider(height: 1, color: Color(0xFFF5F5F5)),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildSmallButton(
"拒绝",
isOutline: true,
onTap: () {
controller.rejectReservation(item.id);
},
),
const SizedBox(width: 12),
_buildSmallButton(
"确认",
isOutline: false,
onTap: () {
controller.confirmReservation(item.id);
},
),
],
),
],
],
),
);
}
/// 通用小按钮
Widget _buildSmallButton(String text, {
required bool isOutline,
required VoidCallback onTap,
}) {
const kPrimaryGreen = Color(0xFF006D35);
const kDangerRed = Color(0xFFFF7D7D);
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8),
decoration: BoxDecoration(
color: isOutline ? Colors.white : kPrimaryGreen,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: isOutline ? kDangerRed : kPrimaryGreen),
),
child: Text(
text,
style: TextStyle(
color: isOutline ? kDangerRed : Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
);
}
/// 状态标签构建(带圆角和浅色背景)
Widget _buildStatusTag(ReservationStatus status) {
Color textColor;
Color bgColor;
String text;
switch (status) {
case ReservationStatus.pending:
text = "待加氢";
textColor = const Color(0xFFFE9E62); // 橘色
bgColor = const Color(0xFFFFF2E9);
break;
case ReservationStatus.completed: // 假设已加氢状态
text = "已加氢";
textColor = const Color(0xFF00A870); // 绿色
bgColor = const Color(0xFFE6F7F1);
break;
case ReservationStatus.rejected:
text = "拒绝加氢";
textColor = const Color(0xFFFF7D7D); // 红色
bgColor = const Color(0xFFFFEEEE);
break;
case ReservationStatus.unadded:
text = '未加氢';
textColor = const Color(0xFFFF7D7D); // 红色
bgColor = const Color(0xFFFFEEEE);
break;
default:
text = "未知";
textColor = Colors.grey;
bgColor = Colors.grey[100]!;
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: textColor.withOpacity(0.3)),
),
child: Text(
text,
style: TextStyle(color: textColor, fontSize: 11, fontWeight: FontWeight.bold),
),
);
}
/// 右侧操作按钮(拒绝/确认)
Widget _buildActionButtons(ReservationModel item) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
// 拒绝按钮(空心)
GestureDetector(
onTap: () => controller.rejectReservation(item.id),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: const Color(0xFFFF7D7D)),
),
child: const Text(
"拒绝",
style: TextStyle(
color: Color(0xFFFF7D7D),
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(width: 8),
// 确认按钮(实心深绿)
GestureDetector(
onTap: () => controller.confirmReservation(item.id),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFF006D35),
borderRadius: BorderRadius.circular(10),
),
child: const Text(
"确认",
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
),
),
],
);
}
/// 构建状态标签
Widget _buildStatusChip(ReservationStatus status) {
String text;
@@ -555,12 +716,11 @@ class SitePage extends GetView<SiteController> {
}
/// 构建信息详情行
Widget _buildDetailRow(
IconData icon,
String label,
String value, {
Color valueColor = Colors.black87,
}) {
Widget _buildDetailRow(IconData icon,
String label,
String value, {
Color valueColor = Colors.black87,
}) {
return Row(
children: [
Icon(icon, color: Colors.grey, size: 20),