加氢站-查看证件
This commit is contained in:
BIN
ln_jq_app/assets/images/ic_close@2x.png
Normal file
BIN
ln_jq_app/assets/images/ic_close@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 892 B |
@@ -1,11 +1,18 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
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:image_gallery_saver/image_gallery_saver.dart';
|
||||||
|
import 'package:ln_jq_app/common/login_util.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/styles/theme.dart';
|
import 'package:ln_jq_app/common/styles/theme.dart';
|
||||||
import 'package:ln_jq_app/storage_service.dart';
|
import 'package:ln_jq_app/storage_service.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
import 'package:photo_view/photo_view_gallery.dart';
|
||||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
|
|
||||||
enum ReservationStatus {
|
enum ReservationStatus {
|
||||||
@@ -46,6 +53,8 @@ class ReservationModel {
|
|||||||
final int isTruckAttachment; // 1为有证件数据 0为缺少
|
final int isTruckAttachment; // 1为有证件数据 0为缺少
|
||||||
final bool hasDrivingAttachment; // 是否有行驶证
|
final bool hasDrivingAttachment; // 是否有行驶证
|
||||||
final bool hasHydrogenationAttachment; // 是否有加氢证
|
final bool hasHydrogenationAttachment; // 是否有加氢证
|
||||||
|
final List<String> drivingAttachments; // 行驶证图片列表
|
||||||
|
final List<String> hydrogenationAttachments; // 加氢证图片列表
|
||||||
|
|
||||||
ReservationModel({
|
ReservationModel({
|
||||||
required this.id,
|
required this.id,
|
||||||
@@ -73,6 +82,8 @@ class ReservationModel {
|
|||||||
required this.hasDrivingAttachment,
|
required this.hasDrivingAttachment,
|
||||||
required this.hasHydrogenationAttachment,
|
required this.hasHydrogenationAttachment,
|
||||||
required this.isEdit,
|
required this.isEdit,
|
||||||
|
required this.drivingAttachments,
|
||||||
|
required this.hydrogenationAttachments,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// 工厂构造函数,用于从JSON创建ReservationModel实例
|
/// 工厂构造函数,用于从JSON创建ReservationModel实例
|
||||||
@@ -146,6 +157,8 @@ class ReservationModel {
|
|||||||
hasDrivingAttachment: drivingList.isNotEmpty,
|
hasDrivingAttachment: drivingList.isNotEmpty,
|
||||||
hasHydrogenationAttachment: hydrogenationList.isNotEmpty,
|
hasHydrogenationAttachment: hydrogenationList.isNotEmpty,
|
||||||
isEdit: json['isEdit']?.toString() ?? '0',
|
isEdit: json['isEdit']?.toString() ?? '0',
|
||||||
|
drivingAttachments: drivingList.map((e) => e.toString()).toList(),
|
||||||
|
hydrogenationAttachments: hydrogenationList.map((e) => e.toString()).toList(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,6 +361,8 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
hasDrivingAttachment: false,
|
hasDrivingAttachment: false,
|
||||||
hasHydrogenationAttachment: false,
|
hasHydrogenationAttachment: false,
|
||||||
isEdit: "0",
|
isEdit: "0",
|
||||||
|
drivingAttachments: [],
|
||||||
|
hydrogenationAttachments: [],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
item = reservationList.firstWhere(
|
item = reservationList.firstWhere(
|
||||||
@@ -416,13 +431,13 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
),
|
),
|
||||||
SizedBox(width: 16.w),
|
SizedBox(width: 16.w),
|
||||||
if (item.plateNumber != "---" && item.hasDrivingAttachment)
|
if (item.plateNumber != "---" && item.hasDrivingAttachment)
|
||||||
_buildInfoTag('行驶证'),
|
buildInfoTag('行驶证', item.drivingAttachments),
|
||||||
if (item.plateNumber != "---" && item.hasHydrogenationAttachment)
|
if (item.plateNumber != "---" && item.hasHydrogenationAttachment)
|
||||||
_buildInfoTag('加氢证'),
|
buildInfoTag('加氢证', item.hydrogenationAttachments),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 6.h),
|
SizedBox(height: 6.h),
|
||||||
|
|
||||||
// 提示逻辑
|
// 提示逻辑
|
||||||
if (isEdit)
|
if (isEdit)
|
||||||
@@ -458,7 +473,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 6.h),
|
SizedBox(height: 6.h),
|
||||||
|
|
||||||
// 预定加氢量输入区
|
// 预定加氢量输入区
|
||||||
Container(
|
Container(
|
||||||
@@ -590,7 +605,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
1,
|
1,
|
||||||
addHydAmount,
|
addHydAmount,
|
||||||
"",
|
"",
|
||||||
item,
|
item!,
|
||||||
gunNumber: selectedGun.value,
|
gunNumber: selectedGun.value,
|
||||||
plateNumber: item.plateNumber,
|
plateNumber: item.plateNumber,
|
||||||
isEdit: true,
|
isEdit: true,
|
||||||
@@ -600,7 +615,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
}
|
}
|
||||||
//订单确认
|
//订单确认
|
||||||
if (!isEdit &&
|
if (!isEdit &&
|
||||||
(item.plateNumber == "---" ||
|
(item!.plateNumber == "---" ||
|
||||||
item.isTruckAttachment == 0) &&
|
item.isTruckAttachment == 0) &&
|
||||||
!isOfflineChecked.value) {
|
!isOfflineChecked.value) {
|
||||||
showToast("车辆未上传加氢证 , 请确保线下登记后点击确认");
|
showToast("车辆未上传加氢证 , 请确保线下登记后点击确认");
|
||||||
@@ -663,14 +678,14 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
if (!isEdit) {
|
if (!isEdit && !isAdd) {
|
||||||
upDataService(
|
upDataService(
|
||||||
id,
|
id,
|
||||||
0,
|
0,
|
||||||
2,
|
2,
|
||||||
0,
|
0,
|
||||||
"",
|
"",
|
||||||
item,
|
item!,
|
||||||
gunNumber: selectedGun.value,
|
gunNumber: selectedGun.value,
|
||||||
plateNumber: item.plateNumber,
|
plateNumber: item.plateNumber,
|
||||||
);
|
);
|
||||||
@@ -684,7 +699,7 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
isEdit ? '取消' : '未加氢',
|
isEdit || isAdd ? '取消' : '未加氢',
|
||||||
style: const TextStyle(color: Colors.grey, fontSize: 16),
|
style: const TextStyle(color: Colors.grey, fontSize: 16),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -725,17 +740,170 @@ class SiteController extends GetxController with BaseControllerMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoTag(String label) {
|
/// 保存图片到相册
|
||||||
return Container(
|
Future<void> saveImageToLocal(String url) async {
|
||||||
margin: const EdgeInsets.only(left: 4),
|
try {
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
// 1. 权限请求
|
||||||
decoration: BoxDecoration(
|
if (Platform.isAndroid) {
|
||||||
color: const Color(0xFFF2F3F5),
|
var status = await Permission.storage.request();
|
||||||
borderRadius: BorderRadius.circular(4),
|
if (!status.isGranted) {
|
||||||
|
showErrorToast("请在系统设置中开启存储权限");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var status = await Permission.photos.request();
|
||||||
|
if (!status.isGranted) {
|
||||||
|
showErrorToast("请在系统设置中开启相册权限");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showLoading("正在保存...");
|
||||||
|
|
||||||
|
// 2. 下载图片
|
||||||
|
var response = await Dio().get(
|
||||||
|
url,
|
||||||
|
options: Options(responseType: ResponseType.bytes),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 3. 保存到相册
|
||||||
|
final result = await ImageGallerySaver.saveImage(
|
||||||
|
Uint8List.fromList(response.data),
|
||||||
|
quality: 100,
|
||||||
|
name: "certificate_${DateTime.now().millisecondsSinceEpoch}",
|
||||||
|
);
|
||||||
|
|
||||||
|
dismissLoading();
|
||||||
|
|
||||||
|
if (result != null && result['isSuccess'] == true) {
|
||||||
|
showSuccessToast("图片已保存至相册");
|
||||||
|
} else {
|
||||||
|
showErrorToast("保存失败");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
dismissLoading();
|
||||||
|
showErrorToast("保存异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildInfoTag(String label, List<String> images) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showImagePreview(images);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(left: 4),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFF2F3F5),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: TextStyle(color: Color(0xFF999999), fontSize: 11.sp),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
);
|
||||||
label,
|
}
|
||||||
style: TextStyle(color: Color(0xFF999999), fontSize: 11.sp),
|
|
||||||
|
/// 显示图片预览弹窗
|
||||||
|
void showImagePreview(List<String> images) {
|
||||||
|
if (images.isEmpty) return;
|
||||||
|
|
||||||
|
final RxInt currentIndex = 0.obs;
|
||||||
|
final PageController pageController = PageController();
|
||||||
|
|
||||||
|
Get.dialog(
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// 图片翻页
|
||||||
|
SizedBox(
|
||||||
|
height: Get.height * 0.5,
|
||||||
|
child: PhotoViewGallery.builder(
|
||||||
|
scrollPhysics: const BouncingScrollPhysics(),
|
||||||
|
builder: (BuildContext context, int index) {
|
||||||
|
return PhotoViewGalleryPageOptions(
|
||||||
|
imageProvider: NetworkImage(images[index]),
|
||||||
|
initialScale: PhotoViewComputedScale.contained,
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(tag: images[index]),
|
||||||
|
onTapDown: (context, details, controllerValue) {
|
||||||
|
_showSaveImageMenu(images[index]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: images.length,
|
||||||
|
loadingBuilder: (context, event) => const Center(
|
||||||
|
child: CircularProgressIndicator(color: Colors.white),
|
||||||
|
),
|
||||||
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
pageController: pageController,
|
||||||
|
onPageChanged: (index) => currentIndex.value = index,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 10.h),
|
||||||
|
// 页码指示器
|
||||||
|
Center(
|
||||||
|
child: Text(
|
||||||
|
"${currentIndex.value + 1} / ${images.length}",
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
decoration: TextDecoration.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 关闭按钮
|
||||||
|
Positioned(
|
||||||
|
top: 150.h,
|
||||||
|
right: 20,
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.close, color: Colors.white, size: 30),
|
||||||
|
onPressed: () => Get.back(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
useSafeArea: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _showSaveImageMenu(String url) {
|
||||||
|
Get.bottomSheet(
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
child: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.download),
|
||||||
|
title: const Text('保存图片到相册'),
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
saveImageToLocal(url);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(height: 1),
|
||||||
|
ListTile(
|
||||||
|
title: const Text('取消', textAlign: TextAlign.center),
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -550,10 +550,11 @@ class SitePage extends GetView<SiteController> {
|
|||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
if (item.hasDrivingAttachment) _buildInfoTag('行驶证'),
|
if (item.hasDrivingAttachment)
|
||||||
|
controller.buildInfoTag('行驶证',item.drivingAttachments),
|
||||||
if (item.hasHydrogenationAttachment) ...[
|
if (item.hasHydrogenationAttachment) ...[
|
||||||
SizedBox(width: 8.w),
|
SizedBox(width: 8.w),
|
||||||
_buildInfoTag('加氢证'),
|
controller.buildInfoTag('加氢证',item.hydrogenationAttachments)
|
||||||
],
|
],
|
||||||
Spacer(),
|
Spacer(),
|
||||||
if (item.isEdit == "1") ...[
|
if (item.isEdit == "1") ...[
|
||||||
@@ -602,19 +603,7 @@ class SitePage extends GetView<SiteController> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInfoTag(String label) {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color.fromRGBO(242, 243, 245, 1),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: TextStyle(color: Color.fromRGBO(78, 89, 105, 1), fontSize: 11.sp),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildSmallButton(
|
Widget _buildSmallButton(
|
||||||
String text, {
|
String text, {
|
||||||
|
|||||||
@@ -227,6 +227,8 @@ class C_ReservationController extends GetxController with BaseControllerMixin {
|
|||||||
hasHydrogenationAttachment: true,
|
hasHydrogenationAttachment: true,
|
||||||
hasDrivingAttachment: true,
|
hasDrivingAttachment: true,
|
||||||
isEdit: '',
|
isEdit: '',
|
||||||
|
drivingAttachments: [],
|
||||||
|
hydrogenationAttachments: [],
|
||||||
);
|
);
|
||||||
|
|
||||||
//打开预约列表
|
//打开预约列表
|
||||||
|
|||||||
@@ -589,6 +589,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.7.2"
|
version: "4.7.2"
|
||||||
|
image_gallery_saver:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_gallery_saver
|
||||||
|
sha256: "0aba74216a4d9b0561510cb968015d56b701ba1bd94aace26aacdd8ae5761816"
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.3"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ 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.3+6
|
version: 1.2.2+5
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.9.0
|
sdk: ^3.9.0
|
||||||
|
|
||||||
# Dependencies specify other packages that your package needs in order to work.
|
# Dependencies specify other packages tha。。。t your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
||||||
# dependencies can be manually updated by changing the version numbers below to
|
# dependencies can be manually updated by changing the version numbers below to
|
||||||
@@ -53,6 +53,7 @@ dependencies:
|
|||||||
aliyun_push_flutter: ^1.3.6
|
aliyun_push_flutter: ^1.3.6
|
||||||
pull_to_refresh: ^2.0.0
|
pull_to_refresh: ^2.0.0
|
||||||
flutter_app_update: ^3.2.2
|
flutter_app_update: ^3.2.2
|
||||||
|
image_gallery_saver: ^2.0.3
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user