Compare commits
13 Commits
dev_featur
...
45f5035d1b
| Author | SHA1 | Date | |
|---|---|---|---|
| 45f5035d1b | |||
| f792915429 | |||
| edbacc502b | |||
| 5722e3ace0 | |||
| d41b21654a | |||
| 2eb059defd | |||
| fbcc85af2a | |||
| 9a97b56505 | |||
| 8302d7c179 | |||
| e7a9e4483a | |||
| 9b64fdfa52 | |||
| d8f335eb4e | |||
| d1b7a9eb76 |
@@ -1,3 +1,6 @@
|
|||||||
|
import java.util.Properties
|
||||||
|
import java.io.FileInputStream
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
id("kotlin-android")
|
id("kotlin-android")
|
||||||
@@ -5,6 +8,14 @@ plugins {
|
|||||||
id("dev.flutter.flutter-gradle-plugin")
|
id("dev.flutter.flutter-gradle-plugin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val keystoreProperties = Properties()
|
||||||
|
val keystorePropertiesFile = rootProject.file("key.properties")
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystorePropertiesFile.inputStream().use { input ->
|
||||||
|
keystoreProperties.load(input.reader(Charsets.UTF_8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.lnkj.ln_jq_app"
|
namespace = "com.lnkj.ln_jq_app"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
@@ -26,15 +37,30 @@ android {
|
|||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = flutter.minSdkVersion
|
minSdk = flutter.minSdkVersion
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode = 4
|
versionCode = 5
|
||||||
versionName = "1.2.1"
|
versionName = "1.2.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
create("release") {
|
||||||
|
keyAlias = keystoreProperties["keyAlias"] as String?
|
||||||
|
keyPassword = keystoreProperties["keyPassword"] as String?
|
||||||
|
val storeFilePath = keystoreProperties["storeFile"] as String?
|
||||||
|
storeFile = if (storeFilePath != null) file(storeFilePath) else null
|
||||||
|
storePassword = keystoreProperties["storePassword"] as String?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
getByName("release") {
|
||||||
// TODO: Add your own signing config for the release build.
|
// 使用上面定义的 release 签名
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
signingConfig = signingConfigs.getByName("release")
|
||||||
signingConfig = signingConfigs.getByName("debug")
|
|
||||||
|
// 修复混淆规则引用语法
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
ln_jq_app/android/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Please add these rules to your existing keep rules in order to suppress warnings.
|
||||||
|
# This is generated automatically by the Android Gradle plugin.
|
||||||
|
|
||||||
|
# 忽略 Google Play Core 相关的缺失警告(解决你目前的报错)
|
||||||
|
-dontwarn com.google.android.play.core.**
|
||||||
|
|
||||||
|
# Flutter 基础规则
|
||||||
|
-keep class io.flutter.app.** { *; }
|
||||||
|
-keep class io.flutter.plugin.** { *; }
|
||||||
|
-keep class io.flutter.util.** { *; }
|
||||||
|
-keep class io.flutter.view.** { *; }
|
||||||
|
-keep class io.flutter.** { *; }
|
||||||
|
-keep class io.flutter.plugins.** { *; }
|
||||||
|
|
||||||
|
|
||||||
|
-dontwarn com.huawei.android.os.BuildEx$VERSION
|
||||||
|
-dontwarn com.huawei.hianalytics.process.HiAnalyticsConfig$Builder
|
||||||
|
-dontwarn com.huawei.hianalytics.process.HiAnalyticsConfig
|
||||||
|
-dontwarn com.huawei.hianalytics.process.HiAnalyticsInstance$Builder
|
||||||
|
-dontwarn com.huawei.hianalytics.process.HiAnalyticsInstance
|
||||||
|
-dontwarn com.huawei.hianalytics.process.HiAnalyticsManager
|
||||||
|
-dontwarn com.huawei.hianalytics.util.HiAnalyticTools
|
||||||
|
-dontwarn com.huawei.hms.availableupdate.UpdateAdapterMgr
|
||||||
|
-dontwarn com.huawei.libcore.io.ExternalStorageFile
|
||||||
|
-dontwarn com.huawei.libcore.io.ExternalStorageFileInputStream
|
||||||
|
-dontwarn com.huawei.libcore.io.ExternalStorageFileOutputStream
|
||||||
|
-dontwarn com.huawei.libcore.io.ExternalStorageRandomAccessFile
|
||||||
|
-dontwarn org.android.netutil.PingEntry
|
||||||
|
-dontwarn org.android.netutil.PingResponse
|
||||||
|
-dontwarn org.android.netutil.PingTask
|
||||||
|
-dontwarn org.bouncycastle.crypto.BlockCipher
|
||||||
|
-dontwarn org.bouncycastle.crypto.engines.AESEngine
|
||||||
|
-dontwarn org.bouncycastle.crypto.prng.SP800SecureRandom
|
||||||
|
-dontwarn org.bouncycastle.crypto.prng.SP800SecureRandomBuilder
|
||||||
|
|
||||||
|
|
||||||
|
-keepclasseswithmembernames class ** {
|
||||||
|
native <methods>;
|
||||||
|
}
|
||||||
|
-keepattributes Signature
|
||||||
|
-keep class sun.misc.Unsafe { *; }
|
||||||
|
-keep class com.taobao.** {*;}
|
||||||
|
-keep class com.alibaba.** {*;}
|
||||||
|
-keep class com.alipay.** {*;}
|
||||||
|
-keep class com.ut.** {*;}
|
||||||
|
-keep class com.ta.** {*;}
|
||||||
|
-keep class anet.**{*;}
|
||||||
|
-keep class anetwork.**{*;}
|
||||||
|
-keep class org.android.spdy.**{*;}
|
||||||
|
-keep class org.android.agoo.**{*;}
|
||||||
|
-keep class android.os.**{*;}
|
||||||
|
-keep class org.json.**{*;}
|
||||||
|
-dontwarn com.taobao.**
|
||||||
|
-dontwarn com.alibaba.**
|
||||||
|
-dontwarn com.alipay.**
|
||||||
|
-dontwarn anet.**
|
||||||
|
-dontwarn org.android.spdy.**
|
||||||
|
-dontwarn org.android.agoo.**
|
||||||
|
-dontwarn anetwork.**
|
||||||
|
-dontwarn com.ut.**
|
||||||
|
-dontwarn com.ta.**
|
||||||
|
Before Width: | Height: | Size: 6.0 KiB |
BIN
ln_jq_app/android/app/src/main/res/mipmap-xhdpi/logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
@@ -13,7 +13,7 @@
|
|||||||
"size" : "20x20"
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"filename" : "Icon-App-29x29 1.png",
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "29x29"
|
"size" : "29x29"
|
||||||
@@ -31,25 +31,25 @@
|
|||||||
"size" : "29x29"
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-80x80.jpg",
|
"filename" : "Icon-App-80x80.png",
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "40x40"
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-120x120.jpg",
|
"filename" : "Icon-App-120x120.png",
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
"scale" : "3x",
|
"scale" : "3x",
|
||||||
"size" : "40x40"
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-120x120 1.jpg",
|
"filename" : "Icon-App-120x120 1.png",
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "60x60"
|
"size" : "60x60"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-180.jpg",
|
"filename" : "Icon-App-180.png",
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
"scale" : "3x",
|
"scale" : "3x",
|
||||||
"size" : "60x60"
|
"size" : "60x60"
|
||||||
@@ -61,19 +61,19 @@
|
|||||||
"size" : "20x20"
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-20x20@2x.png",
|
"filename" : "Icon-App-20x20@2x 1.png",
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "20x20"
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"filename" : "Icon-App-29x29.png",
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "29x29"
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-29x29@2x.png",
|
"filename" : "Icon-App-29x29@2x 1.png",
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "29x29"
|
"size" : "29x29"
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
"size" : "40x40"
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-App-76x76@1x.png",
|
"filename" : "Icon-App-76x76.png",
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "76x76"
|
"size" : "76x76"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 509 B After Width: | Height: | Size: 465 B |
|
After Width: | Height: | Size: 849 B |
|
Before Width: | Height: | Size: 848 B After Width: | Height: | Size: 849 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 613 B |
|
After Width: | Height: | Size: 613 B |
|
Before Width: | Height: | Size: 707 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -8,11 +8,11 @@ class AppTheme {
|
|||||||
static const Color themeColor = Color(0xFF0c83c3);
|
static const Color themeColor = Color(0xFF0c83c3);
|
||||||
|
|
||||||
//是否开放域名切换
|
//是否开放域名切换
|
||||||
static const bool is_show_host = true;
|
static const bool is_show_host = false;
|
||||||
|
|
||||||
//http://192.168.110.222:8080/
|
//http://192.168.110.222:8080/
|
||||||
//http://192.168.110.44:8080/
|
//http://192.168.110.44:8080/
|
||||||
static String test_service_url = "https://beta-esg.api.lnh2e.com/";
|
static String test_service_url = "http://47.101.201.13:8443/api/";
|
||||||
static const String release_service_url = "";
|
static const String release_service_url = "";
|
||||||
|
|
||||||
//加氢站相关查询
|
//加氢站相关查询
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ void main() async {
|
|||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
WidgetsBinding widgetsBinding = await init(
|
WidgetsBinding widgetsBinding = await init(
|
||||||
isDebug: true,
|
isDebug: false,
|
||||||
logTag: '小羚羚',
|
logTag: '小羚羚',
|
||||||
supportedLocales: [Locale('zh', 'CN')],
|
supportedLocales: [Locale('zh', 'CN')],
|
||||||
);
|
);
|
||||||
@@ -31,7 +31,7 @@ void main() async {
|
|||||||
// 设计稿尺寸 单位:dp
|
// 设计稿尺寸 单位:dp
|
||||||
designSize: const Size(390, 844),
|
designSize: const Size(390, 844),
|
||||||
// Getx Log
|
// Getx Log
|
||||||
enableLog: true,
|
enableLog: false,
|
||||||
// 默认的跳转动画
|
// 默认的跳转动画
|
||||||
defaultTransition: Transition.rightToLeft,
|
defaultTransition: Transition.rightToLeft,
|
||||||
// 主题模式
|
// 主题模式
|
||||||
@@ -74,6 +74,9 @@ void initHttpSet() {
|
|||||||
// 设置全局响应处理器
|
// 设置全局响应处理器
|
||||||
HttpService.to.setOnResponseHandler((response) async {
|
HttpService.to.setOnResponseHandler((response) async {
|
||||||
try {
|
try {
|
||||||
|
if (response.data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
final baseModel = BaseModel.fromJson(response.data);
|
final baseModel = BaseModel.fromJson(response.data);
|
||||||
if (baseModel.code == 0 || baseModel.code == 200) {
|
if (baseModel.code == 0 || baseModel.code == 200) {
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,10 @@ class HistoryPage extends GetView<HistoryController> {
|
|||||||
text = '未加氢';
|
text = '未加氢';
|
||||||
color = Colors.red;
|
color = Colors.red;
|
||||||
break;
|
break;
|
||||||
|
case ReservationStatus.cancel:
|
||||||
|
text = '已取消';
|
||||||
|
color = Colors.red;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
text = '未知状态';
|
text = '未知状态';
|
||||||
color = Colors.grey;
|
color = Colors.grey;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -33,6 +35,9 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
final TextEditingController broadcastContentController = TextEditingController();
|
final TextEditingController broadcastContentController = TextEditingController();
|
||||||
final RxInt selectedTabIndex = 0.obs;
|
final RxInt selectedTabIndex = 0.obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get listenLifecycleEvent => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
@@ -40,6 +45,38 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
customStartTime = DateTime.now();
|
customStartTime = DateTime.now();
|
||||||
customEndTime = customStartTime!.add(const Duration(days: 1));
|
customEndTime = customStartTime!.add(const Duration(days: 1));
|
||||||
renderData();
|
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 name = "";
|
||||||
@@ -56,6 +93,7 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
String jobTipStr = "";
|
String jobTipStr = "";
|
||||||
String jobDetailsStr = "";
|
String jobDetailsStr = "";
|
||||||
String jobId = "";
|
String jobId = "";
|
||||||
|
Timer? _refreshTimer;
|
||||||
|
|
||||||
Future<void> renderData() async {
|
Future<void> renderData() async {
|
||||||
showLoading("加载中");
|
showLoading("加载中");
|
||||||
@@ -65,11 +103,16 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
if (jobData != null) {
|
if (jobData != null) {
|
||||||
final jobDataResult = BaseModel.fromJson(jobData.data);
|
final jobDataResult = BaseModel.fromJson(jobData.data);
|
||||||
if (jobDataResult.code == 0) {
|
if (jobDataResult.code == 0) {
|
||||||
try{
|
try {
|
||||||
jobId = jobDataResult.data["id"] ?? "";
|
final List<dynamic> dataList = jobDataResult.data is List
|
||||||
String endTime = jobDataResult.data["endTime"] ?? "";
|
? jobDataResult.data
|
||||||
String beginTime = jobDataResult.data["beginTime"] ?? "";
|
: [];
|
||||||
String hydStatus = jobDataResult.data["hydStatus"] ?? "";
|
final firstJob = dataList[0];
|
||||||
|
|
||||||
|
jobId = firstJob["id"] ?? "";
|
||||||
|
String endTime = firstJob["endTime"] ?? "";
|
||||||
|
String beginTime = firstJob["beginTime"] ?? "";
|
||||||
|
String hydStatus = firstJob["hydStatus"].toString() ?? "";
|
||||||
String hydStatusStr = "";
|
String hydStatusStr = "";
|
||||||
if (hydStatus == "0") {
|
if (hydStatus == "0") {
|
||||||
hydStatusStr = "营运中";
|
hydStatusStr = "营运中";
|
||||||
@@ -81,28 +124,52 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
hydStatusStr = "暂停营业";
|
hydStatusStr = "暂停营业";
|
||||||
}
|
}
|
||||||
|
|
||||||
jobDetailsStr = "当前站点已设置$beginTime-$endTime为$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) {
|
if (endTime.isNotEmpty) {
|
||||||
try {
|
try {
|
||||||
// 解析时间字符串
|
// 解析时间字符串
|
||||||
DateTime endDateTime = DateTime.parse(endTime);
|
DateTime endDateTime = DateTime.parse(endTime);
|
||||||
DateTime beginDateTime = DateTime.parse(beginTime);
|
DateTime beginDateTime = DateTime.parse(beginTime);
|
||||||
DateTime now = DateTime.now(); // 2. 计算时间差 (endTime - now)
|
DateTime now = DateTime.now(); //计算时间差 (endTime - now)
|
||||||
Duration diff = endDateTime.difference(now);
|
Duration diff = endDateTime.difference(now);
|
||||||
|
|
||||||
// 计算小时数 (允许小数,例如 0.5)
|
// 计算小时数 (允许小数,例如 0.5)
|
||||||
// inMinutes / 60 可以得到更精确的小数小时
|
// inMinutes / 60 可以得到更精确的小数小时
|
||||||
double hoursLeft = diff.inMinutes / 60.0;
|
double hoursLeft = diff.inMinutes / 60.0;
|
||||||
|
|
||||||
if (hoursLeft > 0) {
|
//计算当前时间-开始时间
|
||||||
|
Duration startDiff = beginDateTime.difference(now);
|
||||||
|
double hoursUntilStart = startDiff.inMinutes / 60.0;
|
||||||
|
|
||||||
|
|
||||||
|
// 只有在【当前时间早于开始时间】且【剩余时间大于0】时才显示文案
|
||||||
|
if (now.isBefore(beginDateTime) && hoursLeft > 0) {
|
||||||
// 如果是正数,表示还有多久结束
|
// 如果是正数,表示还有多久结束
|
||||||
String timeTip = "${hoursLeft.toStringAsFixed(1)}小时后";
|
String timeTip = " ${hoursUntilStart.toStringAsFixed(2)}小时后";
|
||||||
jobTipStr = "$timeTip$hydStatusStr";
|
jobTipStr = "$timeTip$hydStatusStr";
|
||||||
} else {
|
} else {
|
||||||
jobTipStr = "";
|
jobTipStr = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobDetailsStr =
|
||||||
|
"当前站点已设置$beginTime至$endTime,共${hoursLeft.toStringAsFixed(2)}小时,为$hydStatusStr状态";
|
||||||
|
|
||||||
// 如果是处于非营运状态,自动回填开始和结束时间
|
// 如果是处于非营运状态,自动回填开始和结束时间
|
||||||
// 假设 customStartTime 是现在,customEndTime 是接口返回的结束时间
|
// 假设 customStartTime 是现在,customEndTime 是接口返回的结束时间
|
||||||
customStartTime = beginDateTime;
|
customStartTime = beginDateTime;
|
||||||
@@ -111,8 +178,10 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
print("时间解析失败: $e");
|
print("时间解析失败: $e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (e){
|
} catch (e) {
|
||||||
Logger.d("解析失败: $e");
|
Logger.d("解析失败或者没返回信息: $e");
|
||||||
|
|
||||||
|
jobTipStr = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,6 +351,7 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
'appointment/station/updateStationStatus',
|
'appointment/station/updateStationStatus',
|
||||||
data: {
|
data: {
|
||||||
'hydrogenId': hydrogenId,
|
'hydrogenId': hydrogenId,
|
||||||
|
'name': name,
|
||||||
'siteStatus': selectedOperationStatus == "营运中"
|
'siteStatus': selectedOperationStatus == "营运中"
|
||||||
? "0"
|
? "0"
|
||||||
: selectedOperationStatus == "维修中"
|
: selectedOperationStatus == "维修中"
|
||||||
@@ -309,6 +379,9 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
var result = BaseModel.fromJson(responseData.data);
|
var result = BaseModel.fromJson(responseData.data);
|
||||||
if (result.code == 0) {
|
if (result.code == 0) {
|
||||||
showSuccessToast("保存成功,已同步通知对应司机");
|
showSuccessToast("保存成功,已同步通知对应司机");
|
||||||
|
|
||||||
|
//重新刷新页面
|
||||||
|
renderData();
|
||||||
}
|
}
|
||||||
dismissLoading();
|
dismissLoading();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -325,10 +398,7 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
|
|
||||||
DialogX.to.showConfirmDialog(
|
DialogX.to.showConfirmDialog(
|
||||||
title: '当前设置详情',
|
title: '当前设置详情',
|
||||||
content: Text(
|
content: Text(jobDetailsStr, style: const TextStyle(fontSize: 15, height: 1.5)),
|
||||||
jobDetailsStr,
|
|
||||||
style: const TextStyle(fontSize: 15, height: 1.5),
|
|
||||||
),
|
|
||||||
confirmText: '好的',
|
confirmText: '好的',
|
||||||
cancelText: '取消设置',
|
cancelText: '取消设置',
|
||||||
onCancel: () {
|
onCancel: () {
|
||||||
@@ -342,9 +412,7 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
void _cancelJob() async {
|
void _cancelJob() async {
|
||||||
showLoading("正在取消...");
|
showLoading("正在取消...");
|
||||||
try {
|
try {
|
||||||
var response = await HttpService.to.delete(
|
var response = await HttpService.to.delete('appointment/job/hyd/$jobId');
|
||||||
'appointment/job/hyd/$jobId',
|
|
||||||
);
|
|
||||||
|
|
||||||
dismissLoading();
|
dismissLoading();
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
@@ -404,11 +472,4 @@ class ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
await StorageService.to.clearLoginInfo();
|
await StorageService.to.clearLoginInfo();
|
||||||
Get.offAll(() => LoginPage());
|
Get.offAll(() => LoginPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void onClose() {
|
|
||||||
broadcastTitleController.dispose();
|
|
||||||
broadcastContentController.dispose();
|
|
||||||
super.onClose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,8 @@ class ReservationPage extends GetView<ReservationController> {
|
|||||||
controller.jobTipStr,
|
controller.jobTipStr,
|
||||||
style: TextStyle(color: Colors.yellow[800], fontSize: 14),
|
style: TextStyle(color: Colors.yellow[800], fontSize: 14),
|
||||||
),
|
),
|
||||||
Icon(AntdIcon.question_circle, size: 14, color: Colors.yellow[800]),
|
SizedBox(width: 2.w),
|
||||||
|
Icon(AntdIcon.info_circle, size: 14, color: Colors.yellow[800]),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ enum ReservationStatus {
|
|||||||
completed, // 完成 ( addStatus: 1)
|
completed, // 完成 ( addStatus: 1)
|
||||||
rejected, // 拒绝 ( -1)
|
rejected, // 拒绝 ( -1)
|
||||||
unadded, // 未加 ( 2)
|
unadded, // 未加 ( 2)
|
||||||
|
cancel, // 取消预约
|
||||||
unknown, // 未知状态
|
unknown, // 未知状态
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReservationModel {
|
class ReservationModel {
|
||||||
final String id;
|
final String id;
|
||||||
|
final String stationId;
|
||||||
final String plateNumber;
|
final String plateNumber;
|
||||||
String amount;
|
String amount;
|
||||||
final String time;
|
final String time;
|
||||||
@@ -40,6 +42,7 @@ class ReservationModel {
|
|||||||
|
|
||||||
ReservationModel({
|
ReservationModel({
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.stationId,
|
||||||
required this.plateNumber,
|
required this.plateNumber,
|
||||||
required this.amount,
|
required this.amount,
|
||||||
required this.time,
|
required this.time,
|
||||||
@@ -80,6 +83,9 @@ class ReservationModel {
|
|||||||
case 2:
|
case 2:
|
||||||
currentStatus = ReservationStatus.unadded;
|
currentStatus = ReservationStatus.unadded;
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
currentStatus = ReservationStatus.cancel;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
currentStatus = ReservationStatus.unknown;
|
currentStatus = ReservationStatus.unknown;
|
||||||
}
|
}
|
||||||
@@ -97,6 +103,7 @@ class ReservationModel {
|
|||||||
return ReservationModel(
|
return ReservationModel(
|
||||||
// 原始字段,用于UI兼容
|
// 原始字段,用于UI兼容
|
||||||
id: json['id']?.toString() ?? '',
|
id: json['id']?.toString() ?? '',
|
||||||
|
stationId: json['stationId']?.toString() ?? '',
|
||||||
plateNumber: json['plateNumber']?.toString() ?? '未知车牌',
|
plateNumber: json['plateNumber']?.toString() ?? '未知车牌',
|
||||||
amount: '${json['hydAmount']?.toString() ?? '0'}kg',
|
amount: '${json['hydAmount']?.toString() ?? '0'}kg',
|
||||||
time: timeRange,
|
time: timeRange,
|
||||||
@@ -137,20 +144,50 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
|
|
||||||
final TextEditingController searchController = TextEditingController();
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get listenLifecycleEvent => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
renderData();
|
renderData();
|
||||||
|
msgNotice();
|
||||||
startAutoRefresh();
|
startAutoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onPaused() {
|
||||||
|
stopAutoRefresh();
|
||||||
|
super.onPaused();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
stopAutoRefresh();
|
stopAutoRefresh();
|
||||||
searchController.dispose();
|
searchController.dispose();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
bool isNotice = false;
|
||||||
|
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 startAutoRefresh() {
|
void startAutoRefresh() {
|
||||||
// 先停止已存在的定时器,防止重复启动
|
// 先停止已存在的定时器,防止重复启动
|
||||||
@@ -162,7 +199,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 【6. 新增】停止定时器的方法
|
///停止定时器的方法
|
||||||
void stopAutoRefresh() {
|
void stopAutoRefresh() {
|
||||||
// 如果定时器存在并且是激活状态,就取消它
|
// 如果定时器存在并且是激活状态,就取消它
|
||||||
_refreshTimer?.cancel();
|
_refreshTimer?.cancel();
|
||||||
@@ -184,6 +221,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
'pageNum': 1,
|
'pageNum': 1,
|
||||||
'pageSize': 50, // 暂时不考虑分页,一次获取30条
|
'pageSize': 50, // 暂时不考虑分页,一次获取30条
|
||||||
'keyword': searchText, // 加氢站名称、手机号
|
'keyword': searchText, // 加氢站名称、手机号
|
||||||
|
'stationId': StorageService.to.userId
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -580,7 +618,6 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
//加载列表数据
|
//加载列表数据
|
||||||
fetchReservationData();
|
fetchReservationData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:getx_scaffold/getx_scaffold.dart';
|
import 'package:getx_scaffold/getx_scaffold.dart';
|
||||||
import 'package:ln_jq_app/common/styles/theme.dart';
|
import 'package:ln_jq_app/common/styles/theme.dart';
|
||||||
import 'package:ln_jq_app/pages/b_page/history/view.dart';
|
import 'package:ln_jq_app/pages/b_page/history/view.dart';
|
||||||
|
import 'package:ln_jq_app/pages/c_page/message/view.dart' show MessagePage;
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
|
|
||||||
@@ -42,9 +43,11 @@ class SitePage extends GetView<SiteController> {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Icons.calendar_today, color: Colors.blue, size: 32),
|
const Icon(Icons.calendar_today, color: Colors.blue, size: 32),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
const Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'今日预约统计',
|
'今日预约统计',
|
||||||
@@ -53,15 +56,9 @@ class SitePage extends GetView<SiteController> {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
SizedBox(width: 5.w,),
|
||||||
"Today's Reservation Statistics",
|
|
||||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 10,
|
horizontal: 10,
|
||||||
vertical: 4,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
@@ -69,7 +66,7 @@ class SitePage extends GetView<SiteController> {
|
|||||||
color: Colors.blue.withOpacity(0.1),
|
color: Colors.blue.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: const Text(
|
child: Text(
|
||||||
'实时',
|
'实时',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
@@ -80,6 +77,43 @@ class SitePage extends GetView<SiteController> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
"Today's Reservation Statistics",
|
||||||
|
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () async {
|
||||||
|
// 跳转消息中心
|
||||||
|
var scanResult = await Get.to(() => const MessagePage());
|
||||||
|
if (scanResult == null) {
|
||||||
|
controller.msgNotice();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 这里的 style 是为了模拟你图片里的灰色圆形背景
|
||||||
|
style: IconButton.styleFrom(
|
||||||
|
backgroundColor: Colors.grey[100],
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
),
|
||||||
|
icon: Badge(
|
||||||
|
// label: Text('3'), // 如果你想显示数字,就加 label
|
||||||
|
smallSize: 8,
|
||||||
|
// 红点的大小
|
||||||
|
backgroundColor: controller.isNotice
|
||||||
|
? Colors.red
|
||||||
|
: Colors.white,
|
||||||
|
// 红点颜色
|
||||||
|
child: Icon(
|
||||||
|
Icons.notifications_outlined,
|
||||||
|
color: Colors.black87,
|
||||||
|
size: 25,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
const Divider(height: 1, indent: 16, endIndent: 16),
|
const Divider(height: 1, indent: 16, endIndent: 16),
|
||||||
@@ -132,7 +166,7 @@ class SitePage extends GetView<SiteController> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'今日预约信息',
|
'预约信息',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -156,9 +190,7 @@ class SitePage extends GetView<SiteController> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Get.to(
|
Get.to(
|
||||||
() => HistoryPage(),
|
() => HistoryPage(),
|
||||||
arguments: {
|
arguments: {'stationName': controller.name},
|
||||||
'stationName': controller.name,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
@@ -465,6 +497,10 @@ class SitePage extends GetView<SiteController> {
|
|||||||
text = '未加氢';
|
text = '未加氢';
|
||||||
color = Colors.red;
|
color = Colors.red;
|
||||||
break;
|
break;
|
||||||
|
case ReservationStatus.cancel:
|
||||||
|
text = '已取消';
|
||||||
|
color = Colors.red;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
text = '未知状态';
|
text = '未知状态';
|
||||||
color = Colors.grey;
|
color = Colors.grey;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class CarInfoController extends GetxController with BaseControllerMixin {
|
|||||||
// 如果未绑定车辆,且本次会话尚未提示过,则弹出提示
|
// 如果未绑定车辆,且本次会话尚未提示过,则弹出提示
|
||||||
if (!StorageService.to.hasShownBindVehicleDialog &&
|
if (!StorageService.to.hasShownBindVehicleDialog &&
|
||||||
StorageService.to.isLoggedIn &&
|
StorageService.to.isLoggedIn &&
|
||||||
|
StorageService.to.loginChannel == LoginChannel.driver &&
|
||||||
!StorageService.to.hasVehicleInfo) {
|
!StorageService.to.hasVehicleInfo) {
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
DialogX.to.showConfirmDialog(
|
DialogX.to.showConfirmDialog(
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ class MessageController extends GetxController {
|
|||||||
_loadData(isRefresh: true);
|
_loadData(isRefresh: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onRefresh() => _loadData(isRefresh: true);
|
||||||
|
|
||||||
|
void onLoading() => _loadData(isRefresh: false);
|
||||||
|
|
||||||
Future<void> _loadData({bool isRefresh = false}) async {
|
Future<void> _loadData({bool isRefresh = false}) async {
|
||||||
final int targetPage = isRefresh ? 1 : _pageNum + 1;
|
final int targetPage = isRefresh ? 1 : _pageNum + 1;
|
||||||
|
|
||||||
@@ -100,9 +104,7 @@ class MessageController extends GetxController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRefresh() => _loadData(isRefresh: true);
|
|
||||||
|
|
||||||
void onLoading() => _loadData(isRefresh: false);
|
|
||||||
|
|
||||||
// 标记全部已读
|
// 标记全部已读
|
||||||
void markAllRead() async {
|
void markAllRead() async {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class MineController extends GetxController with BaseControllerMixin {
|
|||||||
_fetchAccidentCount(), // 请求2:事故数
|
_fetchAccidentCount(), // 请求2:事故数
|
||||||
_fetchBreakRulesCount(), // 请求3:违章数
|
_fetchBreakRulesCount(), // 请求3:违章数
|
||||||
_rating(), // 司机评分
|
_rating(), // 司机评分
|
||||||
_msgNotice(), // 红点消息
|
msgNotice(), // 红点消息
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await renderViolation();
|
await renderViolation();
|
||||||
@@ -69,7 +69,7 @@ class MineController extends GetxController with BaseControllerMixin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _msgNotice() async {
|
Future<void> msgNotice() async {
|
||||||
final Map<String, dynamic> requestData = {
|
final Map<String, dynamic> requestData = {
|
||||||
'appFlag': 1,
|
'appFlag': 1,
|
||||||
'isRead': 1,
|
'isRead': 1,
|
||||||
@@ -85,6 +85,7 @@ class MineController extends GetxController with BaseControllerMixin {
|
|||||||
if (result.code == 0 && result.data != null) {
|
if (result.code == 0 && result.data != null) {
|
||||||
String total = result.data["total"].toString();
|
String total = result.data["total"].toString();
|
||||||
isNotice = int.parse(total) > 0;
|
isNotice = int.parse(total) > 0;
|
||||||
|
updateUi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,9 +82,12 @@ class MinePage extends GetView<MineController> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
// 跳转消息中心
|
// 跳转消息中心
|
||||||
Get.to(() => const MessagePage());
|
var scanResult = await Get.to(() => const MessagePage());
|
||||||
|
if (scanResult == null) {
|
||||||
|
controller.msgNotice();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 这里的 style 是为了模拟你图片里的灰色圆形背景
|
// 这里的 style 是为了模拟你图片里的灰色圆形背景
|
||||||
style: IconButton.styleFrom(
|
style: IconButton.styleFrom(
|
||||||
|
|||||||
@@ -2,17 +2,11 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:getx_scaffold/common/common.dart';
|
|
||||||
import 'package:getx_scaffold/common/services/http.dart';
|
|
||||||
import 'package:getx_scaffold/getx_scaffold.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/common/model/base_model.dart';
|
||||||
import 'package:ln_jq_app/common/model/station_model.dart';
|
import 'package:ln_jq_app/common/model/station_model.dart';
|
||||||
import 'package:ln_jq_app/common/model/vehicle_info.dart';
|
import 'package:ln_jq_app/common/model/vehicle_info.dart';
|
||||||
import 'package:ln_jq_app/pages/b_page/site/controller.dart';
|
import 'package:ln_jq_app/pages/b_page/site/controller.dart';
|
||||||
import 'package:ln_jq_app/pages/c_page/reservation_edit/controller.dart';
|
|
||||||
import 'package:ln_jq_app/pages/c_page/reservation_edit/view.dart';
|
|
||||||
import 'package:ln_jq_app/pages/qr_code/view.dart';
|
import 'package:ln_jq_app/pages/qr_code/view.dart';
|
||||||
import 'package:ln_jq_app/storage_service.dart';
|
import 'package:ln_jq_app/storage_service.dart';
|
||||||
|
|
||||||
@@ -341,12 +335,12 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
final startTimeStr =
|
final startTimeStr =
|
||||||
'$dateStr ${_formatTimeOfDay(startTime.value)}:00'; // Use helper directly
|
'$dateStr ${_formatTimeOfDay(startTime.value)}:00'; // Use helper directly
|
||||||
|
|
||||||
if (lastSuccessfulReservation != null &&
|
/*if (lastSuccessfulReservation != null &&
|
||||||
lastSuccessfulReservation!.id == selectedStationId.value &&
|
lastSuccessfulReservation!.id == selectedStationId.value &&
|
||||||
lastSuccessfulReservation!.startTime == startTimeStr) {
|
lastSuccessfulReservation!.startTime == startTimeStr) {
|
||||||
showToast("请勿重复提交相同时间段的预约,可在“查看预约”中修改");
|
showToast("请勿重复提交相同时间段的预约,可在“查看预约”中修改");
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
final reservationEndDateTime = DateTime(
|
final reservationEndDateTime = DateTime(
|
||||||
selectedDate.value.year,
|
selectedDate.value.year,
|
||||||
@@ -395,7 +389,6 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
);
|
);
|
||||||
var result = BaseModel.fromJson(responseData?.data);
|
var result = BaseModel.fromJson(responseData?.data);
|
||||||
|
|
||||||
|
|
||||||
if (responseData == null || result.code != 0) {
|
if (responseData == null || result.code != 0) {
|
||||||
dismissLoading();
|
dismissLoading();
|
||||||
showToast(result.error);
|
showToast(result.error);
|
||||||
@@ -408,6 +401,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
|
|
||||||
lastSuccessfulReservation = ReservationModel(
|
lastSuccessfulReservation = ReservationModel(
|
||||||
id: selectedStationId.value!,
|
id: selectedStationId.value!,
|
||||||
|
stationId: '',
|
||||||
hydAmount: ampuntStr,
|
hydAmount: ampuntStr,
|
||||||
startTime: startTimeStr,
|
startTime: startTimeStr,
|
||||||
endTime: endTimeStr,
|
endTime: endTimeStr,
|
||||||
@@ -546,6 +540,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
//用来管理查看预约的弹窗
|
//用来管理查看预约的弹窗
|
||||||
Worker? _sheetWorker;
|
Worker? _sheetWorker;
|
||||||
bool init = false;
|
bool init = false;
|
||||||
|
Timer? _refreshTimer;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get listenLifecycleEvent => true;
|
bool get listenLifecycleEvent => true;
|
||||||
@@ -555,7 +550,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
super.onInit();
|
super.onInit();
|
||||||
getUserBindCarInfo();
|
getUserBindCarInfo();
|
||||||
getSiteList();
|
getSiteList();
|
||||||
|
startAutoRefresh();
|
||||||
if (!init) {
|
if (!init) {
|
||||||
_setupListener();
|
_setupListener();
|
||||||
init = true;
|
init = true;
|
||||||
@@ -563,9 +558,26 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void onPaused() {
|
||||||
_sheetWorker?.dispose();
|
stopAutoRefresh();
|
||||||
super.dispose();
|
super.onPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
void startAutoRefresh() {
|
||||||
|
// 先停止已存在的定时器,防止重复启动
|
||||||
|
stopAutoRefresh();
|
||||||
|
|
||||||
|
// 创建一个每1分钟执行一次的周期性定时器
|
||||||
|
_refreshTimer = Timer.periodic(const Duration(minutes: 1), (timer) {
|
||||||
|
getSiteList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
///停止定时器的方法
|
||||||
|
void stopAutoRefresh() {
|
||||||
|
// 如果定时器存在并且是激活状态,就取消它
|
||||||
|
_refreshTimer?.cancel();
|
||||||
|
_refreshTimer = null; // 置为null,方便判断
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setupListener() {
|
void _setupListener() {
|
||||||
@@ -691,7 +703,9 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
try {
|
try {
|
||||||
showLoading("加氢站数据加载中");
|
showLoading("加氢站数据加载中");
|
||||||
|
|
||||||
var responseData = await HttpService.to.get("appointment/station/queryHydrogenSiteInfo");
|
var responseData = await HttpService.to.get(
|
||||||
|
"appointment/station/queryHydrogenSiteInfo",
|
||||||
|
);
|
||||||
|
|
||||||
if (responseData == null || responseData.data == null) {
|
if (responseData == null || responseData.data == null) {
|
||||||
showToast('暂时无法获取站点信息');
|
showToast('暂时无法获取站点信息');
|
||||||
@@ -743,6 +757,7 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
// 如果未绑定车辆,且本次会话尚未提示过,则弹出提示
|
// 如果未绑定车辆,且本次会话尚未提示过,则弹出提示
|
||||||
if (!StorageService.to.hasShownBindVehicleDialog &&
|
if (!StorageService.to.hasShownBindVehicleDialog &&
|
||||||
StorageService.to.isLoggedIn &&
|
StorageService.to.isLoggedIn &&
|
||||||
|
StorageService.to.loginChannel == LoginChannel.driver &&
|
||||||
!StorageService.to.hasVehicleInfo) {
|
!StorageService.to.hasVehicleInfo) {
|
||||||
Future.delayed(const Duration(milliseconds: 500), () {
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
DialogX.to.showConfirmDialog(
|
DialogX.to.showConfirmDialog(
|
||||||
@@ -773,6 +788,8 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
if (_debounce != null) {
|
if (_debounce != null) {
|
||||||
_debounce?.cancel();
|
_debounce?.cancel();
|
||||||
}
|
}
|
||||||
|
_sheetWorker?.dispose();
|
||||||
|
stopAutoRefresh();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:getx_scaffold/getx_scaffold.dart';
|
import 'package:getx_scaffold/getx_scaffold.dart';
|
||||||
import 'package:ln_jq_app/common/model/station_model.dart';
|
import 'package:ln_jq_app/common/model/station_model.dart';
|
||||||
import 'package:ln_jq_app/pages/qr_code/view.dart';
|
|
||||||
import 'package:ln_jq_app/storage_service.dart';
|
import 'package:ln_jq_app/storage_service.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
import 'reservation_list_bottomsheet.dart';
|
|
||||||
|
|
||||||
///加氢预约
|
///加氢预约
|
||||||
class ReservationPage extends GetView<C_ReservationController> {
|
class ReservationPage extends GetView<C_ReservationController> {
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ class ReservationEditController extends GetxController with BaseControllerMixin
|
|||||||
|
|
||||||
TimeSlot tempSlot = availableSlots[initialItem];
|
TimeSlot tempSlot = availableSlots[initialItem];
|
||||||
|
|
||||||
|
|
||||||
Get.bottomSheet(
|
Get.bottomSheet(
|
||||||
Container(
|
Container(
|
||||||
height: 300,
|
height: 300,
|
||||||
@@ -228,6 +227,7 @@ class ReservationEditController extends GetxController with BaseControllerMixin
|
|||||||
'appointment/orderAddHyd/saveOrUpdate',
|
'appointment/orderAddHyd/saveOrUpdate',
|
||||||
data: {
|
data: {
|
||||||
'id': reservation.id,
|
'id': reservation.id,
|
||||||
|
'stationId': reservation.stationId,
|
||||||
'startTime': startTimeStr,
|
'startTime': startTimeStr,
|
||||||
'endTime': endTimeStr,
|
'endTime': endTimeStr,
|
||||||
'hydAmount': amountStr,
|
'hydAmount': amountStr,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:getx_scaffold/getx_scaffold.dart';
|
|||||||
import 'package:ln_jq_app/common/styles/theme.dart';
|
import 'package:ln_jq_app/common/styles/theme.dart';
|
||||||
import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart';
|
import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart';
|
||||||
import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart';
|
import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart';
|
||||||
|
import 'package:ln_jq_app/pages/c_page/message/view.dart';
|
||||||
import 'package:ln_jq_app/pages/login/view.dart';
|
import 'package:ln_jq_app/pages/login/view.dart';
|
||||||
|
|
||||||
import '../../storage_service.dart';
|
import '../../storage_service.dart';
|
||||||
@@ -156,6 +157,7 @@ class HomeController extends GetxController with BaseControllerMixin {
|
|||||||
|
|
||||||
Future<void> _onNotificationOpened(Map<dynamic, dynamic> message) async {
|
Future<void> _onNotificationOpened(Map<dynamic, dynamic> message) async {
|
||||||
Logger.d('onNotificationOpened ====> $message');
|
Logger.d('onNotificationOpened ====> $message');
|
||||||
|
await Get.to(() => const MessagePage());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onNotificationRemoved(Map<dynamic, dynamic> message) async {
|
Future<void> _onNotificationRemoved(Map<dynamic, dynamic> message) async {
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
|||||||
addAlias(phone);
|
addAlias(phone);
|
||||||
|
|
||||||
//登录后查询已绑定车辆信息
|
//登录后查询已绑定车辆信息
|
||||||
|
try {
|
||||||
var carInfo = await HttpService.to.get(
|
var carInfo = await HttpService.to.get(
|
||||||
"appointment/driver/getTruckInfoByDriver?phone=$phone",
|
"appointment/driver/getTruckInfoByDriver?phone=$phone",
|
||||||
);
|
);
|
||||||
@@ -221,6 +222,9 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
|||||||
await StorageService.to.saveVehicleInfo(vehicle);
|
await StorageService.to.saveVehicleInfo(vehicle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Logger.d("暂时不处理 查询车辆信息失败的情况");
|
||||||
|
}
|
||||||
|
|
||||||
//页面操作
|
//页面操作
|
||||||
dismissLoading();
|
dismissLoading();
|
||||||
@@ -400,7 +404,8 @@ class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMix
|
|||||||
final _aliyunPush = AliyunPushFlutter();
|
final _aliyunPush = AliyunPushFlutter();
|
||||||
|
|
||||||
void addAlias(String alias) async {
|
void addAlias(String alias) async {
|
||||||
var result = await _aliyunPush.addAlias(alias);
|
var result = await _aliyunPush.bindAccount(alias);
|
||||||
|
|
||||||
var code = result['code'];
|
var code = result['code'];
|
||||||
if (code == kAliyunPushSuccessCode) {
|
if (code == kAliyunPushSuccessCode) {
|
||||||
Logger.d('添加别名$alias成功');
|
Logger.d('添加别名$alias成功');
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class StorageService extends GetxService {
|
|||||||
|
|
||||||
void delAlias() async {
|
void delAlias() async {
|
||||||
String phoen = StorageService.to.phone ?? "";
|
String phoen = StorageService.to.phone ?? "";
|
||||||
var result = await _aliyunPush.removeAlias(phoen);
|
var result = await await _aliyunPush.unbindAccount();
|
||||||
var code = result['code'];
|
var code = result['code'];
|
||||||
if (code == kAliyunPushSuccessCode) {
|
if (code == kAliyunPushSuccessCode) {
|
||||||
Logger.d('删除别名$phoen成功');
|
Logger.d('删除别名$phoen成功');
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.2.1+4
|
version: 1.2.2+5
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.0
|
sdk: ^3.9.0
|
||||||
|
|||||||