feat:硬件核销相关
This commit is contained in:
1 parent
aea52e482e
commit
5cf2b74158
16 files changed
+562
-28
No files matched your search
@@ -2,3 +2,9 @@
|
||||
```
|
||||
flutter pub run build_runner build --delete-conflicting-outputs~
|
||||
```
|
||||
## flutter打包
|
||||
```
|
||||
flutter build apk --build-name 1.1.0 --build-number 110
|
||||
--build-name为版本号(展示)
|
||||
--build-number为版本号(内部比较)
|
||||
```
|
||||
@@ -1,6 +1,7 @@
|
||||
library;
|
||||
|
||||
export 'product_api.dart';
|
||||
export './product_api.dart';
|
||||
export './hard_api.dart';
|
||||
export './user_api.dart';
|
||||
export './wallet_api.dart';
|
||||
export './app_api.dart';
|
||||
@@ -75,4 +75,14 @@ abstract class WalletApi {
|
||||
?.map<ServiceWallet>((e) => ServiceWallet.fromJson(e))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// 获取通用活动详情
|
||||
static Future<ServiceComAct?> getComAct(dynamic pa) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/wallet/act/com/ad/get-act",
|
||||
queryParameters: pa,
|
||||
);
|
||||
if (res.data == null) return null;
|
||||
return ServiceComAct.fromJson(res.data);
|
||||
}
|
||||
}
|
||||
@@ -134,3 +134,39 @@ class ServiceWallet {
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceWalletToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ServiceComAct {
|
||||
/// 活动类型
|
||||
@JsonKey(
|
||||
fromJson: JsonTool.stringToWalletActType,
|
||||
toJson: JsonTool.walletActTypeToString,
|
||||
)
|
||||
WalletActType? actType;
|
||||
|
||||
/// 活动id
|
||||
String? actItemId;
|
||||
|
||||
/// 用户id
|
||||
String? userId;
|
||||
|
||||
/// 用户名
|
||||
String? username;
|
||||
|
||||
/// 用户头像
|
||||
String? userAvatar;
|
||||
|
||||
/// 详情
|
||||
Map<String, dynamic>? detail;
|
||||
|
||||
ServiceComAct({
|
||||
required this.actType,
|
||||
required this.actItemId,
|
||||
required this.detail,
|
||||
});
|
||||
|
||||
factory ServiceComAct.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServiceComActFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceComActToJson(this);
|
||||
}
|
||||
@@ -80,3 +80,23 @@ Map<String, dynamic> _$ServiceWalletToJson(ServiceWallet instance) =>
|
||||
'cardNumber': instance.cardNumber,
|
||||
'isFreeze': JsonTool.booleanToString(instance.isFreeze),
|
||||
};
|
||||
|
||||
ServiceComAct _$ServiceComActFromJson(Map<String, dynamic> json) =>
|
||||
ServiceComAct(
|
||||
actType: JsonTool.stringToWalletActType(json['actType'] as String?),
|
||||
actItemId: json['actItemId'] as String?,
|
||||
detail: json['detail'] as Map<String, dynamic>?,
|
||||
)
|
||||
..userId = json['userId'] as String?
|
||||
..username = json['username'] as String?
|
||||
..userAvatar = json['userAvatar'] as String?;
|
||||
|
||||
Map<String, dynamic> _$ServiceComActToJson(ServiceComAct instance) =>
|
||||
<String, dynamic>{
|
||||
'actType': JsonTool.walletActTypeToString(instance.actType),
|
||||
'actItemId': instance.actItemId,
|
||||
'userId': instance.userId,
|
||||
'username': instance.username,
|
||||
'userAvatar': instance.userAvatar,
|
||||
'detail': instance.detail,
|
||||
};
|
||||
@@ -50,6 +50,7 @@ enum OrderPayType implements BaseEnum {
|
||||
ZYY("12", "中医院"),
|
||||
RMYY("13", "人民医院"),
|
||||
CSXFK("13", "超市消费卡"),
|
||||
ACT_CANCEL("50", "活动核销"),
|
||||
;
|
||||
|
||||
@override
|
||||
|
||||
@@ -9,10 +9,12 @@ export './api/wallet_api_models.dart';
|
||||
|
||||
export './base/base_models.dart';
|
||||
|
||||
export './page/app_version_enum_models.dart';
|
||||
export './page/order_page_enum_models.dart';
|
||||
export './page/order_page_models.dart';
|
||||
export './page/panel_page_models.dart';
|
||||
export './page/setting_page_enum_models.dart';
|
||||
export './page/wallet_page_enum_models.dart';
|
||||
|
||||
export './mq/mq_enum_models.dart';
|
||||
export './mq/mq_models.dart';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'package:pj_supermarket_cloud/common/models/base/base_models.dart';
|
||||
|
||||
enum AppPlatformEnum implements BaseEnum {
|
||||
android("1", "安卓"),
|
||||
ios("2", "苹果"),
|
||||
;
|
||||
|
||||
@override
|
||||
final String code;
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const AppPlatformEnum(this.code, this.title);
|
||||
}
|
||||
|
||||
enum AppVersionStatusEnum implements BaseEnum {
|
||||
published("1", "已发布"),
|
||||
unpublished("2", "未发布"),
|
||||
offShelf("3", "已下架"),
|
||||
;
|
||||
|
||||
@override
|
||||
final String code;
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const AppVersionStatusEnum(this.code, this.title);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
enum WalletActType implements BaseEnum {
|
||||
cancelAct("1", "核销活动"),
|
||||
couponAct("2", "优惠券活动"),
|
||||
;
|
||||
|
||||
@override
|
||||
final String code;
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const WalletActType(this.code, this.title);
|
||||
}
|
||||
@@ -93,4 +93,5 @@ const _$OrderPayTypeEnumMap = {
|
||||
OrderPayType.ZYY: 'ZYY',
|
||||
OrderPayType.RMYY: 'RMYY',
|
||||
OrderPayType.CSXFK: 'CSXFK',
|
||||
OrderPayType.ACT_CANCEL: 'ACT_CANCEL',
|
||||
};
|
||||
@@ -47,4 +47,13 @@ abstract class JsonTool {
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
static WalletActType? stringToWalletActType(String? value) {
|
||||
return WalletActType.values.fromCode(value);
|
||||
}
|
||||
|
||||
static String? walletActTypeToString(WalletActType? value) {
|
||||
if (value == null) return null;
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,7 @@ class Constants {
|
||||
|
||||
/// 数据库名字
|
||||
static const databaseName = 'cash_register.db';
|
||||
|
||||
/// 设备唯一编码
|
||||
static const deviceUniqueCode = 'EjFJx0WQ';
|
||||
}
|
||||
@@ -1,7 +1,17 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:external_path/external_path.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio/io.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
@@ -14,7 +24,18 @@ class VersionManageController extends GetxController {
|
||||
|
||||
RxInt totalPage = RxInt(0);
|
||||
|
||||
RxInt pageSize = RxInt(15);
|
||||
RxInt pageSize = RxInt(3);
|
||||
|
||||
RxList<ServiceAppVersion> versionList = RxList();
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await getVersionList();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {}
|
||||
|
||||
/// 搜索
|
||||
Future<void> doPage({int? page}) async {
|
||||
@@ -30,7 +51,18 @@ class VersionManageController extends GetxController {
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
}
|
||||
try {} finally {
|
||||
try {
|
||||
final params = {
|
||||
"appUniqueCode": Constants.deviceUniqueCode,
|
||||
};
|
||||
final data = await AppApi.openCardList(params);
|
||||
logger.d("|$_tag|获取版本列表成功:${json.encode(data)}");
|
||||
if (data == null || ObjectUtil.isEmptyList(data.records)) {
|
||||
return;
|
||||
}
|
||||
versionList.value = data.records!;
|
||||
totalPage.value = data.total;
|
||||
} finally {
|
||||
if (isLoading) {
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
EasyLoading.dismiss();
|
||||
@@ -38,6 +70,121 @@ class VersionManageController extends GetxController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 远程下载apk
|
||||
Future<void> doDownload(String url) async {
|
||||
if (url.isEmpty) return;
|
||||
String downUrl = url;
|
||||
if (!url.startsWith("http") && !url.startsWith("https")) {
|
||||
downUrl = "${Constants.ossUrl}/api/admin/sys-file/oss/file?fileName=$url";
|
||||
}
|
||||
logger.d("|$_tag|远程下载apk,url:$downUrl");
|
||||
try {
|
||||
EasyLoading.show(
|
||||
status: '下载中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
if (Platform.isAndroid) {
|
||||
var hasStorage = await Permission.storage.request().isGranted;
|
||||
if (!hasStorage) {
|
||||
EasyLoading.showError("存储权限未授权,无法下载");
|
||||
return;
|
||||
}
|
||||
if (await Permission.manageExternalStorage.isDenied) {
|
||||
final g = await Permission.manageExternalStorage.request();
|
||||
hasStorage = hasStorage || g.isGranted;
|
||||
}
|
||||
const channel =
|
||||
MethodChannel('com.example.pj_supermarket_cloud/system_download');
|
||||
final user = await AppSettingTool.getUserSetting();
|
||||
final headers = <String, String>{};
|
||||
if (ObjectUtil.isNotEmpty(user.accessToken)) {
|
||||
headers['Authorization'] = "Bearer ${user.accessToken}";
|
||||
}
|
||||
headers['TENANT-ID'] = "${user.tenantId ?? 1}";
|
||||
headers['CLIENT-TOC'] = "Y";
|
||||
headers['Accept'] = "*/*";
|
||||
headers['User-Agent'] = "Mozilla/5.0 (Android) DownloadManager";
|
||||
final ext = AppFileTool.getFileExtension(downUrl);
|
||||
final useExt = ObjectUtil.isEmpty(ext) ? ".apk" : ext;
|
||||
final fileName = "pj_${DateTime.now().millisecondsSinceEpoch}$useExt";
|
||||
final mimeType = useExt == ".apk"
|
||||
? "application/vnd.android.package-archive"
|
||||
: "application/octet-stream";
|
||||
final res = await channel.invokeMethod<int>('download', {
|
||||
'url': downUrl,
|
||||
'fileName': fileName,
|
||||
'mimeType': mimeType,
|
||||
'headers': headers,
|
||||
});
|
||||
logger.i("|$_tag|系统下载任务创建:${res ?? -1}");
|
||||
try {
|
||||
final info = await channel.invokeMethod<Map<dynamic, dynamic>>(
|
||||
'query',
|
||||
{'id': res},
|
||||
);
|
||||
logger.i("|$_tag|系统下载状态:${info?['status']},原因:${info?['reason']}");
|
||||
final st = info?['status'] as int?;
|
||||
if (st == 1 || st == 4) {
|
||||
final downloadsDir =
|
||||
await ExternalPath.getExternalStoragePublicDirectory(
|
||||
"Downloads");
|
||||
final savePath = "$downloadsDir/$fileName";
|
||||
final dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(minutes: 5),
|
||||
));
|
||||
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||
createHttpClient: () {
|
||||
final client = HttpClient(
|
||||
context: SecurityContext(withTrustedRoots: false),
|
||||
);
|
||||
client.badCertificateCallback = (cert, host, port) => true;
|
||||
return client;
|
||||
},
|
||||
);
|
||||
await dio.download(
|
||||
downUrl,
|
||||
savePath,
|
||||
options: Options(headers: headers),
|
||||
);
|
||||
logger.i("|$_tag|直连下载成功:$savePath");
|
||||
}
|
||||
} catch (e) {
|
||||
final downloadsDir =
|
||||
await ExternalPath.getExternalStoragePublicDirectory("Downloads");
|
||||
final savePath = "$downloadsDir/$fileName";
|
||||
final dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(minutes: 5),
|
||||
));
|
||||
dio.httpClientAdapter = IOHttpClientAdapter(
|
||||
createHttpClient: () {
|
||||
final client = HttpClient(
|
||||
context: SecurityContext(withTrustedRoots: false),
|
||||
);
|
||||
client.badCertificateCallback = (cert, host, port) => true;
|
||||
return client;
|
||||
},
|
||||
);
|
||||
await dio.download(
|
||||
downUrl,
|
||||
savePath,
|
||||
options: Options(headers: headers),
|
||||
);
|
||||
logger.i("|$_tag|系统查询失败降级直连成功:$savePath;error:$e");
|
||||
}
|
||||
EasyLoading.showSuccess("已添加到系统下载");
|
||||
} else {
|
||||
EasyLoading.showInfo("当前平台不支持系统下载");
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e("|$_tag|远程下载apk,下载失败:$e");
|
||||
EasyLoading.showError("下载失败");
|
||||
} finally {
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget settingVersionSetting(BuildContext context) {
|
||||
@@ -61,15 +208,238 @@ Widget settingVersionSetting(BuildContext context) {
|
||||
|
||||
// 版本更新搜索区域
|
||||
Widget buildSettingVersionSettingSearch(BuildContext context) {
|
||||
return Container();
|
||||
final versionC = Get.find<VersionManageController>();
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
const Spacer(),
|
||||
FButton(
|
||||
prefix: FIcon(
|
||||
FAssets.icons.search,
|
||||
size: theme.typography.base.fontSize,
|
||||
),
|
||||
label: Text(
|
||||
'搜索',
|
||||
style: theme.typography.base.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () => versionC.doPage(),
|
||||
),
|
||||
].toRow();
|
||||
}
|
||||
|
||||
// 版本更新列表区域
|
||||
Widget buildSettingVersionSettingList(BuildContext context) {
|
||||
return Container();
|
||||
final versionC = Get.find<VersionManageController>();
|
||||
return Obx(() {
|
||||
if (versionC.versionList.isEmpty) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.info_outline, size: 48, color: Colors.grey),
|
||||
const SizedBox(height: 10),
|
||||
Text("暂无版本信息", style: TextStyle(color: Colors.grey[600])),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return GridView.builder(
|
||||
padding: const EdgeInsets.all(10),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 1,
|
||||
crossAxisSpacing: 10,
|
||||
mainAxisSpacing: 10,
|
||||
childAspectRatio: 6,
|
||||
),
|
||||
itemCount: versionC.versionList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = versionC.versionList[index];
|
||||
return buildSettingVersionSettingCardCopy(context, item);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildSettingVersionSettingCardCopy(
|
||||
BuildContext context,
|
||||
ServiceAppVersion item,
|
||||
) {
|
||||
final versionC = Get.find<VersionManageController>();
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
<Widget>[
|
||||
Text(
|
||||
"${AppPlatformEnum.values.fromCode(item.platform ?? '')?.title ?? '未知平台'} - ${item.versionName ?? '未知版本'}",
|
||||
style: theme.typography.lg.copyWith(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(width: 20.w),
|
||||
FBadge(
|
||||
label: Text(
|
||||
AppVersionStatusEnum.values.fromCode(item.status ?? '')?.title ??
|
||||
'未知状态',
|
||||
style: theme.typography.sm.copyWith(height: 1, color: Colors.white),
|
||||
).padding(),
|
||||
),
|
||||
].toRow(),
|
||||
SizedBox(height: 10.w),
|
||||
Text(
|
||||
"更新内容",
|
||||
style: theme.typography.base.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 10.w),
|
||||
Text(
|
||||
item.updateContent ?? '暂无更新内容',
|
||||
style: theme.typography.base.copyWith(color: Colors.grey),
|
||||
),
|
||||
SizedBox(height: 10.w),
|
||||
<Widget>[
|
||||
FIcon(
|
||||
FAssets.icons.sendHorizontal,
|
||||
size: theme.typography.base.fontSize,
|
||||
),
|
||||
SizedBox(width: 10.w),
|
||||
Text(
|
||||
item.downloadUrl ?? '未知下载地址',
|
||||
style: theme.typography.sm.copyWith(color: Colors.grey),
|
||||
),
|
||||
const Spacer(),
|
||||
FIcon(
|
||||
FAssets.icons.arrowDownToLine,
|
||||
size: theme.typography.base.fontSize,
|
||||
),
|
||||
]
|
||||
.toRow()
|
||||
.padding(horizontal: 20.w, vertical: 15.w)
|
||||
.decorated(
|
||||
color: theme.colorScheme.secondary,
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: theme.style.borderRadius,
|
||||
)
|
||||
.onTap(() => versionC.doDownload(item.downloadUrl ?? '')),
|
||||
]
|
||||
.toColumn(crossAxisAlignment: CrossAxisAlignment.start)
|
||||
.padding(horizontal: 20.w, vertical: 15.w)
|
||||
.decorated(
|
||||
color: theme.colorScheme.muted,
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: theme.style.borderRadius,
|
||||
);
|
||||
}
|
||||
|
||||
// 版本管理卡片
|
||||
Widget buildSettingVersionSettingCard(BuildContext context) {
|
||||
return Container();
|
||||
Widget buildSettingVersionSettingCard(
|
||||
BuildContext context,
|
||||
ServiceAppVersion item,
|
||||
) {
|
||||
final theme = FTheme.of(context);
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"${item.platform ?? '未知平台'} - ${item.versionName ?? '未知版本'}",
|
||||
style:
|
||||
theme.typography.lg.copyWith(fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: item.status == '已发布'
|
||||
? Colors.green.withOpacity(0.1)
|
||||
: Colors.grey.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
item.status ?? '未知状态',
|
||||
style: theme.typography.sm.copyWith(
|
||||
color: item.status == '已发布' ? Colors.green : Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Text("Build: ${item.versionCode ?? '-'}",
|
||||
style: theme.typography.base.copyWith(color: Colors.grey)),
|
||||
const SizedBox(width: 10),
|
||||
if (item.isForce == true) _buildTag(context, "强制更新", Colors.red),
|
||||
if (item.isSilent == true)
|
||||
_buildTag(context, "静默更新", Colors.orange),
|
||||
],
|
||||
),
|
||||
const Divider(height: 20),
|
||||
Text("更新内容:",
|
||||
style: theme.typography.base.copyWith(fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
item.updateContent ?? '暂无更新内容',
|
||||
style: theme.typography.base.copyWith(color: Colors.grey[800]),
|
||||
),
|
||||
if (item.downloadUrl != null && item.downloadUrl!.isNotEmpty) ...[
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.link, size: 16, color: Colors.blue),
|
||||
const SizedBox(width: 5),
|
||||
Expanded(
|
||||
child: Text(
|
||||
item.downloadUrl!,
|
||||
style: theme.typography.sm.copyWith(color: Colors.blue),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTag(BuildContext context, String text, Color color) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: color),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(text, style: TextStyle(color: color, fontSize: 10)),
|
||||
);
|
||||
}
|
||||
@@ -49,6 +49,7 @@ class TakeFoodController extends GetxController {
|
||||
doCancelPay() {
|
||||
orderId = null;
|
||||
globalQrCode = null;
|
||||
orderPayType = OrderPayType.RESERVE_QR_CODE;
|
||||
payUser.value = ServiceUser();
|
||||
payUser.refresh();
|
||||
carList.value = [];
|
||||
@@ -100,13 +101,36 @@ class TakeFoodController extends GetxController {
|
||||
BarcodeScanManage.instance.qrcodeScanStream.listen((event) async {
|
||||
final serviceCode = await BarcodeScanManage.instance.getCodeInfo(event);
|
||||
if (serviceCode == null) return;
|
||||
if (serviceCode.payType != OrderPayType.RESERVE_QR_CODE) {
|
||||
await TtsManage.speak("请出示线上订餐二维码");
|
||||
return;
|
||||
if (serviceCode.payType == OrderPayType.RESERVE_QR_CODE) {
|
||||
orderPayType = OrderPayType.RESERVE_QR_CODE;
|
||||
globalQrCode = serviceCode;
|
||||
orderId = serviceCode.id;
|
||||
await getOrderDetail();
|
||||
} else if (serviceCode.payType == OrderPayType.ACT_CANCEL) {
|
||||
orderPayType = OrderPayType.ACT_CANCEL;
|
||||
// 查询核销活动
|
||||
final act = await WalletApi.getComAct({
|
||||
"actItemId": serviceCode.id,
|
||||
"userId": serviceCode.userId,
|
||||
});
|
||||
if (act == null) {
|
||||
await TtsManage.speak("核销活动不存在");
|
||||
return;
|
||||
}
|
||||
// 更新用户
|
||||
payUser.value?.username = act.username;
|
||||
payUser.value?.userId = act.userId;
|
||||
payUser.value?.userAvatar = act.userAvatar;
|
||||
payUser.refresh();
|
||||
// 生成简单购物车
|
||||
carList.value = [
|
||||
ServiceCar(productName: "生日活动核销", productPrice: 0, productCount: 1)
|
||||
];
|
||||
senSubScreen();
|
||||
} else {
|
||||
await TtsManage.speak("无效的二维码");
|
||||
}
|
||||
globalQrCode = serviceCode;
|
||||
orderId = serviceCode.id;
|
||||
await getOrderDetail();
|
||||
return;
|
||||
});
|
||||
} catch (e) {
|
||||
doCancelPay();
|
||||
@@ -123,26 +147,35 @@ class TakeFoodController extends GetxController {
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
final serviceId = appSetting.serviceId;
|
||||
if (ObjectUtil.isEmpty(serviceId)) {
|
||||
Toast.error(msg: "订单不存在");
|
||||
Toast.error(msg: "请前往设置绑定设备");
|
||||
return;
|
||||
}
|
||||
final pa = {
|
||||
"orderId": orderId,
|
||||
"hardwareId": serviceId,
|
||||
};
|
||||
EasyLoading.show(
|
||||
status: '核销中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
disposeOrderQrCodeCancel(serviceId!);
|
||||
}
|
||||
|
||||
Future<void> disposeOrderQrCodeCancel(String serviceId) async {
|
||||
try {
|
||||
EasyLoading.show(
|
||||
status: '核销中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
final flag = await HardApi.cancelQrCode(pa);
|
||||
if (flag == false) throw Error();
|
||||
// 线上订餐二维码支付
|
||||
if (orderPayType == OrderPayType.RESERVE_QR_CODE) {
|
||||
final pa = {
|
||||
"orderId": orderId,
|
||||
"hardwareId": serviceId,
|
||||
};
|
||||
final flag = await HardApi.cancelQrCode(pa);
|
||||
if (flag == false) throw Error();
|
||||
}
|
||||
// 活动核销
|
||||
if (orderPayType == OrderPayType.ACT_CANCEL) {}
|
||||
EasyLoading.dismiss();
|
||||
Toast.success(msg: "核销成功");
|
||||
TtsManage.speak("核销成功");
|
||||
doCancelPay();
|
||||
} catch (e, stack) {
|
||||
logger.e("获取订单详情错误error:|$e|stack:|$stack|");
|
||||
logger.e("核销订单orderType:|${orderPayType.title}|error:|$e|stack:|$stack|");
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class TakeFoodPage extends GetView<TakeFoodController> {
|
||||
dataRowHeight: hdHeight,
|
||||
columns: [
|
||||
DataColumn2(
|
||||
label: Text("菜品名称", textAlign: TextAlign.center),
|
||||
label: Text("物品名称", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
name: pj_supermarket_cloud
|
||||
description: "A new Flutter project."
|
||||
description: "智慧后勤-测试"
|
||||
publish_to: 'none'
|
||||
version: 1.0.0+1
|
||||
version: 1.1.1+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.6.0
|
||||
|
||||
Reference in new issue
Block a user