improve single-code boxing UX: preserve state, fix work order display, add double-vibrate alert
- Keep UI state after boxing completion for operator review instead of auto-reset - Show real work order number instead of hardcoded "本次扫码" in assigned list - Add double-vibration feedback when re-scanning already completed zongpai - Change completed status banner and dot from green to red for clearer warning Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -344,7 +344,19 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
return false;
|
||||
}
|
||||
|
||||
_feedbackService.trigger(FeedbackEvent.scanValid);
|
||||
// 判断该总牌号是否已全部装箱完毕
|
||||
final packedQuantity = result.currentZongpaiBoxes.fold<int>(
|
||||
0,
|
||||
(sum, item) => sum + item.quantity,
|
||||
);
|
||||
final totalQuantity = result.quantity ?? 0;
|
||||
final alreadyCompleted = totalQuantity > 0 && packedQuantity >= totalQuantity;
|
||||
|
||||
_feedbackService.trigger(
|
||||
alreadyCompleted
|
||||
? FeedbackEvent.alreadyCompleted
|
||||
: FeedbackEvent.scanValid,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
_zongpaiNo = zongpai;
|
||||
@@ -686,9 +698,6 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
StatusDotColor.green,
|
||||
const Duration(milliseconds: 1500),
|
||||
);
|
||||
Future.delayed(const Duration(milliseconds: 1500), () {
|
||||
if (mounted) setState(() => _resetState());
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_phase = _Phase.scanned;
|
||||
@@ -1285,7 +1294,7 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
case _Phase.scanned:
|
||||
_statusDot = StatusDotColor.blue;
|
||||
if (_remainingQuantity <= 0) {
|
||||
_statusDot = StatusDotColor.green;
|
||||
_statusDot = StatusDotColor.red;
|
||||
_statusText = '该总排号已全部装箱完毕';
|
||||
return;
|
||||
}
|
||||
@@ -1423,11 +1432,11 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
_remainingQuantity <= 0) {
|
||||
banners.add(
|
||||
_noticeBanner(
|
||||
icon: Icon(Icons.check, size: 14, color: Colors.green.shade800),
|
||||
icon: Icon(Icons.warning, size: 14, color: Colors.red.shade800),
|
||||
text: '${_zongpaiNo!} 已全部装箱完毕,无需操作',
|
||||
background: Colors.green.shade50,
|
||||
foreground: Colors.green.shade800,
|
||||
border: Colors.green.shade100,
|
||||
background: Colors.red.shade50,
|
||||
foreground: Colors.red.shade800,
|
||||
border: Colors.red.shade100,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1762,7 +1771,7 @@ class _BoxingPageState extends State<BoxingPage> with WidgetsBindingObserver {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
'本次扫码',
|
||||
_workOrderNo ?? '--',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Colors.grey.shade500,
|
||||
|
||||
@@ -10,6 +10,7 @@ enum FeedbackEvent {
|
||||
duplicateError, // Duplicate (shelf) → alert loop + continuous vibrate
|
||||
networkError, // Network error → failure sound + short vibrate
|
||||
duplicateBoxNo, // Duplicate box no → failure sound + short vibrate
|
||||
alreadyCompleted, // Zongpai already boxed → beep + double vibrate
|
||||
modeSwitch, // Mode toggle → beep only
|
||||
paichanSwitch, // Paichan changed → beep + short vibrate
|
||||
}
|
||||
@@ -55,6 +56,10 @@ class FeedbackService {
|
||||
_soundService.playFailure();
|
||||
_vibrateShort();
|
||||
|
||||
case FeedbackEvent.alreadyCompleted:
|
||||
_soundService.playBeep();
|
||||
_vibrateDouble();
|
||||
|
||||
case FeedbackEvent.modeSwitch:
|
||||
_soundService.playBeep();
|
||||
|
||||
@@ -82,6 +87,11 @@ class FeedbackService {
|
||||
Vibration.vibrate(pattern: [0, 300, 100, 300, 100, 300]);
|
||||
}
|
||||
|
||||
/// Two short bursts to signal an already-completed item.
|
||||
void _vibrateDouble() {
|
||||
Vibration.vibrate(pattern: [0, 200, 100, 200]);
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _soundService.dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user