feat:挂单
This commit is contained in:
1 parent
988247f3cd
commit
2b956342f4
12 files changed
+545
-36
No files matched your search
@@ -27,7 +27,8 @@ export './order/steelyard_container.dart';
|
||||
export './order/order_caneen_common.dart';
|
||||
export './order/order_common.dart';
|
||||
export './order/order_supermarket_common.dart';
|
||||
export 'order/order_more_dialog.dart';
|
||||
export './order/select_hold_bill_dialog.dart';
|
||||
export './order/order_more_dialog.dart';
|
||||
|
||||
export './setting/setting_password_dialog.dart';
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ mixin OrderMixin {
|
||||
await orderDao.edit(sqlOrderDetail);
|
||||
if (orderPayType.value != OrderPayType.WALLET_QR_CODE_SCAN) {
|
||||
if (sqlOrderDetail.payPrice != 0) {
|
||||
final price = AppriceTool.fenToYuan(sqlOrderDetail.payPrice);
|
||||
final price = AppPriceTool.fenToYuan(sqlOrderDetail.payPrice);
|
||||
TtsManage.speak("购买成功总金额$price元");
|
||||
}
|
||||
Toast.success(msg: "购买成功");
|
||||
|
||||
@@ -24,7 +24,7 @@ Future<OrderMoreTypeEnum?> selectOrderMoreDialog() async {
|
||||
final width = Get.context!.width;
|
||||
final height = Get.context!.height;
|
||||
final dialogWidth = width * 0.3;
|
||||
final dialogHeight = height * 0.5;
|
||||
final dialogHeight = height * 0.25;
|
||||
return showDialog<OrderMoreTypeEnum?>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
@@ -55,7 +55,10 @@ Future<OrderMoreTypeEnum?> selectOrderMoreDialog() async {
|
||||
).marginOnly(bottom: 20.h),
|
||||
)
|
||||
.toList(),
|
||||
].toColumn().width(double.infinity).height(dialogHeight),
|
||||
]
|
||||
.toColumn(mainAxisAlignment: MainAxisAlignment.center)
|
||||
.width(double.infinity)
|
||||
.height(dialogHeight),
|
||||
actions: [],
|
||||
);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
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:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:forui/forui.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
|
||||
class SelectHoldBillController extends GetxController {
|
||||
static const String _tag = "挂单管理 Controller";
|
||||
|
||||
final appC = Get.find<AppControl>();
|
||||
|
||||
// 选择的时间
|
||||
RxList<DateTime> selectDateTime = <DateTime>[
|
||||
DateTime.now(),
|
||||
DateTime.now().add(const Duration(days: 1)),
|
||||
].obs;
|
||||
|
||||
RxInt currentPage = RxInt(1);
|
||||
|
||||
RxInt totalPage = RxInt(0);
|
||||
|
||||
RxInt pageSize = RxInt(5);
|
||||
|
||||
RxList<OrderHoldBillEntity> holdBillList = RxList();
|
||||
Rxn<int> selectedId = Rxn<int>(null);
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
await getHoldBillList();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {}
|
||||
|
||||
Future<void> doDateRangeDate(List<DateTime>? dateTime) async {
|
||||
if (ObjectUtil.isEmptyList(dateTime)) {
|
||||
return;
|
||||
}
|
||||
selectDateTime.value = dateTime!;
|
||||
currentPage.value = 1;
|
||||
await doPage();
|
||||
}
|
||||
|
||||
/// 搜索
|
||||
Future<void> doPage({int? page}) async {
|
||||
if (page != null) currentPage.value = page;
|
||||
await getHoldBillList(isLoading: true);
|
||||
}
|
||||
|
||||
/// 获取挂单列表
|
||||
Future<void> getHoldBillList({bool isLoading = false}) async {
|
||||
if (isLoading) {
|
||||
EasyLoading.show(
|
||||
status: '查询中...',
|
||||
maskType: EasyLoadingMaskType.black,
|
||||
);
|
||||
}
|
||||
final orderHoldBillDao = appC.dataBase.getOrderHoldBillDao;
|
||||
try {
|
||||
final startTime = DateUtil.formatDate(
|
||||
DateTime(selectDateTime[0].year, selectDateTime[0].month,
|
||||
selectDateTime[0].day, 0, 0, 0),
|
||||
);
|
||||
final endTime = DateUtil.formatDate(
|
||||
DateTime(selectDateTime[1].year, selectDateTime[1].month,
|
||||
selectDateTime[1].day, 23, 59, 59),
|
||||
);
|
||||
final total = await orderHoldBillDao.count(
|
||||
startTime,
|
||||
endTime,
|
||||
);
|
||||
totalPage.value = total ?? 0;
|
||||
final list = await orderHoldBillDao.list(
|
||||
startTime,
|
||||
endTime,
|
||||
pageSize.value,
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
);
|
||||
if (ObjectUtil.isEmptyList(list)) {
|
||||
holdBillList.value = [];
|
||||
return;
|
||||
}
|
||||
holdBillList.value = list;
|
||||
} catch (error, stack) {
|
||||
LogUtil.e("|$_tag|,获取挂单列表意外的错误error:|$error|,stack:|$stack|");
|
||||
} finally {
|
||||
if (isLoading) {
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
EasyLoading.dismiss();
|
||||
});
|
||||
}
|
||||
// 只保留7天内的挂单数据
|
||||
orderHoldBillDao.deleteOlderThan7Days();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<OrderHoldBillEntity?> selectHoldBillDialog() async {
|
||||
final context = Get.context!;
|
||||
final theme = FTheme.of(context);
|
||||
final holdBillC = Get.put<SelectHoldBillController>(
|
||||
SelectHoldBillController(),
|
||||
);
|
||||
await holdBillC.getHoldBillList(isLoading: true);
|
||||
|
||||
final width = Get.context!.width;
|
||||
final height = Get.context!.height;
|
||||
final dialogWidth = width * 0.9;
|
||||
final dialogHeight = height * 0.7;
|
||||
|
||||
return showDialog<OrderHoldBillEntity?>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (BuildContext _) {
|
||||
return FDialog(
|
||||
title: Text(
|
||||
"挂单列表",
|
||||
style: theme.typography.lg,
|
||||
).marginOnly(bottom: 20.h),
|
||||
style: theme.dialogStyle.copyWith(
|
||||
insetPadding: EdgeInsets.zero,
|
||||
maxWidth: dialogWidth,
|
||||
minWidth: dialogWidth,
|
||||
horizontalStyle: theme.dialogStyle.horizontalStyle.copyWith(
|
||||
padding: EdgeInsets.all(20.w),
|
||||
),
|
||||
),
|
||||
body: <Widget>[
|
||||
_buildHoldBillSearch(context),
|
||||
_buildHoldBillList(context).expanded(),
|
||||
Obx(
|
||||
() => appPage(
|
||||
context,
|
||||
pageNo: holdBillC.currentPage.value,
|
||||
pageSize: holdBillC.pageSize.value,
|
||||
total: holdBillC.totalPage.value,
|
||||
onPageChanged: (pageNo) => holdBillC.doPage(page: pageNo),
|
||||
),
|
||||
)
|
||||
].toColumn().width(double.infinity).height(dialogHeight),
|
||||
actions: [
|
||||
<Widget>[
|
||||
FButton(
|
||||
label: Text(
|
||||
'确定',
|
||||
style: theme.typography.base.copyWith(
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
onPress: () {
|
||||
final holdBillC = Get.find<SelectHoldBillController>();
|
||||
final selected = holdBillC.holdBillList.firstWhereOrNull(
|
||||
(v) => v.id == holdBillC.selectedId.value,
|
||||
);
|
||||
if (selected == null) {
|
||||
EasyLoading.showInfo("请先选择一条挂单");
|
||||
return;
|
||||
}
|
||||
Get.back(result: selected);
|
||||
},
|
||||
).flexible(flex: 1),
|
||||
SizedBox(width: 10.w),
|
||||
FButton(
|
||||
style: FButtonStyle.outline,
|
||||
label: Text('取消', style: theme.typography.base),
|
||||
onPress: () => Get.back(result: null),
|
||||
).flexible(flex: 1),
|
||||
].toRow()
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHoldBillSearch(BuildContext context) {
|
||||
final holdBillC = Get.find<SelectHoldBillController>();
|
||||
return <Widget>[
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => appDatePicker(
|
||||
context,
|
||||
datetimeRange: holdBillC.selectDateTime,
|
||||
onChnage: (dateList) => holdBillC.doDateRangeDate(dateList),
|
||||
).width(400.w).marginOnly(right: 15.w),
|
||||
),
|
||||
].toRow();
|
||||
}
|
||||
|
||||
Widget _buildHoldBillList(BuildContext context) {
|
||||
final theme = FTheme.of(context);
|
||||
final holdBillC = Get.find<SelectHoldBillController>();
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
final width = constraints.maxWidth;
|
||||
// 计算列可用总宽度 = 父容器宽度 - 左右边距 - 每列之间的间距
|
||||
const int colCount = 4;
|
||||
final double spacing = 12.w; // columnSpacing
|
||||
final double marginH = 12.w; // horizontalMargin
|
||||
final double totalColAvailableWidth =
|
||||
width - 2 * marginH - spacing * (colCount - 1);
|
||||
final hdWidth = totalColAvailableWidth / colCount;
|
||||
|
||||
final height = constraints.maxHeight;
|
||||
final hdHeight = (height - 60.h) / 5;
|
||||
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: hdWidth * 1.7,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("价格", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: hdWidth * 0.8,
|
||||
),
|
||||
DataColumn2(
|
||||
label: Text("挂单时间", textAlign: TextAlign.center),
|
||||
headingRowAlignment: MainAxisAlignment.center,
|
||||
fixedWidth: hdWidth,
|
||||
),
|
||||
],
|
||||
rows: holdBillC.holdBillList.map((e) {
|
||||
final carList = (jsonDecode(e.carListJson ?? '[]') as List)
|
||||
.map((v) => ShopCardEntity.fromJson(v as Map<String, dynamic>))
|
||||
.toList();
|
||||
return DataRow(
|
||||
selected: holdBillC.selectedId.value == e.id,
|
||||
onSelectChanged: (selected) {
|
||||
if (selected == true) {
|
||||
holdBillC.selectedId.value = e.id;
|
||||
}
|
||||
},
|
||||
color: WidgetStateProperty.resolveWith<Color?>((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return theme.colorScheme.secondary.withAlpha(24);
|
||||
}
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return theme.colorScheme.secondary.withAlpha(12);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
cells: [
|
||||
DataCell(
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 1,
|
||||
mainAxisSpacing: 5,
|
||||
crossAxisSpacing: 5,
|
||||
childAspectRatio: 30,
|
||||
),
|
||||
itemCount: carList.length,
|
||||
itemBuilder: (context, i) {
|
||||
final currentCar = carList[i];
|
||||
return <Widget>[
|
||||
Text(
|
||||
"${currentCar.productName}(单价¥${AppPriceTool.fenToYuan(currentCar.productPrice)}) x ${currentCar.productNumber}",
|
||||
textAlign: TextAlign.left,
|
||||
style: theme.typography.sm,
|
||||
),
|
||||
Text("共", style: theme.typography.sm),
|
||||
appPrice(
|
||||
context,
|
||||
currentCar.totalPrice,
|
||||
textStyle: theme.typography.sm,
|
||||
),
|
||||
].toRow().marginOnly(left: 50.w);
|
||||
},
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 1,
|
||||
mainAxisSpacing: 5,
|
||||
crossAxisSpacing: 5,
|
||||
childAspectRatio: 10,
|
||||
),
|
||||
itemCount: 3,
|
||||
itemBuilder: (context, i) {
|
||||
// 购物车总价
|
||||
if (i == 0) {
|
||||
return <Widget>[
|
||||
Text(
|
||||
"购物车总价:",
|
||||
textAlign: TextAlign.left,
|
||||
style: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
appPrice(
|
||||
context,
|
||||
e.price,
|
||||
textStyle: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
].toRow();
|
||||
}
|
||||
// 额外价格
|
||||
if (i == 1) {
|
||||
return <Widget>[
|
||||
Text(
|
||||
"额外价格:",
|
||||
textAlign: TextAlign.left,
|
||||
style: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
appPrice(
|
||||
context,
|
||||
e.extraPrice,
|
||||
textStyle: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
].toRow();
|
||||
}
|
||||
// 支付价格
|
||||
if (i == 2) {
|
||||
return <Widget>[
|
||||
Text(
|
||||
"支付价格:",
|
||||
textAlign: TextAlign.left,
|
||||
style: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
appPrice(
|
||||
context,
|
||||
e.payPrice,
|
||||
textStyle: theme.typography.sm,
|
||||
).flexible(flex: 1),
|
||||
].toRow();
|
||||
}
|
||||
return SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
Text(
|
||||
DateUtil.formatDate(
|
||||
e.createTime,
|
||||
format: DateFormats.full,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.typography.base,
|
||||
).center(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user