Files
ln-ios/ln_jq_app/lib/pages/b_page/reservation/controller.dart
2026-01-29 17:01:21 +08:00

499 lines
16 KiB
Dart
Raw 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: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<String> 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();
msgNotice(); // 红点消息
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;
bool isNotice = false;
Future<void> 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<dynamic> 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(2)}小时后";
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();
}
}
Future<void> msgNotice() async {
final Map<String, dynamic> requestData = {
'appFlag': 1,
'isRead': 1,
'pageNum': 1,
'pageSize': 5,
};
final response = await HttpService.to.get(
'appointment/unread_notice/page',
params: requestData,
);
if (response != null) {
final result = BaseModel.fromJson(response.data);
if (result.code == 0 && result.data != null) {
String total = result.data["total"].toString();
isNotice = int.parse(total) > 0;
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());
}
}