无预约

This commit is contained in:
2026-02-28 11:59:07 +08:00
parent a8314d8a7a
commit 0df1902df2
4 changed files with 462 additions and 370 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 573 B

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 594 B

View File

@@ -124,8 +124,8 @@ class ReservationModel {
plateNumber: json['plateNumber']?.toString() ?? '---', plateNumber: json['plateNumber']?.toString() ?? '---',
amount: '${json['hydAmount']?.toString() ?? '0'}kg', amount: '${json['hydAmount']?.toString() ?? '0'}kg',
time: timeRange, time: timeRange,
contactPerson: json['contacts']?.toString() ?? '无联系人', contactPerson: json['contacts']?.toString() ?? '',
contactPhone: json['phone']?.toString() ?? '无联系电话', contactPhone: json['phone']?.toString() ?? '',
status: currentStatus, status: currentStatus,
// 新增的完整字段 // 新增的完整字段
@@ -315,11 +315,46 @@ class SiteController extends GetxController with BaseControllerMixin {
} }
/// 确认预约弹窗重构 /// 确认预约弹窗重构
Future<void> confirmReservation(String id, {bool isEdit = false}) async { Future<void> confirmReservation(
final item = reservationList.firstWhere( String id, {
bool isEdit = false,
bool isAdd = false,
}) async {
ReservationModel item;
if (isAdd) {
// 如果是无预约车辆加氢,创建一个临时 model
item = ReservationModel(
id: "",
stationId: StorageService.to.userId ?? "",
plateNumber: "---",
amount: "0.000",
time: "",
contactPerson: "",
contactPhone: "",
hasEdit: true,
contacts: "",
phone: "",
stationName: name,
startTime: "",
endTime: "",
date: "",
hydAmount: "0.000",
state: "",
stateName: "",
addStatus: "",
addStatusName: "",
rejectReason: "",
isTruckAttachment: 0,
hasDrivingAttachment: false,
hasHydrogenationAttachment: false,
isEdit: "0",
);
} else {
item = reservationList.firstWhere(
(item) => item.id == id, (item) => item.id == id,
orElse: () => throw Exception('Reservation not found'), orElse: () => throw Exception('Reservation not found'),
); );
}
// 加氢量保留3位小数 // 加氢量保留3位小数
double initialAmount = double.tryParse(item.hydAmount) ?? 0.0; double initialAmount = double.tryParse(item.hydAmount) ?? 0.0;
@@ -341,7 +376,7 @@ class SiteController extends GetxController with BaseControllerMixin {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
isEdit ? '修改加氢量' : '确认加氢状态', isAdd ? "无预约车辆加氢" : (isEdit ? '修改加氢量' : '确认加氢状态'),
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -359,8 +394,13 @@ class SiteController extends GetxController with BaseControllerMixin {
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Container( isEdit
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), ? SizedBox()
: Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 2,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color.fromRGBO(232, 243, 255, 1), color: Color.fromRGBO(232, 243, 255, 1),
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
@@ -382,27 +422,33 @@ class SiteController extends GetxController with BaseControllerMixin {
], ],
), ),
const SizedBox(height: 12), SizedBox(height: 6.h),
// 提示逻辑 // 提示逻辑
if (isEdit) if (isEdit)
const Text( Text(
'每个订单只能修改一次,请确认加氢量准确无误', '每个订单只能修改一次,请确认加氢量准确无误',
style: TextStyle(color: Colors.red, fontSize: 12), style: TextStyle(
color: Colors.red,
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
) )
else else if (item.plateNumber == "---" || item.isTruckAttachment == 0)
if (item.plateNumber == "---" || item.isTruckAttachment == 0)
Row( Row(
children: [ children: [
const Expanded( Expanded(
child: Text( child: Text(
'车辆未上传加氢证,请完成线下登记', '车辆未上传加氢证,请完成线下登记',
style: TextStyle(color: Colors.red, fontSize: 12), style: TextStyle(
color: Colors.red,
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
), ),
), ),
Obx( Obx(
() => () => Checkbox(
Checkbox(
value: isOfflineChecked.value, value: isOfflineChecked.value,
onChanged: (v) => isOfflineChecked.value = v ?? false, onChanged: (v) => isOfflineChecked.value = v ?? false,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
@@ -412,7 +458,7 @@ class SiteController extends GetxController with BaseControllerMixin {
], ],
), ),
const SizedBox(height: 16), SizedBox(height: 6.h),
// 预定加氢量输入区 // 预定加氢量输入区
Container( Container(
@@ -459,14 +505,10 @@ class SiteController extends GetxController with BaseControllerMixin {
), ),
decoration: const InputDecoration( decoration: const InputDecoration(
enabledBorder: UnderlineInputBorder( enabledBorder: UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(color: Color(0xFF017143)),
color: Color(0xFF017143),
),
), ),
focusedBorder: const UnderlineInputBorder( focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(color: Color(0xFF017143)),
color: Color(0xFF017143),
),
), ),
isDense: true, isDense: true,
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
@@ -483,10 +525,7 @@ class SiteController extends GetxController with BaseControllerMixin {
), ),
), ),
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
horizontal: 12,
vertical: 8,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF017143), color: const Color(0xFF017143),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
@@ -509,14 +548,10 @@ class SiteController extends GetxController with BaseControllerMixin {
const SizedBox(height: 16), const SizedBox(height: 16),
// 加氢枪号选择 // 加氢枪号选择
const Text( const Text('请选择加氢枪号', style: TextStyle(color: Colors.grey, fontSize: 12)),
'请选择加氢枪号',
style: TextStyle(color: Colors.grey, fontSize: 12),
),
const SizedBox(height: 8), const SizedBox(height: 8),
Obx( Obx(
() => () => Container(
Container(
padding: const EdgeInsets.symmetric(horizontal: 12), padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
@@ -528,8 +563,7 @@ class SiteController extends GetxController with BaseControllerMixin {
isExpanded: true, isExpanded: true,
hint: const Text('请选择加氢枪号'), hint: const Text('请选择加氢枪号'),
items: gasGunList.map((String gun) { items: gasGunList.map((String gun) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(value: gun, child: Text(gun));
value: gun, child: Text(gun));
}).toList(), }).toList(),
onChanged: (v) => selectedGun.value = v ?? '', onChanged: (v) => selectedGun.value = v ?? '',
), ),
@@ -559,7 +593,7 @@ class SiteController extends GetxController with BaseControllerMixin {
item, item,
gunNumber: selectedGun.value, gunNumber: selectedGun.value,
plateNumber: item.plateNumber, plateNumber: item.plateNumber,
isEdit: true isEdit: true,
); );
Get.back(); Get.back();
return; return;
@@ -576,6 +610,25 @@ class SiteController extends GetxController with BaseControllerMixin {
showToast("请选择加氢枪号"); showToast("请选择加氢枪号");
return; return;
} }
//无预约订单
if (isAdd) {
final num addHydAmount =
num.tryParse(amountController.text) ?? 0;
upDataService(
id,
0,
1,
addHydAmount,
"",
item,
gunNumber: selectedGun.value,
plateNumber: item.plateNumber,
isAdd: true,
);
Get.back();
return;
}
//有预约订单确认
Get.back(); Get.back();
final num addHydAmount = final num addHydAmount =
num.tryParse(amountController.text) ?? 0; num.tryParse(amountController.text) ?? 0;
@@ -722,8 +775,7 @@ class SiteController extends GetxController with BaseControllerMixin {
const Text('选择或填写拒绝原因:', style: TextStyle(color: Colors.grey)), const Text('选择或填写拒绝原因:', style: TextStyle(color: Colors.grey)),
const SizedBox(height: 8), const SizedBox(height: 8),
Obx( Obx(
() => () => Wrap(
Wrap(
// 使用 Wrap 自动换行 // 使用 Wrap 自动换行
spacing: 8.0, // 水平间距 spacing: 8.0, // 水平间距
children: presetReasons.map((reason) { children: presetReasons.map((reason) {
@@ -794,16 +846,14 @@ class SiteController extends GetxController with BaseControllerMixin {
plateNumber: item.plateNumber, plateNumber: item.plateNumber,
); );
}, },
child: const Text('确认拒绝', style: TextStyle(color: Colors child: const Text('确认拒绝', style: TextStyle(color: Colors.red)),
.red)),
), ),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded( Expanded(
child: TextButton( child: TextButton(
onPressed: () => Get.back(), onPressed: () => Get.back(),
child: const Text('暂不处理', style: TextStyle(color: Colors child: const Text('暂不处理', style: TextStyle(color: Colors.grey)),
.grey)),
), ),
), ),
], ],
@@ -818,20 +868,32 @@ class SiteController extends GetxController with BaseControllerMixin {
} }
//addStatus 1完成 2未加 -1拒绝 //addStatus 1完成 2未加 -1拒绝
void upDataService(String id, void upDataService(
String id,
int status, int status,
int addStatus, int addStatus,
num addHydAmount, num addHydAmount,
String rejectReason, String rejectReason,
ReservationModel item, { ReservationModel item, {
String? gunNumber, String? gunNumber,
String? plateNumber, bool isEdit = false String? plateNumber,
bool isEdit = false,
bool isAdd = false,
}) async { }) async {
showLoading("确认中"); showLoading("确认中");
try { try {
var responseData; var responseData;
if (isEdit) { if (isAdd) {
responseData = await HttpService.to.post(
'appointment/orderAddHyd/addOfflineOrder',
data: {
"addHydAmount": addHydAmount,
"plateNumber": plateNumber,
if (gunNumber != null && gunNumber.isNotEmpty) "gunNumber": gunNumber,
},
);
} else if (isEdit) {
responseData = await HttpService.to.post( responseData = await HttpService.to.post(
'appointment/orderAddHyd/modifyOrder', 'appointment/orderAddHyd/modifyOrder',
data: { data: {
@@ -867,7 +929,6 @@ class SiteController extends GetxController with BaseControllerMixin {
if (responseData == null || responseData.data == null) { if (responseData == null || responseData.data == null) {
dismissLoading(); dismissLoading();
showToast('服务暂不可用,请稍后');
return; return;
} }
var result = BaseModel.fromJson(responseData.data); var result = BaseModel.fromJson(responseData.data);
@@ -922,15 +983,15 @@ class SiteController extends GetxController with BaseControllerMixin {
orderUnfinishedAmount = result.data["orderUnfinishedAmount"].toString(); orderUnfinishedAmount = result.data["orderUnfinishedAmount"].toString();
leftHydrogen = leftHydrogen.isEmpty ? "统计中" : leftHydrogen.toString(); leftHydrogen = leftHydrogen.isEmpty ? "统计中" : leftHydrogen.toString();
orderTotalAmount = orderTotalAmount = orderTotalAmount.isEmpty ? "统计中" : orderTotalAmount.toString();
orderTotalAmount.isEmpty ? "统计中" : orderTotalAmount.toString();
orderUnfinishedAmount = orderUnfinishedAmount.isEmpty orderUnfinishedAmount = orderUnfinishedAmount.isEmpty
? "统计中" ? "统计中"
: orderUnfinishedAmount.toString(); : orderUnfinishedAmount.toString();
} catch (e) { } catch (e) {
showToast('数据异常'); showToast('数据异常');
} }
} catch (e) {} finally { } catch (e) {
} finally {
//加载列表数据 //加载列表数据
fetchReservationData(); fetchReservationData();

View File

@@ -56,17 +56,32 @@ class SitePage extends GetView<SiteController> {
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
Get.to( // 手动录入
() => HistoryPage(), controller.confirmReservation("", isAdd: true);
arguments: {'stationName': controller.name},
);
}, },
child: Text( child: Container(
'历史记录', padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFFEEEEEE)),
),
child: Row(
children: [
const Icon(
Icons.add_circle_outline,
size: 18,
color: Color(0xFF666666),
),
const SizedBox(width: 4),
Text(
"无预约车辆加氢",
style: TextStyle( style: TextStyle(
fontSize: 14.sp, color: const Color(0xFF666666),
fontWeight: FontWeight.bold, fontSize: 13.sp,
color: Color.fromRGBO(156, 163, 175, 1), ),
),
],
), ),
), ),
), ),
@@ -184,27 +199,7 @@ class SitePage extends GetView<SiteController> {
], ],
), ),
), ),
IconButton( _buildDropdownMenu(),
onPressed: () async {
var scanResult = await Get.to(() => const MessagePage());
if (scanResult == null) {
controller.msgNotice();
}
},
style: IconButton.styleFrom(
backgroundColor: Colors.grey[100],
padding: const EdgeInsets.all(8),
),
icon: Badge(
smallSize: 8,
backgroundColor: controller.isNotice ? Colors.red : Colors.transparent,
child: const Icon(
Icons.notifications_outlined,
color: Colors.black87,
size: 30,
),
),
),
], ],
), ),
const SizedBox(height: 25), const SizedBox(height: 25),
@@ -232,6 +227,40 @@ class SitePage extends GetView<SiteController> {
); );
} }
Widget _buildDropdownMenu() {
return PopupMenuButton<String>(
icon: Container(child: const Icon(Icons.grid_view_rounded, size: 24)),
onSelected: (value) async {
if (value == 'message') {
var scanResult = await Get.to(() => const MessagePage());
if (scanResult == null) {
controller.msgNotice();
}
} else if (value == 'history') {
Get.to(() => const HistoryPage(), arguments: {'stationName': controller.name});
}
},
itemBuilder: (context) => [
const PopupMenuItem(
value: 'message',
child: Row(
children: [
Icon(Icons.notifications_none, size: 20),
SizedBox(width: 8),
Text('消息中心'),
],
),
),
const PopupMenuItem(
value: 'history',
child: Row(
children: [Icon(Icons.history, size: 20), SizedBox(width: 8), Text('加氢历史')],
),
),
],
);
}
Widget _buildStatBox(String title, String enTitle, String value, String unit) { Widget _buildStatBox(String title, String enTitle, String value, String unit) {
return Expanded( return Expanded(
child: Container( child: Container(
@@ -508,7 +537,9 @@ class SitePage extends GetView<SiteController> {
const SizedBox(height: 8), const SizedBox(height: 8),
// 联系信息 // 联系信息
Text( Text(
"${item.contactPerson} | ${item.contactPhone}", item.contactPerson.isEmpty || item.contactPhone.isEmpty
? ""
: "${item.contactPerson} | ${item.contactPhone}",
style: TextStyle( style: TextStyle(
color: Color(0xFF999999), color: Color(0xFF999999),
fontSize: 13.sp, fontSize: 13.sp,