非营业状态 增加时间选择
This commit is contained in:
@@ -1,32 +1,47 @@
|
||||
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'; // 确保ID与View中一致
|
||||
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!)
|
||||
: '点击选择结束时间';
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// 1. 初始化默认时间
|
||||
customStartTime = DateTime.now();
|
||||
customEndTime = customStartTime!.add(const Duration(days: 1));
|
||||
renderData();
|
||||
}
|
||||
|
||||
String name = "";
|
||||
String address = "";
|
||||
String phone = "";
|
||||
String costPrice = ""; //氢气价格
|
||||
String customerPrice = ""; //官方价格
|
||||
String costPrice = "";
|
||||
String customerPrice = "";
|
||||
String startBusiness = "";
|
||||
String endBusiness = "";
|
||||
String timeStr = "";
|
||||
@@ -35,7 +50,6 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
|
||||
Future<void> renderData() async {
|
||||
showLoading("加载中");
|
||||
|
||||
try {
|
||||
var responseData = await HttpService.to.get(
|
||||
'appointment/station/getStationInfoById?hydrogenId=${StorageService.to.userId}',
|
||||
@@ -49,32 +63,30 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
|
||||
try {
|
||||
var result = BaseModel.fromJson(responseData.data);
|
||||
|
||||
name = result.data["name"];
|
||||
name = result.data["name"] ?? "";
|
||||
hydrogenId = result.data["hydrogenId"].toString();
|
||||
address = result.data["address"];
|
||||
var rawCostPrice = result.data["costPrice"];
|
||||
if (rawCostPrice != null && rawCostPrice.toString().isNotEmpty) {
|
||||
costPrice = "¥$rawCostPrice";
|
||||
} else {
|
||||
costPrice = "暂无价格";
|
||||
}
|
||||
var customerPriceTemp = result.data["customerPrice"];
|
||||
if (customerPriceTemp != null && customerPriceTemp.toString().isNotEmpty) {
|
||||
customerPrice = "$customerPriceTemp";
|
||||
} else {
|
||||
customerPrice = "暂无价格";
|
||||
}
|
||||
address = result.data["address"] ?? "";
|
||||
|
||||
phone = result.data["phone"];
|
||||
startBusiness = result.data["startBusiness"];
|
||||
endBusiness = result.data["endBusiness"];
|
||||
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) {
|
||||
// 营业时间为24小时的特殊处理
|
||||
if (startBusiness == "00:00:00" && endBusiness == "23:59:59") {
|
||||
timeStr = "24小时营业";
|
||||
} else {
|
||||
@@ -85,11 +97,9 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
}
|
||||
|
||||
operatingEnterprise = operatingEnterprise.isEmpty ? "暂未设置" : operatingEnterprise;
|
||||
|
||||
updateUi();
|
||||
dismissLoading();
|
||||
} catch (e) {
|
||||
// 如果解析 JSON 失败
|
||||
dismissLoading();
|
||||
showToast('数据异常');
|
||||
}
|
||||
@@ -98,7 +108,6 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新运营状态的方法
|
||||
void onOperationStatusChanged(String? newValue) {
|
||||
if (newValue != null) {
|
||||
selectedOperationStatus = newValue;
|
||||
@@ -106,9 +115,102 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void saveInfo() async {
|
||||
showLoading("保存中");
|
||||
/// 使用底部滚轮形式选择时间(下拉框效果)
|
||||
void pickDateTime(BuildContext context, bool isStart) {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime initialDate = isStart ? (customStartTime ?? now) : (customEndTime ?? now);
|
||||
|
||||
// 确保初始时间不早于最小允许时间
|
||||
// 将 minimumDate 稍微提前一点点(比如1分钟)
|
||||
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',
|
||||
@@ -123,11 +225,17 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
: 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) {
|
||||
if (responseData == null || responseData!.data == null) {
|
||||
dismissLoading();
|
||||
showToast('服务暂不可用,请稍后');
|
||||
return;
|
||||
@@ -143,10 +251,7 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
||||
}
|
||||
|
||||
void logout() async {
|
||||
// TODO: 在这里执行退出登录的逻辑
|
||||
//清理本地缓存的用户信息 导航到登录页面
|
||||
await StorageService.to.clearLoginInfo();
|
||||
|
||||
Get.offAll(() => LoginPage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,14 +127,12 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
_buildSectionTitle('运营信息'),
|
||||
Text('运营状态', style: TextStyle(color: Colors.grey[600], fontSize: 14)),
|
||||
const SizedBox(height: 8),
|
||||
//下拉选择框
|
||||
|
||||
// 下拉选择框
|
||||
DropdownButtonFormField<String>(
|
||||
value: controller.selectedOperationStatus,
|
||||
items: controller.operationStatusOptions.map((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
return DropdownMenuItem<String>(value: value, child: Text(value));
|
||||
}).toList(),
|
||||
onChanged: controller.onOperationStatusChanged,
|
||||
decoration: InputDecoration(
|
||||
@@ -142,8 +140,27 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildDisplayField(label: '营业时间', value: controller.timeStr),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// 根据状态动态显示 UI
|
||||
if (controller.selectedOperationStatus == "营运中")
|
||||
_buildDisplayField(label: '营业时间', value: controller.timeStr)
|
||||
else
|
||||
Column(
|
||||
children: [
|
||||
_buildClickField(
|
||||
label: '开始时间',
|
||||
value: controller.customStartTimeStr,
|
||||
onTap: () => controller.pickDateTime(context, true),
|
||||
),
|
||||
_buildClickField(
|
||||
label: '结束时间',
|
||||
value: controller.customEndTimeStr,
|
||||
onTap: () => controller.pickDateTime(context, false),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
_buildDisplayField(label: '联系电话', value: controller.phone),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
@@ -162,70 +179,6 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建静态提示信息卡片
|
||||
Widget _buildTipsCard() {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildInfoItem(Icons.info_outline, '请确保信息准确无误'),
|
||||
const SizedBox(height: 10),
|
||||
_buildInfoItem(Icons.help_outline, '价格信息将实时更新到用户端'),
|
||||
const SizedBox(height: 10),
|
||||
_buildInfoItem(Icons.headset_mic_outlined, '如有疑问请联系技术支持: 400-021-1773'),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.verified_outlined, color: Colors.blue, size: 20),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: FutureBuilder<String>(
|
||||
future: getVersion(),
|
||||
builder: (context, snapshot) {
|
||||
// 判断是否还在加载
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Text("");
|
||||
}
|
||||
|
||||
// 如果加载完成且有数据
|
||||
if (snapshot.hasData) {
|
||||
return TextX.labelSmall("当前版本: ${snapshot.data}",color: Colors.black54,);
|
||||
}
|
||||
|
||||
// 错误处理
|
||||
return const Text("");
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建退出登录按钮
|
||||
Widget _buildLogoutButton() {
|
||||
return ElevatedButton(
|
||||
onPressed: controller.logout,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
|
||||
elevation: 2,
|
||||
),
|
||||
child: const Text(
|
||||
'退出登录',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建带标题的表单区域
|
||||
Widget _buildSectionTitle(String title) {
|
||||
return Padding(
|
||||
@@ -253,7 +206,7 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[200], // 使用灰色背景以区分
|
||||
color: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
border: Border.all(color: Colors.grey[300]!),
|
||||
),
|
||||
@@ -267,6 +220,104 @@ class ReservationPage extends GetView<ReservationController> {
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建一个“可点击”的选择行
|
||||
Widget _buildClickField({required String label, required String value, required VoidCallback onTap}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: TextStyle(color: Colors.grey[600], fontSize: 14)),
|
||||
const SizedBox(height: 8),
|
||||
InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
border: Border.all(color: Colors.blue.withOpacity(0.5)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: const TextStyle(fontSize: 14, color: Colors.black87),
|
||||
),
|
||||
const Icon(Icons.calendar_month, size: 18, color: Colors.blue),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建静态提示信息卡片
|
||||
Widget _buildTipsCard() {
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildInfoItem(Icons.info_outline, '请确保信息准确无误'),
|
||||
const SizedBox(height: 10),
|
||||
_buildInfoItem(Icons.help_outline, '价格信息将实时更新到用户端'),
|
||||
const SizedBox(height: 10),
|
||||
_buildInfoItem(Icons.headset_mic_outlined, '如有疑问请联系技术支持: 400-021-1773'),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.verified_outlined, color: Colors.blue, size: 20),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: FutureBuilder<String>(
|
||||
future: getVersion(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Text("");
|
||||
}
|
||||
if (snapshot.hasData) {
|
||||
return TextX.labelSmall(
|
||||
"当前版本: ${snapshot.data}",
|
||||
color: Colors.black54,
|
||||
);
|
||||
}
|
||||
return const Text("");
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建退出登录按钮
|
||||
Widget _buildLogoutButton() {
|
||||
return ElevatedButton(
|
||||
onPressed: controller.logout,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
|
||||
elevation: 2,
|
||||
),
|
||||
child: const Text(
|
||||
'退出登录',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建带图标的提示信息行
|
||||
Widget _buildInfoItem(IconData icon, String text) {
|
||||
return Row(
|
||||
|
||||
Reference in New Issue
Block a user