11
This commit is contained in:
1 parent
295b4058be
commit
08bf352984
21 files changed
+1109
-234
No files matched your search
@@ -70,29 +70,25 @@ abstract class HardApi {
|
||||
}
|
||||
|
||||
/// 获取订单详情
|
||||
static Future<ServiceBase> getOrder(dynamic formData) async {
|
||||
final res = await HttpManage().dio.get<ServiceBase>(
|
||||
static Future<ServiceHardOrder?> getOrder(dynamic formData) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/hard/hard-api/ad/get-order",
|
||||
queryParameters: formData,
|
||||
);
|
||||
return res.data as ServiceBase;
|
||||
if (res.data == null) return null;
|
||||
return ServiceHardOrder.fromJson(res.data);
|
||||
}
|
||||
|
||||
/// 获取订单购物车
|
||||
static Future<ServiceListBase<ServiceCar>> getCarByOrderId(
|
||||
static Future<List<ServiceCar>?> getCarByOrderId(
|
||||
dynamic formData,
|
||||
) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/hard/hard-api/ad/get-by-order-id",
|
||||
queryParameters: formData,
|
||||
);
|
||||
if (res.data?.data == null) {
|
||||
return res.data!;
|
||||
}
|
||||
final typeData =
|
||||
res.data?.data?.map<ServiceCar>((e) => ServiceCar.fromJson(e)).toList();
|
||||
res.data?.data = typeData;
|
||||
return res.data!;
|
||||
if (res.data == null) return null;
|
||||
return res.data?.map<ServiceCar>((e) => ServiceCar.fromJson(e)).toList();
|
||||
}
|
||||
|
||||
/// 核销订单
|
||||
|
||||
@@ -44,20 +44,16 @@ abstract class UserApi {
|
||||
}
|
||||
|
||||
/// 获取人脸
|
||||
static Future<ServiceListBase<ServiceAsyncFace>> getFaceList(
|
||||
static Future<List<ServiceAsyncFace>?> getFaceList(
|
||||
dynamic formData,
|
||||
) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/admin/user-face/ad/find-face",
|
||||
queryParameters: formData,
|
||||
);
|
||||
if (res.data?.data == null) {
|
||||
return res.data;
|
||||
}
|
||||
final typeData = res.data?.data
|
||||
if (res.data == null) return null;
|
||||
return res.data
|
||||
?.map<ServiceAsyncFace>((e) => ServiceAsyncFace.fromJson(e))
|
||||
.toList();
|
||||
res.data?.data = typeData;
|
||||
return res.data;
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,15 @@ abstract class WalletApi {
|
||||
}
|
||||
|
||||
/// 开卡列表
|
||||
static Future<ServiceBase?> openCardList(dynamic pa) async {
|
||||
static Future<ServiceOpenCardPage?> openCardList(
|
||||
dynamic pa,
|
||||
) async {
|
||||
final res = await HttpManage().dio.get(
|
||||
"/wallet/wallet-active/ad/open-card-list",
|
||||
queryParameters: pa,
|
||||
);
|
||||
if (res.data == null) return null;
|
||||
return res.data as ServiceBase;
|
||||
return ServiceOpenCardPage.fromJson(res.data);
|
||||
}
|
||||
|
||||
/// 开卡成功
|
||||
|
||||
@@ -21,20 +21,21 @@ class ServiceBase<T> {
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ServiceListBase<T> {
|
||||
String? msg;
|
||||
int? code;
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
List<T>? data;
|
||||
class ServicePageBase {
|
||||
int current;
|
||||
int pages;
|
||||
int size;
|
||||
int total;
|
||||
|
||||
ServiceListBase({
|
||||
this.msg,
|
||||
this.code,
|
||||
this.data,
|
||||
ServicePageBase({
|
||||
this.current = 1,
|
||||
this.pages = 1,
|
||||
this.size = 10,
|
||||
this.total = 0,
|
||||
});
|
||||
|
||||
factory ServiceListBase.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServiceListBaseFromJson(json);
|
||||
factory ServicePageBase.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServicePageBaseFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceListBaseToJson(this);
|
||||
Map<String, dynamic> toJson() => _$ServicePageBaseToJson(this);
|
||||
}
|
||||
@@ -20,14 +20,18 @@ Map<String, dynamic> _$ServiceBaseToJson<T>(ServiceBase<T> instance) =>
|
||||
'data': instance.data,
|
||||
};
|
||||
|
||||
ServiceListBase<T> _$ServiceListBaseFromJson<T>(Map<String, dynamic> json) =>
|
||||
ServiceListBase<T>(
|
||||
msg: json['msg'] as String?,
|
||||
code: (json['code'] as num?)?.toInt(),
|
||||
ServicePageBase _$ServicePageBaseFromJson(Map<String, dynamic> json) =>
|
||||
ServicePageBase(
|
||||
current: (json['current'] as num?)?.toInt() ?? 1,
|
||||
pages: (json['pages'] as num?)?.toInt() ?? 1,
|
||||
size: (json['size'] as num?)?.toInt() ?? 10,
|
||||
total: (json['total'] as num?)?.toInt() ?? 0,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ServiceListBaseToJson<T>(ServiceListBase<T> instance) =>
|
||||
Map<String, dynamic> _$ServicePageBaseToJson(ServicePageBase instance) =>
|
||||
<String, dynamic>{
|
||||
'msg': instance.msg,
|
||||
'code': instance.code,
|
||||
'current': instance.current,
|
||||
'pages': instance.pages,
|
||||
'size': instance.size,
|
||||
'total': instance.total,
|
||||
};
|
||||
@@ -201,3 +201,110 @@ class ServiceQRCode {
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceQRCodeToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ServiceHardOrder {
|
||||
/// 用户名
|
||||
final String? username;
|
||||
|
||||
/// 用户手机号
|
||||
final String? userMobile;
|
||||
|
||||
/// 用户头像
|
||||
final String? userAvatar;
|
||||
|
||||
ServiceHardOrder({
|
||||
this.username,
|
||||
this.userMobile,
|
||||
this.userAvatar,
|
||||
});
|
||||
|
||||
factory ServiceHardOrder.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServiceHardOrderFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceHardOrderToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ServiceOpenCard {
|
||||
/// 用户名
|
||||
String? username;
|
||||
|
||||
/// 用户手机号
|
||||
String? mobile;
|
||||
|
||||
/// 用户头像
|
||||
String? avatar;
|
||||
|
||||
/// 饭卡状态
|
||||
String? cardStatus;
|
||||
|
||||
/// 编号
|
||||
String? id;
|
||||
|
||||
/// 部门名
|
||||
String? deptId;
|
||||
|
||||
/// 部门名
|
||||
String? deptName;
|
||||
|
||||
/// 用户编号
|
||||
String? userId;
|
||||
|
||||
/// 饭卡类型Id
|
||||
String? walletTypeId;
|
||||
|
||||
/// 饭卡类型
|
||||
String? walletTypeUniqueCode;
|
||||
|
||||
/// 饭卡图标
|
||||
String? walletTypeIcon;
|
||||
|
||||
/// 用户卡号
|
||||
String? cardNumber;
|
||||
|
||||
/// 钱包编号
|
||||
String? walletId;
|
||||
|
||||
/// 是否激活
|
||||
@JsonKey(fromJson: JsonTool.stringToBoolean, toJson: JsonTool.booleanToString)
|
||||
bool? isActiveHardware;
|
||||
|
||||
ServiceOpenCard({
|
||||
this.username,
|
||||
this.mobile,
|
||||
this.avatar,
|
||||
this.cardStatus,
|
||||
this.id,
|
||||
this.deptId,
|
||||
this.deptName,
|
||||
this.userId,
|
||||
this.walletTypeId,
|
||||
this.walletTypeUniqueCode,
|
||||
this.walletTypeIcon,
|
||||
this.cardNumber,
|
||||
this.walletId,
|
||||
this.isActiveHardware,
|
||||
});
|
||||
|
||||
factory ServiceOpenCard.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServiceOpenCardFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceOpenCardToJson(this);
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
class ServiceOpenCardPage extends ServicePageBase {
|
||||
List<ServiceOpenCard>? records;
|
||||
|
||||
ServiceOpenCardPage({
|
||||
this.records,
|
||||
});
|
||||
|
||||
factory ServiceOpenCardPage.fromJson(Map<String, dynamic> json) =>
|
||||
_$ServiceOpenCardPageFromJson(
|
||||
json,
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ServiceOpenCardPageToJson(this);
|
||||
}
|
||||
@@ -118,3 +118,75 @@ Map<String, dynamic> _$ServiceQRCodeToJson(ServiceQRCode instance) =>
|
||||
'exceedTime': instance.exceedTime,
|
||||
'extra': instance.extra,
|
||||
};
|
||||
|
||||
ServiceHardOrder _$ServiceHardOrderFromJson(Map<String, dynamic> json) =>
|
||||
ServiceHardOrder(
|
||||
username: json['username'] as String?,
|
||||
userMobile: json['userMobile'] as String?,
|
||||
userAvatar: json['userAvatar'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ServiceHardOrderToJson(ServiceHardOrder instance) =>
|
||||
<String, dynamic>{
|
||||
'username': instance.username,
|
||||
'userMobile': instance.userMobile,
|
||||
'userAvatar': instance.userAvatar,
|
||||
};
|
||||
|
||||
ServiceOpenCard _$ServiceOpenCardFromJson(Map<String, dynamic> json) =>
|
||||
ServiceOpenCard(
|
||||
username: json['username'] as String?,
|
||||
mobile: json['mobile'] as String?,
|
||||
avatar: json['avatar'] as String?,
|
||||
cardStatus: json['cardStatus'] as String?,
|
||||
id: json['id'] as String?,
|
||||
deptId: json['deptId'] as String?,
|
||||
deptName: json['deptName'] as String?,
|
||||
userId: json['userId'] as String?,
|
||||
walletTypeId: json['walletTypeId'] as String?,
|
||||
walletTypeUniqueCode: json['walletTypeUniqueCode'] as String?,
|
||||
walletTypeIcon: json['walletTypeIcon'] as String?,
|
||||
cardNumber: json['cardNumber'] as String?,
|
||||
walletId: json['walletId'] as String?,
|
||||
isActiveHardware:
|
||||
JsonTool.stringToBoolean(json['isActiveHardware'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ServiceOpenCardToJson(ServiceOpenCard instance) =>
|
||||
<String, dynamic>{
|
||||
'username': instance.username,
|
||||
'mobile': instance.mobile,
|
||||
'avatar': instance.avatar,
|
||||
'cardStatus': instance.cardStatus,
|
||||
'id': instance.id,
|
||||
'deptId': instance.deptId,
|
||||
'deptName': instance.deptName,
|
||||
'userId': instance.userId,
|
||||
'walletTypeId': instance.walletTypeId,
|
||||
'walletTypeUniqueCode': instance.walletTypeUniqueCode,
|
||||
'walletTypeIcon': instance.walletTypeIcon,
|
||||
'cardNumber': instance.cardNumber,
|
||||
'walletId': instance.walletId,
|
||||
'isActiveHardware': JsonTool.booleanToString(instance.isActiveHardware),
|
||||
};
|
||||
|
||||
ServiceOpenCardPage _$ServiceOpenCardPageFromJson(Map<String, dynamic> json) =>
|
||||
ServiceOpenCardPage(
|
||||
records: (json['records'] as List<dynamic>?)
|
||||
?.map((e) => ServiceOpenCard.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
)
|
||||
..current = (json['current'] as num).toInt()
|
||||
..pages = (json['pages'] as num).toInt()
|
||||
..size = (json['size'] as num).toInt()
|
||||
..total = (json['total'] as num).toInt();
|
||||
|
||||
Map<String, dynamic> _$ServiceOpenCardPageToJson(
|
||||
ServiceOpenCardPage instance) =>
|
||||
<String, dynamic>{
|
||||
'current': instance.current,
|
||||
'pages': instance.pages,
|
||||
'size': instance.size,
|
||||
'total': instance.total,
|
||||
'records': instance.records,
|
||||
};
|
||||
@@ -100,3 +100,16 @@ enum ProductHourType implements BaseEnum {
|
||||
|
||||
const ProductHourType(this.code, this.title);
|
||||
}
|
||||
|
||||
enum WalletType implements BaseEnum {
|
||||
eat("1", "饭卡钱包"),
|
||||
pay("2", "虚拟钱包"),
|
||||
;
|
||||
|
||||
@override
|
||||
final String code;
|
||||
@override
|
||||
final String title;
|
||||
|
||||
const WalletType(this.code, this.title);
|
||||
}
|
||||
@@ -68,6 +68,7 @@ const _$OrderTypeEnumMap = {
|
||||
};
|
||||
|
||||
const _$OrderStatusEnumMap = {
|
||||
OrderStatus.all: 'all',
|
||||
OrderStatus.nonePay: 'nonePay',
|
||||
OrderStatus.pay: 'pay',
|
||||
OrderStatus.offlinePay: 'offlinePay',
|
||||
|
||||
@@ -26,9 +26,8 @@ class SyncFaceTool {
|
||||
if (isGlobalFace != null && isGlobalFace) pa["merchantDeptId"] = null;
|
||||
logger.i("|$_tag|同步人脸api参数:|$pa|");
|
||||
try {
|
||||
final res = await UserApi.getFaceList(pa);
|
||||
if (res.code != 0 || res.data == null) throw Error();
|
||||
final data = res.data as List<ServiceAsyncFace>;
|
||||
final data = await UserApi.getFaceList(pa);
|
||||
if (data == null) throw Error();
|
||||
if (ObjectUtil.isEmptyList(data)) {
|
||||
if (ObjectUtil.isEmpty(userId)) return false;
|
||||
// 删除人脸图片
|
||||
|
||||
@@ -81,7 +81,7 @@ Widget orderAllPrice(
|
||||
Widget orderSelectPanel(
|
||||
BuildContext context, {
|
||||
required void Function(int, int) onChange,
|
||||
String label = "馒头馒头馒头馒头馒头",
|
||||
String label = "",
|
||||
int total = 1,
|
||||
num price = 0,
|
||||
int index = 0,
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
Widget userInfo(
|
||||
Widget appUserInfo(
|
||||
BuildContext context, {
|
||||
dynamic username = "未知",
|
||||
dynamic balance = "未知",
|
||||
|
||||
@@ -19,28 +19,31 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
size: theme.typography.xl4.fontSize,
|
||||
).alignLeft().width(headerHeight).onTap(() => Get.back()),
|
||||
Obx(() => controller.classifyList
|
||||
.map((v) {
|
||||
final currentIndex = controller.currentTabIndex.value;
|
||||
final target = controller.classifyList[currentIndex];
|
||||
final active = target.id == v.id;
|
||||
return FButton(
|
||||
style: active ? FButtonStyle.primary : FButtonStyle.secondary,
|
||||
label: Text(
|
||||
v.name,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: active
|
||||
? theme.colorScheme.secondary
|
||||
: theme.colorScheme.primary,
|
||||
.map(
|
||||
(v) {
|
||||
final currentIndex = controller.currentTabIndex.value;
|
||||
final target = controller.classifyList[currentIndex];
|
||||
final active = target.id == v.id;
|
||||
return FButton(
|
||||
style:
|
||||
active ? FButtonStyle.primary : FButtonStyle.secondary,
|
||||
label: Text(
|
||||
v.name,
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: active
|
||||
? theme.colorScheme.secondary
|
||||
: theme.colorScheme.primary,
|
||||
),
|
||||
).center().width(120.w),
|
||||
onPress: () => controller.doTab(
|
||||
controller.classifyList.indexWhere((i) => i.id == v.id),
|
||||
),
|
||||
).center().width(120.w),
|
||||
onPress: () => controller.doTab(
|
||||
controller.classifyList.indexWhere((i) => i.id == v.id),
|
||||
),
|
||||
);
|
||||
})
|
||||
);
|
||||
},
|
||||
)
|
||||
.toList()
|
||||
.toRowSpace(space: 20.w))
|
||||
.scrollable(scrollDirection: Axis.horizontal)
|
||||
@@ -169,7 +172,7 @@ class CanteenProductPage extends GetView<CanteenProductController> {
|
||||
<Widget>[
|
||||
Obx(() {
|
||||
final payUser = controller.payUser.value;
|
||||
return userInfo(
|
||||
return appUserInfo(
|
||||
context,
|
||||
username: payUser?.username,
|
||||
balance: payUser?.walletBalance,
|
||||
|
||||
@@ -1,18 +1,45 @@
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
class CardActiveController extends GetxController {
|
||||
CardActiveController();
|
||||
final appC = Get.find<AppControl>();
|
||||
|
||||
SerialCardManage get serialCardManage => appC.serialCardManage;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
// table
|
||||
RxInt currentPage = 1.obs;
|
||||
|
||||
RxInt totalPage = 0.obs;
|
||||
|
||||
RxInt pageSize = 10.obs;
|
||||
|
||||
RxList<ServiceOpenCard> tableList = <ServiceOpenCard>[].obs;
|
||||
|
||||
// 读卡器
|
||||
RxString readCardNumber = "未读取".obs;
|
||||
|
||||
RxBool readLoading = false.obs;
|
||||
|
||||
// 写卡
|
||||
RxBool writeLoading = false.obs;
|
||||
|
||||
_initData() {
|
||||
update(["card_active"]);
|
||||
}
|
||||
|
||||
void onTap() {}
|
||||
|
||||
// @override
|
||||
// void onInit() {
|
||||
// super.onInit();
|
||||
// }
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_closeStatus();
|
||||
getTableList();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
@@ -20,8 +47,188 @@ class CardActiveController extends GetxController {
|
||||
_initData();
|
||||
}
|
||||
|
||||
// @override
|
||||
// void onClose() {
|
||||
// super.onClose();
|
||||
// }
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
_closeStatus();
|
||||
}
|
||||
|
||||
Future<void> doPage({int? page}) async {
|
||||
if (page != null) currentPage.value = page;
|
||||
getTableList();
|
||||
}
|
||||
|
||||
Future<void> getTableList() async {
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
final deptId = appSetting.merchantDeptId;
|
||||
final pa = {
|
||||
"current": currentPage.value,
|
||||
"size": pageSize.value,
|
||||
"deptId": "",
|
||||
"walletTypeId": "",
|
||||
};
|
||||
final data = await WalletApi.openCardList(pa);
|
||||
if (data == null) return;
|
||||
totalPage.value = data.total;
|
||||
final records = data.records;
|
||||
if (records != null) {
|
||||
tableList.value = records;
|
||||
}
|
||||
}
|
||||
|
||||
// 写卡
|
||||
void doWriteCard(ServiceOpenCard v) async {
|
||||
if (v.isActiveHardware == true) {
|
||||
Toast.error(msg: "该卡已经激活,无需重复激活");
|
||||
return;
|
||||
}
|
||||
if (ObjectUtil.isEmpty(v.cardNumber)) {
|
||||
Toast.error(msg: "没有设置卡号");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await serialCardManage.connect();
|
||||
if (!serialCardManage.isConnect) {
|
||||
Toast.error(msg: "连接读卡器失败");
|
||||
return;
|
||||
}
|
||||
writeLoading.value = true;
|
||||
// writeCardDialog(
|
||||
// context: Get.context!,
|
||||
// cardNumber: v.cardNumber!,
|
||||
// doCancel: () {
|
||||
// Get.back();
|
||||
// serialCardManage.readerClose();
|
||||
// serialCardManage.close();
|
||||
// _closeWriteStatus();
|
||||
// },
|
||||
// );
|
||||
serialCardManage.callback = (type, status, res) async {
|
||||
switch (status) {
|
||||
case SerialCardResStatus.success:
|
||||
Toast.success(msg: "写入成功");
|
||||
serialCardManage.readerClose();
|
||||
serialCardManage.close();
|
||||
if (ObjectUtil.isNotEmpty(v.id)) {
|
||||
await _getOpenCardSuccess(v.id!);
|
||||
currentPage.value = 1;
|
||||
getTableList();
|
||||
}
|
||||
Navigator.of(Get.context!).pop();
|
||||
break;
|
||||
case SerialCardResStatus.warning:
|
||||
break;
|
||||
case SerialCardResStatus.error:
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
Toast.error(msg: "请在合适区域放置饭卡");
|
||||
break;
|
||||
}
|
||||
};
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
serialCardManage.sendWrite(v.cardNumber!);
|
||||
} catch (e, stack) {
|
||||
logger.d("写卡失败error:|$e|stack:|$stack|");
|
||||
Toast.error(msg: "写入失败,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
// 读卡
|
||||
void doSelectHorType() async {
|
||||
try {
|
||||
await serialCardManage.connect();
|
||||
if (!serialCardManage.isConnect) {
|
||||
Toast.error(msg: "连接读卡器失败");
|
||||
return;
|
||||
}
|
||||
readLoading.value = true;
|
||||
// readCardDialog(
|
||||
// context: Get.context!,
|
||||
// doCancel: () {
|
||||
// serialCardManage.readerClose();
|
||||
// serialCardManage.close();
|
||||
// _closeReadStatus();
|
||||
// Get.back();
|
||||
// },
|
||||
// );
|
||||
serialCardManage.callback = (type, status, res) {
|
||||
switch (status) {
|
||||
case SerialCardResStatus.success:
|
||||
Toast.success(msg: "读取成功");
|
||||
readLoading.value = false;
|
||||
readCardNumber.value = res;
|
||||
serialCardManage.readerClose();
|
||||
serialCardManage.close();
|
||||
break;
|
||||
case SerialCardResStatus.warning:
|
||||
break;
|
||||
case SerialCardResStatus.error:
|
||||
Toast.error(msg: "请在合适区域放置饭卡");
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
break;
|
||||
}
|
||||
};
|
||||
_speeching("请在合适区域放置饭卡");
|
||||
serialCardManage.sendRead();
|
||||
} catch (e, stack) {
|
||||
_closeReadStatus();
|
||||
logger.d("读卡失败error:|$e|stack:|$stack|");
|
||||
Toast.error(msg: "读取失败,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _getOpenCardSuccess(String id) async {
|
||||
try {
|
||||
EasyLoading.show(status: '激活饭卡中...');
|
||||
final pa = {"id": id};
|
||||
final data = await WalletApi.openCardSuccess(pa);
|
||||
if (data == false) throw Error();
|
||||
EasyLoading.dismiss();
|
||||
_speeching("激活成功");
|
||||
Toast.success(msg: "激活成功");
|
||||
} catch (e, stack) {
|
||||
logger.e("激活饭卡请求失败error:|$e|stack:|$stack|");
|
||||
EasyLoading.dismiss();
|
||||
Toast.error(msg: "激活失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 重新激活
|
||||
Future<void> doRefreshAvatar(ServiceOpenCard v) async {
|
||||
if (v.isActiveHardware == false) {
|
||||
Toast.error(msg: "该卡为激活状态,不能重新激活");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final isSure = await appMessageDialog(Get.context!, "是否重新激活");
|
||||
if (!isSure) return;
|
||||
final pa = {"id": v.id};
|
||||
final data = await WalletApi.refreshAvatar(pa);
|
||||
if (data == false) return;
|
||||
getTableList();
|
||||
} catch (e, stack) {
|
||||
logger.d("重新激活失败error:|$e|stack:|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _closeReadStatus() {
|
||||
readLoading.value = false;
|
||||
readCardNumber.value = "未读取";
|
||||
}
|
||||
|
||||
// 重置状态
|
||||
void _closeStatus() {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,176 @@
|
||||
import 'package:data_table_2/data_table_2.dart';
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
import 'index.dart';
|
||||
|
||||
class CardActivePage extends GetView<CardActiveController> {
|
||||
const CardActivePage({super.key});
|
||||
|
||||
// 主视图
|
||||
Widget _buildView() {
|
||||
return const Center(
|
||||
child: Text("CardActivePage"),
|
||||
);
|
||||
Widget _buildView(BuildContext context) {
|
||||
return <Widget>[
|
||||
_condition(context),
|
||||
_buildTable(context).expanded(),
|
||||
Obx(() => appPage(
|
||||
context,
|
||||
pageNo: controller.currentPage.value,
|
||||
pageSize: controller.pageSize.value,
|
||||
total: controller.totalPage.value,
|
||||
onPageChanged: (page) => controller.doPage(page: page),
|
||||
))
|
||||
].toColumn();
|
||||
}
|
||||
|
||||
// 条件
|
||||
Widget _condition(BuildContext context) {
|
||||
return const Center();
|
||||
}
|
||||
|
||||
// 主视图
|
||||
Widget _buildTable(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final width = constraints.maxWidth;
|
||||
final height = constraints.maxHeight;
|
||||
final hdHeight = (height - 50.h) / 10.5;
|
||||
final hdWidth = (width - 50.h) / 4.5;
|
||||
return Obx(() => DataTable2(
|
||||
columnSpacing: 12.w,
|
||||
horizontalMargin: 12.w,
|
||||
minWidth: hdWidth,
|
||||
showBottomBorder: true,
|
||||
headingTextStyle: theme.typography.lg,
|
||||
dataTextStyle: theme.typography.base,
|
||||
dataRowHeight: hdHeight,
|
||||
columns: [
|
||||
DataColumn2(
|
||||
label: Text("编号", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 280.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("开卡部门", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("绑定用户昵称", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("绑定用户手机号", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("饭卡类型", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("饭卡卡号", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("饭卡状态", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("操作", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
],
|
||||
rows: controller.tableList
|
||||
.map(
|
||||
(v) => DataRow(
|
||||
cells: [
|
||||
DataCell(
|
||||
Text(
|
||||
v.id ?? "未知",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.deptName ?? "未知",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.username ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.mobile ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
WalletType.values
|
||||
.fromCode(v.walletTypeUniqueCode)
|
||||
?.title ??
|
||||
"未知",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.cardNumber ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.isActiveHardware == false ? "未激活" : "激活",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
WalletType.values
|
||||
.fromCode(v.walletTypeUniqueCode)
|
||||
?.title ??
|
||||
"未知",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final height = context.height;
|
||||
return GetBuilder<CardActiveController>(
|
||||
init: CardActiveController(),
|
||||
id: "card_active",
|
||||
builder: (_) {
|
||||
return FScaffold(
|
||||
header: FHeader(title: SizedBox.shrink()),
|
||||
content: _buildView(),
|
||||
contentPad: true,
|
||||
resizeToAvoidBottomInset: true,
|
||||
header: FHeader.nested(
|
||||
title: Text("开卡管理"),
|
||||
prefixActions: [
|
||||
FHeaderAction.back(onPress: Get.back),
|
||||
],
|
||||
style: theme.headerStyle.nestedStyle.copyWith(
|
||||
titleTextStyle: theme.typography.lg,
|
||||
actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith(
|
||||
size: theme.typography.xl2.fontSize,
|
||||
),
|
||||
),
|
||||
).height(height * 0.1),
|
||||
content: _buildView(context),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
+127
-124
@@ -20,12 +20,14 @@ class OrderHistoryPage extends GetView<OrderHistoryController> {
|
||||
_buildCondition(context, headerHeight),
|
||||
SizedBox(height: 20.h),
|
||||
_buildTable(context).center().expanded(),
|
||||
appPage(
|
||||
context,
|
||||
pageNo: controller.currentPage.value,
|
||||
pageSize: controller.pageSize.value,
|
||||
total: controller.totalPage.value,
|
||||
onPageChanged: (page) => controller.doPage(page: page),
|
||||
Obx(
|
||||
() => appPage(
|
||||
context,
|
||||
pageNo: controller.currentPage.value,
|
||||
pageSize: controller.pageSize.value,
|
||||
total: controller.totalPage.value,
|
||||
onPageChanged: (page) => controller.doPage(page: page),
|
||||
),
|
||||
)
|
||||
].toColumn();
|
||||
}
|
||||
@@ -69,128 +71,129 @@ class OrderHistoryPage extends GetView<OrderHistoryController> {
|
||||
|
||||
Widget _buildTable(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final titleTextStyle = theme.typography.lg;
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final height = constraints.maxHeight;
|
||||
final hdHeight = (height - 50.h) / 10.5;
|
||||
return DataTable2(
|
||||
columnSpacing: 12.w,
|
||||
horizontalMargin: 12.w,
|
||||
minWidth: 600.w,
|
||||
showBottomBorder: true,
|
||||
headingTextStyle: theme.typography.lg,
|
||||
dataTextStyle: theme.typography.base,
|
||||
dataRowHeight: hdHeight,
|
||||
columns: [
|
||||
DataColumn2(
|
||||
label: Text("下单时间", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 260.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('订餐类型'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('支付类型'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('订单人', textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('菜品名称'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 220.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('数量'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('菜品总价'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('额外支付'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('实际扣款'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('操作'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
],
|
||||
rows: controller.orderList
|
||||
.map(
|
||||
(v) => DataRow(cells: [
|
||||
DataCell(
|
||||
Text(
|
||||
DateUtil.formatDate(v.createTime),
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.type.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.payType.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.username ?? "未知用户",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.productDesc ?? "未知商品",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
"${v.count}",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.price).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.extraPrice).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.payPrice).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.payType.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.toList(),
|
||||
return Obx(
|
||||
() => DataTable2(
|
||||
columnSpacing: 12.w,
|
||||
horizontalMargin: 12.w,
|
||||
minWidth: 600.w,
|
||||
showBottomBorder: true,
|
||||
headingTextStyle: theme.typography.lg,
|
||||
dataTextStyle: theme.typography.base,
|
||||
dataRowHeight: hdHeight,
|
||||
columns: [
|
||||
DataColumn2(
|
||||
label: Text("下单时间", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 260.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('订餐类型'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('支付类型'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('订单人', textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('菜品名称'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 220.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('数量'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('菜品总价'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('额外支付'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('实际扣款'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text('操作'),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: 150.w,
|
||||
),
|
||||
],
|
||||
rows: controller.orderList
|
||||
.map(
|
||||
(v) => DataRow(cells: [
|
||||
DataCell(
|
||||
Text(
|
||||
DateUtil.formatDate(v.createTime),
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.type.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.payType.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.username ?? "未知用户",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.productDesc ?? "未知商品",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
"${v.count}",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.price).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.extraPrice).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.payPrice).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
v.payType.title,
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -104,12 +104,25 @@ class SettingPage extends GetView<SettingController> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final height = context.height;
|
||||
return GetBuilder<SettingController>(
|
||||
init: SettingController(),
|
||||
id: "setting",
|
||||
builder: (_) {
|
||||
return FScaffold(
|
||||
header: FHeader(title: SizedBox.shrink()),
|
||||
header: FHeader.nested(
|
||||
title: Text("设置"),
|
||||
prefixActions: [
|
||||
FHeaderAction.back(onPress: Get.back),
|
||||
],
|
||||
style: theme.headerStyle.nestedStyle.copyWith(
|
||||
titleTextStyle: theme.typography.lg,
|
||||
actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith(
|
||||
size: theme.typography.xl2.fontSize,
|
||||
),
|
||||
),
|
||||
).height(height * 0.1),
|
||||
content: _buildView(),
|
||||
contentPad: true,
|
||||
resizeToAvoidBottomInset: true,
|
||||
|
||||
@@ -212,7 +212,7 @@ Widget buildFacePage(context) {
|
||||
context,
|
||||
pageNo: faceC.currentPage.value,
|
||||
pageSize: faceC.pageSize.value,
|
||||
total: faceC.totalPage.value * faceC.pageSize.value,
|
||||
total: faceC.totalPage.value,
|
||||
onPageChanged: (pageNo) => faceC.doPage(page: pageNo),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -8,7 +9,7 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
const SupermarketOrderPage({super.key});
|
||||
|
||||
// 主视图
|
||||
Widget _buildView() {
|
||||
Widget _buildView(BuildContext context) {
|
||||
return const Center(
|
||||
child: Text("SupermarketOrderPage"),
|
||||
);
|
||||
@@ -16,15 +17,26 @@ class SupermarketOrderPage extends GetView<SupermarketOrderController> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final height = context.height;
|
||||
return GetBuilder<SupermarketOrderController>(
|
||||
init: SupermarketOrderController(),
|
||||
id: "supermarket_order",
|
||||
builder: (_) {
|
||||
return FScaffold(
|
||||
header: FHeader(title: SizedBox.shrink()),
|
||||
content: _buildView(),
|
||||
contentPad: true,
|
||||
resizeToAvoidBottomInset: true,
|
||||
header: FHeader.nested(
|
||||
title: Text("取餐"),
|
||||
prefixActions: [
|
||||
FHeaderAction.back(onPress: Get.back),
|
||||
],
|
||||
style: theme.headerStyle.nestedStyle.copyWith(
|
||||
titleTextStyle: theme.typography.lg,
|
||||
actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith(
|
||||
size: theme.typography.xl2.fontSize,
|
||||
),
|
||||
),
|
||||
).height(height * 0.1),
|
||||
content: _buildView(context),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,27 +1,197 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
class TakeFoodController extends GetxController {
|
||||
TakeFoodController();
|
||||
final appC = Get.find<AppControl>();
|
||||
|
||||
Rxn<ServiceUser> payUser = Rxn<ServiceUser>(ServiceUser());
|
||||
|
||||
RxList<ServiceCar> carList = <ServiceCar>[].obs;
|
||||
|
||||
OrderPayType orderPayType = OrderPayType.reserveQrCode;
|
||||
|
||||
OrderType orderType = OrderType.reserve;
|
||||
|
||||
int totalPrice = 0;
|
||||
|
||||
String? orderId;
|
||||
|
||||
ServiceQRCode? globalQrCode;
|
||||
|
||||
// 语音锁
|
||||
bool _speechingLock = false;
|
||||
|
||||
_initData() {
|
||||
update(["take_food"]);
|
||||
}
|
||||
|
||||
void onTap() {}
|
||||
|
||||
// @override
|
||||
// void onInit() {
|
||||
// super.onInit();
|
||||
// }
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
SubScreenPlugin.doubleScreenShow();
|
||||
SubScreenPlugin.sendMsgToViceScreen(SubScreenAction.jumpSubPage.name);
|
||||
// 开启扫码功能
|
||||
startQrcode();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
_closeStatus();
|
||||
_initData();
|
||||
}
|
||||
|
||||
// @override
|
||||
// void onClose() {
|
||||
// super.onClose();
|
||||
// }
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
// 二维码读头
|
||||
appC.serialCardManage.close();
|
||||
_closeStatus();
|
||||
}
|
||||
|
||||
// 重置状态
|
||||
void _closeStatus() {
|
||||
_speechingLock = false;
|
||||
}
|
||||
|
||||
doCancelPay() {
|
||||
orderId = null;
|
||||
globalQrCode = null;
|
||||
payUser.value = ServiceUser();
|
||||
payUser.refresh();
|
||||
carList.value = [];
|
||||
}
|
||||
|
||||
doPay() async {
|
||||
await orderQrCodeCancel();
|
||||
}
|
||||
|
||||
/// 获取订单详情
|
||||
Future<void> getOrderDetail() async {
|
||||
if (ObjectUtil.isEmpty(orderId)) return;
|
||||
final pa = {"id": orderId};
|
||||
try {
|
||||
final data = await HardApi.getOrder(pa);
|
||||
if (data == null) throw Error();
|
||||
if (ObjectUtil.isEmpty(data)) return;
|
||||
payUser.value?.username = data.username;
|
||||
payUser.value?.userId = globalQrCode?.userId;
|
||||
payUser.value?.userAvatar = data.userAvatar;
|
||||
payUser.refresh();
|
||||
} catch (e) {
|
||||
logger.e("获取订单详情错误error:|$e|");
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取购物车详情
|
||||
Future<void> getCarList() async {
|
||||
if (ObjectUtil.isEmpty(orderId)) return;
|
||||
final pa = {"orderId": orderId};
|
||||
try {
|
||||
final data = await HardApi.getCarByOrderId(pa);
|
||||
if (data == null) throw Error();
|
||||
carList.value = data;
|
||||
senSubScreen();
|
||||
} catch (e, stack) {
|
||||
logger.e("获取购物车详情错误error:|$e|stack:|$stack|");
|
||||
}
|
||||
}
|
||||
|
||||
/// 开启扫码
|
||||
Future<void> startQrcode() async {
|
||||
try {
|
||||
final isOpen = await appC.scanCodeManage.open();
|
||||
if (!isOpen) return;
|
||||
appC.scanCodeManage.listen<String>((str) async {
|
||||
if (ObjectUtil.isNotEmpty(str)) {
|
||||
str = EncryptUtil.decodeBase64(str);
|
||||
final qrCode = ServiceQRCode.fromJson(json.decode(str));
|
||||
if (ObjectUtil.isEmpty(qrCode)) {
|
||||
Toast.error(msg: "识别错误,无效的二维码");
|
||||
return;
|
||||
}
|
||||
globalQrCode = qrCode;
|
||||
// 二维码支付渠道
|
||||
if (ObjectUtil.isNotEmpty(qrCode.payType)) {
|
||||
final OrderPayType? type = OrderPayType.values.fromCode(
|
||||
qrCode.payType!,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(type)) {
|
||||
orderPayType = type!;
|
||||
}
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(qrCode.orderType)) {
|
||||
final OrderType? type = OrderType.values.fromCode(
|
||||
qrCode.orderType!,
|
||||
);
|
||||
if (ObjectUtil.isNotEmpty(type)) {
|
||||
orderType = type!;
|
||||
}
|
||||
}
|
||||
orderId = qrCode.id;
|
||||
await getOrderDetail();
|
||||
await getCarList();
|
||||
Toast.success(msg: "识别二维码成功");
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
doCancelPay();
|
||||
logger.e("开启扫码错误error:|$e|");
|
||||
}
|
||||
}
|
||||
|
||||
/// 订单核销
|
||||
Future<void> orderQrCodeCancel() async {
|
||||
if (ObjectUtil.isEmpty(orderId)) {
|
||||
Toast.error(msg: "请前往设置绑定设备");
|
||||
return;
|
||||
}
|
||||
final appSetting = await AppSettingTool.getSysSetting();
|
||||
final serviceId = appSetting.serviceId;
|
||||
if (ObjectUtil.isEmpty(serviceId)) {
|
||||
Toast.error(msg: "订单不存在");
|
||||
return;
|
||||
}
|
||||
final pa = {
|
||||
"orderId": orderId,
|
||||
"hardwareId": serviceId,
|
||||
};
|
||||
try {
|
||||
EasyLoading.show(
|
||||
status: '核销中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
final res = await HardApi.cancelQrCode(pa);
|
||||
if (res.code != 0) throw Error();
|
||||
EasyLoading.dismiss();
|
||||
Toast.error(msg: "核销成功");
|
||||
_speeching("核销成功");
|
||||
doCancelPay();
|
||||
} catch (e, stack) {
|
||||
logger.e("获取订单详情错误error:|$e|stack:|$stack|");
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
/// 发送给父屏订单信息
|
||||
void senSubScreen() {
|
||||
if (ObjectUtil.isEmpty(carList)) return;
|
||||
}
|
||||
|
||||
Future<void> _speeching(String str) async {
|
||||
if (_speechingLock) return;
|
||||
try {
|
||||
_speechingLock = true;
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await LocalTtsPlugs.speeching(appId: Constants.ttsId, str: str);
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
} finally {
|
||||
_speechingLock = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,164 @@
|
||||
import 'package:data_table_2/data_table_2.dart';
|
||||
import 'package:ducafe_ui_core/ducafe_ui_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
import 'index.dart';
|
||||
|
||||
class TakeFoodPage extends GetView<TakeFoodController> {
|
||||
const TakeFoodPage({super.key});
|
||||
|
||||
// 主视图
|
||||
Widget _buildView() {
|
||||
return const Center(
|
||||
child: Text("TakeFoodPage"),
|
||||
Widget _buildView(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final width = context.width;
|
||||
return <Widget>[
|
||||
_buildTable(context).expanded(),
|
||||
SizedBox(width: 15.w),
|
||||
_buildUserInfo(context).width(width * 0.25).decorated(
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
borderRadius: theme.style.borderRadius,
|
||||
),
|
||||
]
|
||||
.toRow(crossAxisAlignment: CrossAxisAlignment.start)
|
||||
.marginOnly(bottom: 20.h);
|
||||
}
|
||||
|
||||
// 表格
|
||||
Widget _buildTable(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final width = constraints.maxWidth;
|
||||
final height = constraints.maxHeight;
|
||||
final hdHeight = (height - 50.h) / 10.5;
|
||||
final hdWidth = (width - 50.h) / 4.5;
|
||||
return Obx(
|
||||
() => DataTable2(
|
||||
columnSpacing: 12.w,
|
||||
horizontalMargin: 12.w,
|
||||
minWidth: hdWidth,
|
||||
showBottomBorder: true,
|
||||
headingTextStyle: theme.typography.lg,
|
||||
dataTextStyle: theme.typography.base,
|
||||
dataRowHeight: hdHeight,
|
||||
columns: [
|
||||
DataColumn2(
|
||||
label: Text("菜品名称", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("数量", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("单价金额", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("总金额", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
),
|
||||
],
|
||||
rows: controller.carList
|
||||
.map(
|
||||
(v) => DataRow(
|
||||
cells: [
|
||||
DataCell(
|
||||
Text(
|
||||
"${v.productName}",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
"${v.productCount}",
|
||||
textAlign: TextAlign.center,
|
||||
).center(),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.productPrice),
|
||||
),
|
||||
DataCell(
|
||||
appPrice(context, v.totalPrice),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// 用户
|
||||
Widget _buildUserInfo(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
return <Widget>[
|
||||
Obx(() {
|
||||
final payUser = controller.payUser.value;
|
||||
return appUserInfo(
|
||||
context,
|
||||
username: payUser?.username,
|
||||
balance: payUser?.walletBalance,
|
||||
avatar: payUser?.userAvatar,
|
||||
);
|
||||
}).width(400.w).center(),
|
||||
SizedBox(height: 200.h),
|
||||
<Widget>[
|
||||
FButton(
|
||||
style: FButtonStyle.destructive,
|
||||
label: Text(
|
||||
"取消点餐",
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () => controller.doCancelPay(),
|
||||
).flexible(flex: 1),
|
||||
SizedBox(width: 20.w),
|
||||
FButton(
|
||||
label: Text(
|
||||
"确认点餐",
|
||||
style: theme.typography.xl.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () => controller.doPay(),
|
||||
).flexible(flex: 1),
|
||||
].toRow(crossAxisAlignment: CrossAxisAlignment.end).expanded(),
|
||||
].toColumn().padding(vertical: 10.h, horizontal: 10.w);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final height = context.height;
|
||||
return GetBuilder<TakeFoodController>(
|
||||
init: TakeFoodController(),
|
||||
id: "take_food",
|
||||
builder: (_) {
|
||||
return FScaffold(
|
||||
header: FHeader.nested(
|
||||
title: Text("取餐", style: theme.typography.xl3),
|
||||
title: Text("取餐"),
|
||||
prefixActions: [
|
||||
FHeaderAction.back(onPress: () {}),
|
||||
FHeaderAction.back(onPress: Get.back),
|
||||
],
|
||||
),
|
||||
content: _buildView(),
|
||||
style: theme.headerStyle.nestedStyle.copyWith(
|
||||
titleTextStyle: theme.typography.lg,
|
||||
actionStyle: theme.headerStyle.nestedStyle.actionStyle.copyWith(
|
||||
size: theme.typography.xl2.fontSize,
|
||||
),
|
||||
),
|
||||
).height(height * 0.1),
|
||||
content: _buildView(context),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user