import 'dart:async'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:getx_scaffold/getx_scaffold.dart'; import 'package:intl/intl.dart'; import 'package:ln_jq_app/common/model/base_model.dart'; import 'package:ln_jq_app/pages/login/view.dart'; import '../../../common/styles/theme.dart'; import '../../../storage_service.dart'; class ReservationController extends GetxController with BaseControllerMixin { @override String get builderId => 'b_reservation'; final List operationStatusOptions = ["营运中", "维修中", "暂停营业", "站点关闭"]; String selectedOperationStatus = "营运中"; // --- 其它状态下的时间选择 --- DateTime? customStartTime; DateTime? customEndTime; String get customStartTimeStr => customStartTime != null ? DateFormat('yyyy-MM-dd HH:mm').format(customStartTime!) : '点击选择开始时间'; String get customEndTimeStr => customEndTime != null ? DateFormat('yyyy-MM-dd HH:mm').format(customEndTime!) : '点击选择结束时间'; // --- 站点广播相关 --- final TextEditingController broadcastTitleController = TextEditingController(); final TextEditingController broadcastContentController = TextEditingController(); final RxInt selectedTabIndex = 0.obs; @override bool get listenLifecycleEvent => true; @override void onInit() { super.onInit(); // 1. 初始化默认时间 customStartTime = DateTime.now(); customEndTime = customStartTime!.add(const Duration(days: 1)); renderData(); startAutoRefresh(); } @override void onPaused() { stopAutoRefresh(); super.onPaused(); } @override void onClose() { stopAutoRefresh(); broadcastTitleController.dispose(); broadcastContentController.dispose(); super.onClose(); } void startAutoRefresh() { // 先停止已存在的定时器,防止重复启动 stopAutoRefresh(); // 创建一个每5分钟执行一次的周期性定时器 _refreshTimer = Timer.periodic(const Duration(minutes: 5), (timer) { renderData(); }); } ///停止定时器的方法 void stopAutoRefresh() { // 如果定时器存在并且是激活状态,就取消它 _refreshTimer?.cancel(); _refreshTimer = null; // 置为null,方便判断 } String name = ""; String address = ""; String phone = ""; String costPrice = ""; String customerPrice = ""; String startBusiness = ""; String endBusiness = ""; String timeStr = ""; String operatingEnterprise = ""; String hydrogenId = ""; String jobTipStr = ""; String jobDetailsStr = ""; String jobId = ""; Timer? _refreshTimer; Future renderData() async { showLoading("加载中"); try { //获取加氢站未执行的状态修改任务信息 var jobData = await HttpService.to.get('appointment/job/hyd/un-executed'); if (jobData != null) { final jobDataResult = BaseModel.fromJson(jobData.data); if (jobDataResult.code == 0) { try { final List dataList = jobDataResult.data is List ? jobDataResult.data : []; final firstJob = dataList[0]; jobId = firstJob["id"] ?? ""; String endTime = firstJob["endTime"] ?? ""; String beginTime = firstJob["beginTime"] ?? ""; String hydStatus = firstJob["hydStatus"].toString() ?? ""; String hydStatusStr = ""; if (hydStatus == "0") { hydStatusStr = "营运中"; } else if (hydStatus == "1") { hydStatusStr = "维修中"; } else if (hydStatus == "2") { hydStatusStr = "站点关闭"; } else if (hydStatus == "3") { hydStatusStr = "暂停营业"; } //现在的时间晚于开始时间就不显示文案 bool isJobStarted = false; try { if (beginTime.isNotEmpty) { DateTime beginDateTime = DateTime.parse(beginTime); if (DateTime.now().isAfter(beginDateTime)) { isJobStarted = true; } } } catch (e) { print("开始时间解析失败: $e"); } if (isJobStarted) { jobTipStr = ""; } //结束时间 if (endTime.isNotEmpty) { try { // 解析时间字符串 DateTime endDateTime = DateTime.parse(endTime); DateTime beginDateTime = DateTime.parse(beginTime); DateTime now = DateTime.now(); //计算时间差 (endTime - now) Duration diff = endDateTime.difference(now); // 计算小时数 (允许小数,例如 0.5) // inMinutes / 60 可以得到更精确的小数小时 double hoursLeft = diff.inMinutes / 60.0; //计算当前时间-开始时间 Duration startDiff = beginDateTime.difference(now); double hoursUntilStart = startDiff.inMinutes / 60.0; // 只有在【当前时间早于开始时间】且【剩余时间大于0】时才显示文案 if (now.isBefore(beginDateTime) && hoursLeft > 0) { // 如果是正数,表示还有多久结束 String timeTip = " ${hoursUntilStart.toStringAsFixed(1)}小时后"; jobTipStr = "$timeTip$hydStatusStr"; } else { jobTipStr = ""; } jobDetailsStr = "当前站点已设置$beginTime至$endTime,共${hoursLeft.toStringAsFixed(2)}小时,为$hydStatusStr状态"; // 如果是处于非营运状态,自动回填开始和结束时间 // 假设 customStartTime 是现在,customEndTime 是接口返回的结束时间 customStartTime = beginDateTime; customEndTime = endDateTime; } catch (e) { print("时间解析失败: $e"); } } } catch (e) { Logger.d("解析失败或者没返回信息: $e"); jobTipStr = ""; } } } //获取站点信息 var responseData = await HttpService.to.get( 'appointment/station/getStationInfoById?hydrogenId=${StorageService.to.userId}', ); if (responseData == null && responseData!.data == null) { dismissLoading(); showToast('暂时无法获取站点信息'); return; } try { var result = BaseModel.fromJson(responseData.data); name = result.data["name"] ?? ""; hydrogenId = result.data["hydrogenId"].toString(); address = result.data["address"] ?? ""; var rawCostPrice = result.data["costPrice"]; costPrice = (rawCostPrice != null && rawCostPrice.toString().isNotEmpty) ? "¥$rawCostPrice" : "暂无价格"; var customerPriceTemp = result.data["customerPrice"]; customerPrice = (customerPriceTemp != null && customerPriceTemp.toString().isNotEmpty) ? "$customerPriceTemp" : "暂无价格"; phone = result.data["phone"] ?? ""; startBusiness = result.data["startBusiness"] ?? ""; endBusiness = result.data["endBusiness"] ?? ""; operatingEnterprise = result.data["operatingEnterprise"].toString(); String temp = result.data["siteStatusName"].toString(); selectedOperationStatus = (temp.isEmpty || temp == "null") ? "营运中" : temp; if (startBusiness.isNotEmpty && endBusiness.isNotEmpty) { if (startBusiness == "00:00:00" && endBusiness == "23:59:59") { timeStr = "24小时营业"; } else { timeStr = '${startBusiness.substring(0, 5)} - ${endBusiness.substring(0, 5)}'; } } else { timeStr = "时间未设置"; } operatingEnterprise = operatingEnterprise.isEmpty ? "暂未设置" : operatingEnterprise; dismissLoading(); } catch (e) { dismissLoading(); showToast('数据异常'); } } catch (e) { dismissLoading(); } finally { updateUi(); } } void onOperationStatusChanged(String? newValue) { if (newValue != null) { selectedOperationStatus = newValue; updateUi(); } } /// 使用底部滚轮形式选择时间(下拉框效果) void pickDateTime(BuildContext context, bool isStart) { DateTime now = DateTime.now(); DateTime initialDate = isStart ? (customStartTime ?? now) : (customEndTime ?? now); DateTime minLimit = isStart ? now.subtract(const Duration(minutes: 1)) : (customStartTime ?? now).subtract(const Duration(minutes: 1)); if (initialDate.isBefore(minLimit)) { initialDate = isStart ? now : (customStartTime ?? now); } DateTime tempDate = initialDate; Get.bottomSheet( Container( height: 300, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), ), child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CupertinoButton( onPressed: () => Get.back(), child: const Text('取消', style: TextStyle(color: Colors.grey)), ), CupertinoButton( onPressed: () { if (isStart) { customStartTime = tempDate; if (customEndTime != null && customEndTime!.isBefore(customStartTime!)) { customEndTime = customStartTime!.add(const Duration(days: 1)); } } else { if (tempDate.isBefore(customStartTime ?? DateTime.now())) { showToast('结束时间不能早于开始时间'); return; } customEndTime = tempDate; } updateUi(); Get.back(); }, child: const Text( '确定', style: TextStyle( color: AppTheme.themeColor, fontWeight: FontWeight.bold, ), ), ), ], ), ), const Divider(height: 1), Expanded( child: CupertinoDatePicker( mode: CupertinoDatePickerMode.dateAndTime, initialDateTime: initialDate, minimumDate: minLimit, use24hFormat: true, onDateTimeChanged: (DateTime newDate) { tempDate = newDate; }, ), ), ], ), ), backgroundColor: Colors.transparent, ); } void saveInfo() async { if (selectedOperationStatus != "营运中") { if (customStartTime == null || customEndTime == null) { showToast("请选择开始和结束时间"); return; } } showLoading("保存中"); try { var responseData = await HttpService.to.post( 'appointment/station/updateStationStatus', data: { 'hydrogenId': hydrogenId, 'name': name, 'siteStatus': selectedOperationStatus == "营运中" ? "0" : selectedOperationStatus == "维修中" ? "1" : selectedOperationStatus == "站点关闭" ? "2" : selectedOperationStatus == "暂停营业" ? "3" : 0, 'beginTime': selectedOperationStatus == "营运中" ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(customStartTime!), 'endTime': selectedOperationStatus == "营运中" ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(customEndTime!), 'updateTime': getNowDateTimeString(), }, ); if (responseData == null || responseData.data == null) { dismissLoading(); showToast('服务暂不可用,请稍后'); return; } var result = BaseModel.fromJson(responseData.data); if (result.code == 0) { showSuccessToast("保存成功,已同步通知对应司机"); //重新刷新页面 renderData(); } dismissLoading(); } catch (e) { dismissLoading(); } } /// 显示当前未执行任务的详情弹窗 void showJob() { if (jobDetailsStr.isEmpty) { showToast("当前没有正在生效的任务设置"); return; } DialogX.to.showConfirmDialog( title: '当前设置详情', content: Text(jobDetailsStr, style: const TextStyle(fontSize: 15, height: 1.5)), confirmText: '好的', cancelText: '取消设置', onCancel: () { // 点击“取消设置”调用删除接口 _cancelJob(); }, ); } /// 内部私有方法:调用取消/删除任务接口 void _cancelJob() async { showLoading("正在取消..."); try { var response = await HttpService.to.delete('appointment/job/hyd/$jobId'); dismissLoading(); if (response != null) { var result = BaseModel.fromJson(response.data); if (result.code == 0) { showSuccessToast("已成功取消该设置"); // 成功后重新刷新页面数据,重置状态 renderData(); } else { showErrorToast(result.error); } } } catch (e) { dismissLoading(); showErrorToast("取消失败,请稍后重试"); Logger.d("取消任务失败: $e"); } } /// 发送站点广播 void sendBroadcast() async { String title = broadcastTitleController.text.trim(); String content = broadcastContentController.text.trim(); if (title.isEmpty) { showToast("请输入通知标题"); return; } if (content.isEmpty) { showToast("请输入通知内容"); return; } showLoading("发送中..."); try { var responseData = await HttpService.to.post( 'appointment/notice/push/station/broadcast', data: {'title': title, 'content': content}, ); dismissLoading(); if (responseData != null) { var result = BaseModel.fromJson(responseData.data); if (result.code == 0) { showSuccessToast("广播发送成功"); } else { showErrorToast(result.error); } } } catch (e) { dismissLoading(); showToast("发送失败,请稍后重试"); } } void logout() async { await StorageService.to.clearLoginInfo(); Get.offAll(() => LoginPage()); } }