diff --git a/client/lib/screens/stock_in/stock_in_list_screen.dart b/client/lib/screens/stock_in/stock_in_list_screen.dart index 5f6f05f..14ad77a 100644 --- a/client/lib/screens/stock_in/stock_in_list_screen.dart +++ b/client/lib/screens/stock_in/stock_in_list_screen.dart @@ -963,23 +963,27 @@ class _StockInListScreenState extends ConsumerState { } // 点击行/眼睛 → 右侧详情抽屉(对齐原型 openDetail)。 + // 抽屉内按钮不收抽屉(2026-07-04 拍板):操作完成后原地重拉单据刷新内容, + // 仅点遮罩/X/「修改·删除」这类离开语义才关闭。 Future _showDetail(BuildContext context, int orderId) async { await showOrderDetailDrawer( context, - builder: (ctx) => FutureBuilder( - future: ref.read(stockInRepositoryProvider).get(orderId), - builder: (c, snap) { - if (snap.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } - if (snap.hasError || !snap.hasData) { - return Center( - child: Text('暂无数据,网络不可用', - style: TextStyle(color: context.tokens.muted)), - ); - } - return _buildDetailDrawer(snap.data!); - }, + builder: (ctx) => StatefulBuilder( + builder: (sctx, setSheet) => FutureBuilder( + future: ref.read(stockInRepositoryProvider).get(orderId), + builder: (c, snap) { + if (snap.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (snap.hasError || !snap.hasData) { + return Center( + child: Text('暂无数据,网络不可用', + style: TextStyle(color: context.tokens.muted)), + ); + } + return _buildDetailDrawer(snap.data!, () => setSheet(() {})); + }, + ), ), ); } @@ -991,7 +995,7 @@ class _StockInListScreenState extends ConsumerState { static String _fmtQty(double q) => q == q.roundToDouble() ? q.toStringAsFixed(0) : q.toString(); - Widget _buildDetailDrawer(StockInOrder o) { + Widget _buildDetailDrawer(StockInOrder o, VoidCallback refresh) { final t = context.tokens; final rb = returnStateBadge(context, o.returnState); return OrderDetailDrawer( @@ -1031,11 +1035,12 @@ class _StockInListScreenState extends ConsumerState { totalText: o.costTotal != null ? _money.format(o.costTotal) : '—', priceLabel: '进价(单瓶)', amountLabel: '总价', - actionGroups: _detailActionGroups(o), + actionGroups: _detailActionGroups(o, refresh), ); } - List _detailActionGroups(StockInOrder o) { + List _detailActionGroups( + StockInOrder o, VoidCallback refresh) { final readonly = WriteGuard.isReadonly(ref); final isAdmin = ref.read(isAdminProvider); final canWithdraw = isAdmin || @@ -1051,6 +1056,7 @@ class _StockInListScreenState extends ConsumerState { if (!readonly) { switch (o.status) { case 'draft': + // 修改/删除是离开语义:收抽屉再走 audit.add(b('修改', () { close(); context.go('/stock-in/edit/${o.id}'); @@ -1059,36 +1065,36 @@ class _StockInListScreenState extends ConsumerState { close(); _confirmDelete(context, o); }, v: DsBtnVariant.danger)); - audit.add(b('提交', () { - close(); - _confirmSubmit(context, o); + audit.add(b('提交', () async { + await _confirmSubmit(context, o); + refresh(); }, v: DsBtnVariant.primary)); break; case 'pending': - audit.add(b('通过', () { - close(); - _confirmApprove(context, o); + audit.add(b('通过', () async { + await _confirmApprove(context, o); + refresh(); }, v: DsBtnVariant.primary)); - audit.add(b('拒绝', () { - close(); - _confirmReject(context, o); + audit.add(b('拒绝', () async { + await _confirmReject(context, o); + refresh(); }, v: DsBtnVariant.danger)); if (canWithdraw) { - audit.add(b('撤回', () { - close(); - _confirmWithdraw(context, o); + audit.add(b('撤回', () async { + await _confirmWithdraw(context, o); + refresh(); })); } break; case 'approved': - audit.add(b('结清', () { - close(); - _confirmSettle(context, o.id, 'stock_in'); + audit.add(b('结清', () async { + await _confirmSettle(context, o.id, 'stock_in'); + refresh(); })); if (isAdmin) { - audit.add(b('退单', () { - close(); - _confirmReturn(context, o); + audit.add(b('退单', () async { + await _confirmReturn(context, o); + refresh(); }, v: DsBtnVariant.danger)); } break; @@ -1099,9 +1105,9 @@ class _StockInListScreenState extends ConsumerState { final pending = o.items.where((it) => it.costPrice == 0).length; if (o.status == 'approved' && isAdmin && pending > 0) { groups.add(DrawerActionGroup('成本 · $pending 项待定价', [ - b('确认进价', () { - close(); - _confirmCost(o); + b('确认进价', () async { + await _confirmCost(o); + refresh(); }, v: DsBtnVariant.primary), ])); } @@ -1109,12 +1115,8 @@ class _StockInListScreenState extends ConsumerState { // 窄屏详情不出打印入口(移动端无打印——用户拍板)。 if (!context.isMobile) { groups.add(DrawerActionGroup('打印', [ - b('打印标签', () { - close(); - _printLabels(o); - }), + b('打印标签', () => _printLabels(o)), b('打印单据', () async { - close(); final order = await ref.read(stockInRepositoryProvider).get(o.id); if (mounted) await showStockInOrderPrint(context, ref, order); }), diff --git a/client/lib/screens/stock_out/stock_out_list_screen.dart b/client/lib/screens/stock_out/stock_out_list_screen.dart index d9d6734..a64d72f 100644 --- a/client/lib/screens/stock_out/stock_out_list_screen.dart +++ b/client/lib/screens/stock_out/stock_out_list_screen.dart @@ -1035,23 +1035,27 @@ class _StockOutListScreenState extends ConsumerState { } // 点击行/眼睛 → 右侧详情抽屉(对齐原型 openDetail)。 + // 抽屉内按钮不收抽屉(2026-07-04 拍板):操作完成后原地重拉单据刷新内容, + // 仅点遮罩/X/「修改·删除」这类离开语义才关闭。 Future _showDetail(BuildContext context, int orderId) async { await showOrderDetailDrawer( context, - builder: (ctx) => FutureBuilder( - future: ref.read(stockOutRepositoryProvider).get(orderId), - builder: (c, snap) { - if (snap.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } - if (snap.hasError || !snap.hasData) { - return Center( - child: Text('暂无数据,网络不可用', - style: TextStyle(color: context.tokens.muted)), - ); - } - return _buildDetailDrawer(snap.data!); - }, + builder: (ctx) => StatefulBuilder( + builder: (sctx, setSheet) => FutureBuilder( + future: ref.read(stockOutRepositoryProvider).get(orderId), + builder: (c, snap) { + if (snap.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (snap.hasError || !snap.hasData) { + return Center( + child: Text('暂无数据,网络不可用', + style: TextStyle(color: context.tokens.muted)), + ); + } + return _buildDetailDrawer(snap.data!, () => setSheet(() {})); + }, + ), ), ); } @@ -1063,7 +1067,7 @@ class _StockOutListScreenState extends ConsumerState { static String _fmtQty(double q) => q == q.roundToDouble() ? q.toStringAsFixed(0) : q.toString(); - Widget _buildDetailDrawer(StockOutOrder o) { + Widget _buildDetailDrawer(StockOutOrder o, VoidCallback refresh) { final t = context.tokens; final rb = returnStateBadge(context, o.returnState); return OrderDetailDrawer( @@ -1112,11 +1116,12 @@ class _StockOutListScreenState extends ConsumerState { ref.read(isAdminProvider) ? _money.format(o.profitTotal) : null, priceLabel: '售价', amountLabel: '小计', - actionGroups: _detailActionGroups(o), + actionGroups: _detailActionGroups(o, refresh), ); } - List _detailActionGroups(StockOutOrder o) { + List _detailActionGroups( + StockOutOrder o, VoidCallback refresh) { final readonly = WriteGuard.isReadonly(ref); final isAdmin = ref.read(isAdminProvider); final isMine = @@ -1131,6 +1136,7 @@ class _StockOutListScreenState extends ConsumerState { if (!readonly) { switch (o.status) { case 'draft': + // 修改/删除是离开语义:收抽屉再走 audit.add(b('修改', () { close(); context.go('/stock-out/edit/${o.id}'); @@ -1139,36 +1145,36 @@ class _StockOutListScreenState extends ConsumerState { close(); _confirmDelete(context, o); }, v: DsBtnVariant.danger)); - audit.add(b('提交', () { - close(); - _confirmSubmit(context, o); + audit.add(b('提交', () async { + await _confirmSubmit(context, o); + refresh(); }, v: DsBtnVariant.primary)); break; case 'pending': - audit.add(b('通过', () { - close(); - _confirmApprove(context, o); + audit.add(b('通过', () async { + await _confirmApprove(context, o); + refresh(); }, v: DsBtnVariant.primary)); - audit.add(b('拒绝', () { - close(); - _confirmReject(context, o); + audit.add(b('拒绝', () async { + await _confirmReject(context, o); + refresh(); }, v: DsBtnVariant.danger)); if (isAdmin || isMine) { - audit.add(b('撤回', () { - close(); - _confirmWithdraw(context, o); + audit.add(b('撤回', () async { + await _confirmWithdraw(context, o); + refresh(); })); } break; case 'approved': - audit.add(b('结清', () { - close(); - _confirmSettle(context, o.id, 'stock_out'); + audit.add(b('结清', () async { + await _confirmSettle(context, o.id, 'stock_out'); + refresh(); })); if (isAdmin || isMine) { - audit.add(b('退单', () { - close(); - _confirmReturn(context, o); + audit.add(b('退单', () async { + await _confirmReturn(context, o); + refresh(); }, v: DsBtnVariant.danger)); } break; @@ -1179,9 +1185,9 @@ class _StockOutListScreenState extends ConsumerState { final pending = o.items.where((it) => it.salePrice <= 0).length; if (o.status == 'approved' && pending > 0 && !readonly) { groups.add(DrawerActionGroup('售价 · $pending 项待定价', [ - b('确认售价', () { - close(); - _confirmSale(o); + b('确认售价', () async { + await _confirmSale(o); + refresh(); }, v: DsBtnVariant.primary), ])); } @@ -1189,12 +1195,8 @@ class _StockOutListScreenState extends ConsumerState { // 窄屏详情不出打印入口(移动端无打印——用户拍板)。 if (!context.isMobile) { groups.add(DrawerActionGroup('打印', [ - b('打印标签', () { - close(); - _printLabels(o); - }), + b('打印标签', () => _printLabels(o)), b('打印单据', () async { - close(); final order = await ref.read(stockOutRepositoryProvider).get(o.id); if (mounted) await showStockOutOrderPrint(context, ref, order); }), diff --git a/client/lib/widgets/finance_partner_drawer.dart b/client/lib/widgets/finance_partner_drawer.dart index dc27e60..18281a3 100644 --- a/client/lib/widgets/finance_partner_drawer.dart +++ b/client/lib/widgets/finance_partner_drawer.dart @@ -181,16 +181,22 @@ class _FinancePartnerDrawer extends ConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - DsButton('登记收款', small: true, onPressed: () { - Navigator.of(context).pop(); - showFinanceEntryDialog(context, + // 抽屉内按钮不收抽屉(2026-07-04 拍板):登记弹窗叠在抽屉之上, + // 保存后失效流水 provider → 抽屉内近期流水原地刷新 + DsButton('登记收款', small: true, onPressed: () async { + await showFinanceEntryDialog(context, type: 'receipt', partnerId: row.partnerId); + if (row.partnerId != null) { + ref.invalidate(_partnerFlowsProvider(row.partnerId!)); + } }), const SizedBox(width: 10), - DsButton('登记付款', small: true, onPressed: () { - Navigator.of(context).pop(); - showFinanceEntryDialog(context, + DsButton('登记付款', small: true, onPressed: () async { + await showFinanceEntryDialog(context, type: 'payment', partnerId: row.partnerId); + if (row.partnerId != null) { + ref.invalidate(_partnerFlowsProvider(row.partnerId!)); + } }), ], ), diff --git a/client/lib/widgets/partner_detail_drawer.dart b/client/lib/widgets/partner_detail_drawer.dart index 0db31b6..c85ce1c 100644 --- a/client/lib/widgets/partner_detail_drawer.dart +++ b/client/lib/widgets/partner_detail_drawer.dart @@ -194,10 +194,8 @@ class _PartnerDetailDrawer extends ConsumerWidget { const SizedBox(width: 10), if (onEdit != null) WriteGuard( - child: DsButton('编辑', small: true, onPressed: () { - Navigator.of(context).pop(); - onEdit!(); - }), + // 抽屉内按钮不收抽屉(2026-07-04 拍板):编辑弹窗叠在抽屉之上 + child: DsButton('编辑', small: true, onPressed: onEdit), ), ], ), diff --git a/client/lib/widgets/product_editor_drawer.dart b/client/lib/widgets/product_editor_drawer.dart index 899778e..b06de6a 100644 --- a/client/lib/widgets/product_editor_drawer.dart +++ b/client/lib/widgets/product_editor_drawer.dart @@ -623,7 +623,7 @@ class _ProductEditorDrawerState extends ConsumerState<_ProductEditorDrawer> { if (_introDocId != null) 'description_doc_id': _introDocId, }); if (!mounted) return; - Navigator.of(context).pop(); + // 抽屉内按钮不收抽屉(2026-07-04 拍板):保存后停留,可继续编辑 showDsToast(context, '商品介绍已保存 ✓'); } catch (e) { if (mounted) { diff --git a/client/lib/widgets/wheel_date_picker.dart b/client/lib/widgets/wheel_date_picker.dart index c7e86bb..c915c61 100644 --- a/client/lib/widgets/wheel_date_picker.dart +++ b/client/lib/widgets/wheel_date_picker.dart @@ -427,9 +427,16 @@ class _DatePaneState extends State<_DatePane> { focusNode: _focus, keyboardType: TextInputType.datetime, textAlign: TextAlign.center, - textAlignVertical: TextAlignVertical.center, + // 强制 strut 统一行盒(等宽字体 ascent/descent 不对称会让文字 + // 视觉偏离垂直中心;height:1 行高=字号,Center 精确居中) + strutStyle: const StrutStyle( + fontSize: AppDims.fsBody, + height: 1.0, + forceStrutHeight: true, + ), style: TextStyle( fontSize: AppDims.fsBody, + height: 1.0, color: t.text, fontFamily: AppFonts.mono, fontFamilyFallback: AppFonts.monoFallback),