Files
ln-ios/ln_jq_app/lib/pages/b_page/site/controller.dart
2025-11-11 16:51:27 +08:00

300 lines
8.7 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:getx_scaffold/getx_scaffold.dart';
import 'package:ln_jq_app/common/model/base_model.dart';
import 'package:ln_jq_app/storage_service.dart';
enum ReservationStatus {
pending, // 待处理 ( addStatus: 1)
completed, // 已完成 ( addStatus: 2)
rejected, // 已拒绝 ( 3)
unknown, // 未知状态
}
class ReservationModel {
final String id;
final String plateNumber;
final String amount;
final String time;
final String contactPerson;
final String contactPhone;
ReservationStatus status; // 状态是可变的
final String contacts;
final String phone;
final String stationName;
final String startTime;
final String endTime;
final String date;
final String hydAmount;
final String state;
final String stateName;
final String addStatus;
final String addStatusName;
ReservationModel({
required this.id,
required this.plateNumber,
required this.amount,
required this.time,
required this.contactPerson,
required this.contactPhone,
this.status = ReservationStatus.pending,
required this.contacts,
required this.phone,
required this.stationName,
required this.startTime,
required this.endTime,
required this.date,
required this.hydAmount,
required this.state,
required this.stateName,
required this.addStatus,
required this.addStatusName,
});
/// 工厂构造函数用于从JSON创建ReservationModel实例
factory ReservationModel.fromJson(Map<String, dynamic> json) {
//1完成 0待处理 2已拒绝
ReservationStatus currentStatus;
int statusFromServer = json['addStatus'] as int? ?? 0;
switch (statusFromServer) {
case 0:
currentStatus = ReservationStatus.pending;
break;
case 1:
currentStatus = ReservationStatus.completed;
break;
case 2:
currentStatus = ReservationStatus.rejected;
break;
default:
currentStatus = ReservationStatus.unknown;
}
// 格式化时间显示
String startTimeStr = json['startTime']?.toString() ?? '';
String endTimeStr = json['endTime']?.toString() ?? '';
String dateStr = json['date']?.toString() ?? '';
String timeRange = (startTimeStr.isNotEmpty && endTimeStr.isNotEmpty && dateStr.isNotEmpty)
? '$dateStr ${startTimeStr.substring(11, 16)}-${endTimeStr.substring(11, 16)}' // 截取 HH:mm
: '时间未定';
return ReservationModel(
// 原始字段用于UI兼容
id: json['id']?.toString() ?? '',
plateNumber: json['plateNumber']?.toString() ?? '未知车牌',
amount: '${json['hydAmount']?.toString() ?? '0'}kg',
time: timeRange,
contactPerson: json['contacts']?.toString() ?? '无联系人',
contactPhone: json['phone']?.toString() ?? '无联系电话',
status: currentStatus,
// 新增的完整字段
contacts: json['contacts']?.toString() ?? '',
phone: json['phone']?.toString() ?? '',
stationName: json['stationName']?.toString() ?? '',
startTime: startTimeStr,
endTime: endTimeStr,
date: dateStr,
hydAmount: json['hydAmount']?.toString() ?? '0',
state: json['state']?.toString() ?? '',
addStatus: statusFromServer.toString(),
addStatusName: json['addStatusName']?.toString() ?? '',
stateName: json['stateName']?.toString() ?? '',
);
}
}
class SiteController extends GetxController with BaseControllerMixin {
@override
String get builderId => 'site';
SiteController();
/// 状态变量:是否有预约数据
bool hasReservationData = false;
// 新增预约数据列表
List<ReservationModel> reservationList = [];
Timer? _refreshTimer;
@override
void onInit() {
super.onInit();
renderData();
startAutoRefresh();
}
@override
void onClose() {
stopAutoRefresh();
super.onClose();
}
void startAutoRefresh() {
// 先停止已存在的定时器,防止重复启动
stopAutoRefresh();
// 创建一个每5分钟执行一次的周期性定时器
_refreshTimer = Timer.periodic(const Duration(minutes: 5), (timer) {
fetchReservationData();
});
}
/// 【6. 新增】停止定时器的方法
void stopAutoRefresh() {
// 如果定时器存在并且是激活状态,就取消它
_refreshTimer?.cancel();
_refreshTimer = null; // 置为null方便判断
print("【自动刷新】定时器已停止。");
}
/// 获取预约数据的方法
Future<void> fetchReservationData() async {
showLoading("加载中");
try {
var response = await HttpService.to.post(
"appointment/orderAddHyd/sitOrderPage",
data: {
'stationName': name, // 使用从 renderData 中获取到的 name
'pageNum': 1,
'pageSize': 30, // 暂时不考虑分页一次获取30条
},
);
// 安全校验
if (response == null || response.data == null) {
showToast('暂时无法获取预约数据');
hasReservationData = false;
reservationList = [];
return;
}
final baseModel = BaseModel<dynamic>.fromJson(response.data);
if (baseModel.code == 0 && baseModel.data != null) {
// 【核心修改】处理接口返回的列表数据
final dataMap = baseModel.data as Map<String, dynamic>;
final List<dynamic> listFromServer = dataMap['list'] ?? [];
// 使用 .map() 遍历列表,将每个 item 转换为一个 ReservationModel 对象
reservationList = listFromServer.map((item) {
return ReservationModel.fromJson(item as Map<String, dynamic>);
}).toList();
// 根据列表是否为空来更新 hasReservationData 状态
hasReservationData = reservationList.isNotEmpty;
} else {
// 接口返回业务错误
showToast(baseModel.message);
hasReservationData = false;
reservationList = []; // 清空列表
}
} catch (e) {
// 捕获网络或解析异常
showToast('获取预约数据失败');
hasReservationData = false;
reservationList = []; // 清空列表
} finally {
// 无论成功失败最后都要关闭加载动画并更新UI
dismissLoading();
updateUi();
}
}
/// 确认预约
Future<void> confirmReservation(String id) async {
final item = reservationList.firstWhere((item) => item.id == id);
DialogX.to.showConfirmDialog(
title: '确认预约',
message: '确定要确认车牌号${item.plateNumber}的预约吗',
onConfirm: () {
upDataService(id, 1, item);
},
onCancel: () {},
);
}
/// 拒绝预约
Future<void> rejectReservation(String id) async {
final item = reservationList.firstWhere((item) => item.id == id);
DialogX.to.showConfirmDialog(
title: '拒绝预约',
message: '确定要拒绝车牌号${item.plateNumber}的预约吗',
onConfirm: () {
upDataService(id, 2, item);
},
onCancel: () {},
);
}
void upDataService(String id, int status, ReservationModel item) async {
showLoading("确认中");
try {
var responseData = await HttpService.to.post(
'appointment/orderAddHyd/completeOrder',
data: {'id': id, 'addStatus': status},
);
if (responseData == null && responseData!.data == null) {
dismissLoading();
showToast('服务暂不可用,请稍后');
return;
}
var result = BaseModel.fromJson(responseData.data);
if (result.code == 0) {
showSuccessToast("操作成功");
}
dismissLoading();
if (status == 1) {
item.status = ReservationStatus.completed;
} else if (status == 2) {
item.status = ReservationStatus.rejected;
}
updateUi();
} catch (e) {
dismissLoading();
}
}
String leftHydrogen = "";
String orderAmount = "";
String completedAmount = "";
String name = "";
Future<void> renderData() async {
try {
var responseData = await HttpService.to.get(
'appointment/station/getStationInfoById?hydrogenId=${StorageService.to.userId}',
);
if (responseData == null && responseData!.data == null) {
showToast('暂时无法获取站点信息');
return;
}
try {
var result = BaseModel.fromJson(responseData.data);
leftHydrogen = result.data["leftHydrogen"] ?? "";
orderAmount = result.data["orderAmount"].toString();
completedAmount = result.data["completedAmount"].toString();
name = result.data["name"].toString();
leftHydrogen = leftHydrogen.isEmpty ? "统计中" : leftHydrogen.toString();
//加载列表数据
fetchReservationData();
} catch (e) {
showToast('数据异常');
}
} catch (e) {}
}
}