From d03926a1a6bb7af1a3ebb0b405ef39db484f7f88 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 16 May 2025 10:36:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=AE=A2=E5=8D=95=E5=8E=86=E5=8F=B2):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=94=AE=E5=90=8E=E9=80=80=E8=B4=A7=E7=90=86?= =?UTF-8?q?=E7=94=B1=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在订单历史模块中,新增了售后退货理由的功能。具体修改包括: 1. 在 `CanteenExtraPriceSetting` 模型中添加 `afterSaleReturnReasons` 字段。 2. 新增 `refundDialog` 组件,用于显示退货理由选择对话框。 3. 在 `OrderHistoryController` 中,更新支付设置时获取并存储退货理由,并在退款时使用。 这些改动旨在为用户提供更详细的退款原因选择,提升用户体验。 --- .../models/database/database_models.dart | 5 ++ .../widgets/order/mixin/order_mixin.dart | 1 + lib/pages/order_history/controller.dart | 88 ++++++++++++------ .../order_history/widgets/refund_dialog.dart | 90 +++++++++++++++++++ 4 files changed, 158 insertions(+), 26 deletions(-) create mode 100644 lib/pages/order_history/widgets/refund_dialog.dart diff --git a/lib/common/models/database/database_models.dart b/lib/common/models/database/database_models.dart index 84f6716..8d08398 100644 --- a/lib/common/models/database/database_models.dart +++ b/lib/common/models/database/database_models.dart @@ -222,6 +222,9 @@ class CanteenExtraPriceSetting extends Equatable { /// 超过的倍数 double payAmountMealTimes; + /// 售后的退货理由 + String? afterSaleReturnReasons; + // 商户支付规则列表 List? mchRoleList; @@ -229,6 +232,7 @@ class CanteenExtraPriceSetting extends Equatable { required this.payAmountEnable, required this.payAmountMealLimit, required this.payAmountMealTimes, + this.afterSaleReturnReasons, this.mchRoleList, }); @@ -237,6 +241,7 @@ class CanteenExtraPriceSetting extends Equatable { payAmountEnable, payAmountMealLimit, payAmountMealTimes, + afterSaleReturnReasons, mchRoleList, ]; diff --git a/lib/common/widgets/order/mixin/order_mixin.dart b/lib/common/widgets/order/mixin/order_mixin.dart index 995ff9a..0094d36 100644 --- a/lib/common/widgets/order/mixin/order_mixin.dart +++ b/lib/common/widgets/order/mixin/order_mixin.dart @@ -501,6 +501,7 @@ mixin OrderMixin { payAmountEnable: data.payAmountEnable!, payAmountMealLimit: data.payAmountMealLimit!, payAmountMealTimes: data.payAmountMealTimes!, + afterSaleReturnReasons: data.afterSaleReturnReasons, ); if (setting == null || setting != storageData) { await AppSettingTool.setCanteenExtraPriceConfig(storageData); diff --git a/lib/pages/order_history/controller.dart b/lib/pages/order_history/controller.dart index d2c4efe..360ab4e 100644 --- a/lib/pages/order_history/controller.dart +++ b/lib/pages/order_history/controller.dart @@ -1,4 +1,5 @@ import 'package:common_utils/common_utils.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:forui/forui.dart'; import 'package:get/get.dart'; @@ -6,6 +7,8 @@ import 'package:get/get_connect/http/src/utils/utils.dart'; import 'package:pj_supermarket_cloud/common/index.dart'; +import 'widgets/refund_dialog.dart'; + class OrderHistoryController extends GetxController { final appC = Get.find(); @@ -21,6 +24,8 @@ class OrderHistoryController extends GetxController { RxList tabList = [].obs; + RxList saleReasons = [].obs; + // 选择的时间 RxList selectDateTime = [ DateTime.now(), @@ -51,6 +56,7 @@ class OrderHistoryController extends GetxController { sysType.value = appSetting.sysType; hourType.value = appSetting.hourType ?? ProductHourType.MORNING; hourTypeC.value = {hourType.value.code}; + _updateSetting(); // tabs await getTotalList(); await getOrder(); @@ -216,34 +222,41 @@ class OrderHistoryController extends GetxController { return; } final price = AppriceTool.fenToYuan(v.payPrice); - final isSure = await appMessageDialog( + refundDialog( Get.context!, - "是否退还${v.username}用户的$price元", + title: "是否退还${v.username}用户的$price元", + saleReasons: saleReasons, + doCancel: () { + Navigator.of(Get.context!).pop(); + }, + doSubmit: (String value) async { + try { + EasyLoading.show( + status: '退款中...', + maskType: EasyLoadingMaskType.black, + ); + final pa = { + "orderId": v.serviceUniqueCode, + "reason": value, + }; + final data = await HardApi.timeLimitRefund(pa); + if (!data) throw Error(); + // 修改本地订单为退款 + v.status = OrderStatus.REFUND; + final orderDao = appC.dataBase.getOrderDao; + await orderDao.edit(v); + await getTotalList(); + await getOrder(); + TtsManage.speak("退款成功总金额$price元"); + } catch (error, stack) { + TtsManage.speak("退款失败"); + logger.e("退款失败error:|$error|stack:|$stack|"); + } finally { + Navigator.of(Get.context!).pop(); + EasyLoading.dismiss(); + } + }, ); - try { - if (!isSure) return; - EasyLoading.show( - status: '退款中...', - maskType: EasyLoadingMaskType.black, - ); - final pa = { - "orderId": v.serviceUniqueCode, - }; - final data = await HardApi.timeLimitRefund(pa); - if (!data) throw Error(); - // 修改本地订单为退款 - v.status = OrderStatus.REFUND; - final orderDao = appC.dataBase.getOrderDao; - await orderDao.edit(v); - await getTotalList(); - await getOrder(); - TtsManage.speak("退款成功总金额$price元"); - } catch (error, stack) { - TtsManage.speak("退款失败"); - logger.e("退款失败error:|$error|stack:|$stack|"); - } finally { - EasyLoading.dismiss(); - } } /// 跳转到订单详情 @@ -288,4 +301,27 @@ class OrderHistoryController extends GetxController { await printManage.close(); } } + + Future _updateSetting() async { + final isNetwork = AppNetworkTool.isAutoNetwork(); + if (!isNetwork) return; + var setting = await AppSettingTool.getCanteenExtraPriceConfig(); + try { + final data = await WalletApi.getPaySetting(); + if (data == null) throw Error(); + final storageData = CanteenExtraPriceSetting( + payAmountEnable: data.payAmountEnable!, + payAmountMealLimit: data.payAmountMealLimit!, + payAmountMealTimes: data.payAmountMealTimes!, + afterSaleReturnReasons: data.afterSaleReturnReasons, + ); + if (setting == null || setting != storageData) { + await AppSettingTool.setCanteenExtraPriceConfig(storageData); + setting = storageData; + } + saleReasons.value = setting.afterSaleReturnReasons?.split(",") ?? []; + } catch (e, stack) { + logger.e("更新支付设置失败error:|$e|stack:|$stack|"); + } + } } diff --git a/lib/pages/order_history/widgets/refund_dialog.dart b/lib/pages/order_history/widgets/refund_dialog.dart new file mode 100644 index 0000000..f50be79 --- /dev/null +++ b/lib/pages/order_history/widgets/refund_dialog.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:forui/forui.dart'; +import 'package:get/get.dart'; +import 'package:ducafe_ui_core/ducafe_ui_core.dart'; + +import 'package:pj_supermarket_cloud/common/index.dart'; + +Future refundDialog( + BuildContext context, { + required String title, + required RxList saleReasons, + required VoidCallback doCancel, + required Function(String) doSubmit, +}) async { + String value = saleReasons.first; + final typeC = FRadioSelectGroupController(value: value); + + final theme = FTheme.of(context); + final width = context.width; + final height = context.height; + showDialog( + context: context, + builder: (BuildContext _) { + return FDialog( + direction: Axis.vertical, + title: Text(title, style: theme.typography.lg), + body: [ + Obx( + () => FSelectGroup( + enabled: false, + controller: typeC, + style: theme.selectGroupStyle.copyWith( + labelLayoutStyle: + theme.selectGroupStyle.labelLayoutStyle.copyWith( + childPadding: EdgeInsets.symmetric( + vertical: 10.h, + ), + ), + radioStyle: theme.selectGroupStyle.radioStyle.copyWith( + padding: EdgeInsets.symmetric( + vertical: 10.h, + ), + ), + ), + items: saleReasons + .map>( + (v) => FSelectGroupItem.radio( + value: v, + label: Text( + v, + style: theme.typography.xl, + ), + ), + ) + .toList(), + ), + ), + ].toColumn().width(width * 0.5).height(height * 0.6), + actions: [ + [ + FButton( + label: Text( + "确认退款", + style: theme.typography.xl.copyWith( + color: theme.colorScheme.secondary, + ), + ), + onPress: () { + doSubmit.call(value); + }, + ).flexible(flex: 1), + SizedBox(width: 20.w), + FButton( + style: FButtonStyle.destructive, + label: Text( + "取消", + style: theme.typography.xl.copyWith( + color: theme.colorScheme.secondary, + ), + ), + onPress: () { + doCancel.call(); + }, + ).flexible(flex: 1), + ].toRow(), + ], + ); + }, + ); +}