feat:餐段设置

This commit is contained in:
dzc committed 2026-09-07 12:53:05 +08:00
1 parent 67950343a7
commit 07a3141934
14 files changed
+285 -18

No files matched your search

@@ -13,6 +13,7 @@ import 'package:pj_supermarket_cloud/common/index.dart';
/// 收银、预订和设置页面继续使用原有的图标与强调色样式。
/// [checkConfiguredTime] 开启后会在页面初始化完成时校验当前餐段;[ready] 用于等待调用方恢复自身状态。
/// [currentHourTypeLoader] 允许调用方提供当前配置餐段读取器,未提供时读取本机餐段配置。
/// [allowManualChange] 关闭后禁止人工切换餐段:选择器只读,且与餐段配置不符时静默切换为配置餐段。
Widget appRadioHourTypeDialog(
BuildContext context,
FRadioSelectGroupController<String> controller, {
@@ -21,6 +22,7 @@ Widget appRadioHourTypeDialog(
bool enabled = true,
bool compact = false,
bool checkConfiguredTime = false,
bool allowManualChange = true,
Future<void>? ready,
Future<ProductHourType?> Function()? currentHourTypeLoader,
}) {
@@ -28,13 +30,14 @@ Widget appRadioHourTypeDialog(
return _MealPeriodSelectionGuard(
controller: controller,
ready: ready,
allowManualChange: allowManualChange,
currentHourTypeLoader: currentHourTypeLoader,
selectorBuilder: (context, candidateController) => _buildHourTypeSelector(
context,
candidateController,
key: key,
title: title,
enabled: enabled,
enabled: enabled && allowManualChange,
compact: compact,
),
);
@@ -44,7 +47,7 @@ Widget appRadioHourTypeDialog(
controller,
key: key,
title: title,
enabled: enabled,
enabled: enabled && allowManualChange,
compact: compact,
);
}
@@ -191,6 +194,7 @@ class _MealPeriodSelectionGuard extends StatefulWidget {
required this.controller,
required this.selectorBuilder,
this.ready,
this.allowManualChange = true,
this.currentHourTypeLoader,
});
@@ -200,6 +204,9 @@ class _MealPeriodSelectionGuard extends StatefulWidget {
/// 页面业务初始化信号;为空表示无需等待额外初始化。
final Future<void>? ready;
/// 是否允许人工切换餐段;关闭后忽略人工候选并静默跟随餐段配置。
final bool allowManualChange;
/// 当前时间命中餐段的读取器;测试可注入固定结果。
final Future<ProductHourType?> Function()? currentHourTypeLoader;
@@ -258,7 +265,8 @@ class _MealPeriodSelectionGuardState extends State<_MealPeriodSelectionGuard> {
_selectionRevision++;
_scheduleCheck();
} else if (oldWidget.ready != widget.ready ||
oldWidget.currentHourTypeLoader != widget.currentHourTypeLoader) {
oldWidget.currentHourTypeLoader != widget.currentHourTypeLoader ||
oldWidget.allowManualChange != widget.allowManualChange) {
_scheduleCheck();
}
}
@@ -289,7 +297,9 @@ class _MealPeriodSelectionGuardState extends State<_MealPeriodSelectionGuard> {
if (_syncingCandidate) return;
final candidate = ProductHourType.values.fromCode(values.firstOrNull);
final committedCode = widget.controller.value.firstOrNull;
if (candidate == null ||
// 禁止人工修改时任何候选都不受理,候选显示立即回退为已提交餐段。
if (!widget.allowManualChange ||
candidate == null ||
candidate == ProductHourType.TOTAL ||
candidate.code == committedCode) {
_syncCandidateFromCommitted();
@@ -333,6 +343,9 @@ class _MealPeriodSelectionGuardState extends State<_MealPeriodSelectionGuard> {
}
/// 校验人工候选或当前缓存餐段;人工确认后提交候选,初始化确认后提交配置餐段。
///
/// 禁止人工修改时不弹确认框:与餐段配置不符直接静默切换为配置餐段,
/// 当前时间未命中任何餐段时保留原选择,避免把餐段清空成不可用状态。
Future<void> _checkSelection() async {
if (_checking || !mounted) return;
_checking = true;
@@ -350,6 +363,12 @@ class _MealPeriodSelectionGuardState extends State<_MealPeriodSelectionGuard> {
final configured = await (widget.currentHourTypeLoader?.call() ??
AppSettingTool.getCurrentProductHourType());
if (!mounted || revision != _selectionRevision) return;
if (!widget.allowManualChange) {
if (configured != null && configured != selected) {
_commitSelection(configured);
}
return;
}
if (candidate != null &&
(configured == null || configured == candidate)) {
_commitSelection(candidate);
@@ -1557,7 +1557,7 @@ class _CheckoutCartItem extends StatelessWidget {
}
}
/// 套餐购物车行,默认展示全部组成,并将展开热区与数量步进器分离。
/// 套餐购物车行,默认收起组成明细,并将展开热区与数量步进器分离。
class _CheckoutComboCartItem extends StatefulWidget {
/// 创建一条可由主商品整行切换展开状态的套餐记录。
const _CheckoutComboCartItem({
@@ -1591,8 +1591,8 @@ class _CheckoutComboCartItem extends StatefulWidget {
/// 管理单条套餐的展开状态;状态只属于当前购物车快照条目。
class _CheckoutComboCartItemState extends State<_CheckoutComboCartItem> {
/// 首次打开结算弹框时默认展开,方便收银员直接核对套餐组成。
bool _expanded = true;
/// 首次打开结算弹框时默认收起组成明细,与查询菜单核销弹框的套餐行为一致。
bool _expanded = false;
/// 切换套餐明细;没有组成时不制造无反馈的点击行为。
void _toggleExpanded() {