refactor: split registration page into focused parts
This commit is contained in:
21
lib/pages/registration/parts/registration_mode_part.dart
Normal file
21
lib/pages/registration/parts/registration_mode_part.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
// ignore_for_file: invalid_use_of_protected_member
|
||||
|
||||
part of '../../registration_page.dart';
|
||||
|
||||
extension _RegistrationModePart on _RegistrationPageState {
|
||||
void _cycleMode() {
|
||||
_feedbackService.trigger(FeedbackEvent.modeSwitch);
|
||||
setState(() {
|
||||
switch (_mode) {
|
||||
case RegistrationMode.singleCode:
|
||||
_mode = RegistrationMode.multiCode;
|
||||
case RegistrationMode.multiCode:
|
||||
_mode = RegistrationMode.singleCode;
|
||||
// 切换到单码时,只保留最后一个总排号
|
||||
if (_zongpaiNos.length > 1) {
|
||||
_zongpaiNos.removeRange(0, _zongpaiNos.length - 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
88
lib/pages/registration/parts/registration_overview_part.dart
Normal file
88
lib/pages/registration/parts/registration_overview_part.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
// ignore_for_file: invalid_use_of_protected_member
|
||||
|
||||
part of '../../registration_page.dart';
|
||||
|
||||
extension _RegistrationOverviewPart on _RegistrationPageState {
|
||||
/// Find all scanned items that are already on shelf.
|
||||
List<PaichaOverviewItem> _findOnShelfItemsInScanned() {
|
||||
return registration_calculations.findOnShelfItemsInScanned(
|
||||
overview: _overview,
|
||||
zongpaiNos: _zongpaiNos,
|
||||
);
|
||||
}
|
||||
|
||||
/// Find all scanned items that are already transferred.
|
||||
List<PaichaOverviewItem> _findTransferredItemsInScanned() {
|
||||
return registration_calculations.findTransferredItemsInScanned(
|
||||
overview: _overview,
|
||||
zongpaiNos: _zongpaiNos,
|
||||
);
|
||||
}
|
||||
|
||||
/// Whether any scanned item already has a location binding (on_shelf or transferred).
|
||||
bool _hasAnyLocatedInScanned() {
|
||||
return registration_calculations.hasAnyLocatedInScanned(
|
||||
overview: _overview,
|
||||
zongpaiNos: _zongpaiNos,
|
||||
);
|
||||
}
|
||||
|
||||
Future<String?> _baseUrl() async {
|
||||
final configService = AppConfigService();
|
||||
final baseUrl = await configService.getString('api_url') ?? '';
|
||||
if (baseUrl.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
Future<void> _loadOverview(String zongpaiNo, {bool force = false}) async {
|
||||
if (!force && _overviewZongpaiNo == zongpaiNo && _overview != null) {
|
||||
return;
|
||||
}
|
||||
final requestId = ++_overviewRequestId;
|
||||
setState(() {
|
||||
_overviewZongpaiNo = zongpaiNo;
|
||||
_overviewLoading = true;
|
||||
_overviewNotFound = false;
|
||||
_overviewError = null;
|
||||
});
|
||||
|
||||
final baseUrl = await _baseUrl();
|
||||
if (!mounted || requestId != _overviewRequestId) return;
|
||||
if (baseUrl == null) {
|
||||
setState(() {
|
||||
_overviewLoading = false;
|
||||
_overviewError = '未配置 API 地址,请前往设置';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final result = await _apiService.fetchPaichaOverview(
|
||||
baseUrl: baseUrl,
|
||||
zongpaiNo: zongpaiNo,
|
||||
);
|
||||
if (!mounted || requestId != _overviewRequestId) return;
|
||||
|
||||
setState(() {
|
||||
_overviewLoading = false;
|
||||
if (result.success) {
|
||||
_overview = result;
|
||||
_overviewNotFound = false;
|
||||
_overviewError = null;
|
||||
} else if (result.notFound) {
|
||||
_overview = null;
|
||||
_overviewNotFound = true;
|
||||
_overviewError = null;
|
||||
} else {
|
||||
_overviewError = result.errorMessage ?? '加载失败,点击重试';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _refreshCurrentOverview() async {
|
||||
final zongpaiNo = _overviewZongpaiNo;
|
||||
if (zongpaiNo == null) return;
|
||||
await _loadOverview(zongpaiNo, force: true);
|
||||
}
|
||||
}
|
||||
126
lib/pages/registration/parts/registration_scan_part.dart
Normal file
126
lib/pages/registration/parts/registration_scan_part.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
// ignore_for_file: invalid_use_of_protected_member
|
||||
|
||||
part of '../../registration_page.dart';
|
||||
|
||||
extension _RegistrationScanPart on _RegistrationPageState {
|
||||
void _startScanListening() {
|
||||
_scanSubscription ??= _scannerService.scanResults.listen(_onScan);
|
||||
}
|
||||
|
||||
Future<void> _stopScanListening() async {
|
||||
final subscription = _scanSubscription;
|
||||
_scanSubscription = null;
|
||||
await subscription?.cancel();
|
||||
}
|
||||
|
||||
void _restartScanListening() {
|
||||
_scanSubscription?.cancel();
|
||||
_scanSubscription = null;
|
||||
_startScanListening();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
_focusNode.requestFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _onKeyEvent(KeyEvent event) {
|
||||
if (event is! KeyDownEvent) return;
|
||||
if (_isLockToggleKey(event)) {
|
||||
_cycleMode();
|
||||
return;
|
||||
}
|
||||
if (event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
_submit();
|
||||
}
|
||||
}
|
||||
|
||||
bool _isLockToggleKey(KeyEvent event) {
|
||||
final key = event.logicalKey;
|
||||
return key == LogicalKeyboardKey.select ||
|
||||
key == LogicalKeyboardKey.gameButtonRight1;
|
||||
}
|
||||
|
||||
void _onScan(ScanResult result) {
|
||||
final parsed = CodeParser.parse(result.barcode);
|
||||
switch (parsed.type) {
|
||||
case CodeType.zongpaiNo:
|
||||
_handleZongpaiScan(parsed.value);
|
||||
case CodeType.locationNormal:
|
||||
case CodeType.locationTransit:
|
||||
_handleLocationScan(parsed.value, parsed.type);
|
||||
case CodeType.invalid:
|
||||
_feedbackService.trigger(FeedbackEvent.scanInvalid);
|
||||
_showStatusOverride(
|
||||
'无效码:${result.barcode}',
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleLocationScan(String locationCode, CodeType locationType) {
|
||||
// In singleCode mode or no existing data, switch directly
|
||||
if (_mode == RegistrationMode.singleCode || _zongpaiNos.isEmpty) {
|
||||
_feedbackService.trigger(FeedbackEvent.scanValid);
|
||||
setState(() {
|
||||
_locationCode = locationCode;
|
||||
_locationType = locationType;
|
||||
_clearStatusOverride();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// In multiCode mode with existing data, confirm before switching
|
||||
_showLocationSwitchDialog(locationCode, locationType);
|
||||
}
|
||||
|
||||
void _handleZongpaiScan(String zongpaiNo) {
|
||||
// If cross-paicha dialog is showing, just vibrate and discard
|
||||
if (_crossPaichaPending) {
|
||||
_triggerDoubleVibration();
|
||||
return;
|
||||
}
|
||||
|
||||
// In multiCode mode with existing data, check for cross-paicha scan
|
||||
if (_mode == RegistrationMode.multiCode &&
|
||||
_zongpaiNos.isNotEmpty &&
|
||||
_overview?.success == true &&
|
||||
!_overview!.items.any((item) => item.zongpaiNo == zongpaiNo)) {
|
||||
_crossPaichaPending = true;
|
||||
_triggerDoubleVibration();
|
||||
_showCrossPaichaDialog(zongpaiNo);
|
||||
return;
|
||||
}
|
||||
|
||||
final shouldRefresh = _overviewZongpaiNo != zongpaiNo;
|
||||
_feedbackService.trigger(FeedbackEvent.scanValid);
|
||||
setState(() {
|
||||
if (_mode == RegistrationMode.multiCode) {
|
||||
if (!_zongpaiNos.contains(zongpaiNo)) {
|
||||
_zongpaiNos.add(zongpaiNo);
|
||||
}
|
||||
} else {
|
||||
if (_zongpaiNos.isEmpty) {
|
||||
_zongpaiNos.add(zongpaiNo);
|
||||
} else {
|
||||
_zongpaiNos[0] = zongpaiNo;
|
||||
}
|
||||
}
|
||||
_clearStatusOverride();
|
||||
});
|
||||
if (shouldRefresh) {
|
||||
_loadOverview(zongpaiNo);
|
||||
}
|
||||
}
|
||||
|
||||
void _triggerDoubleVibration() {
|
||||
Vibration.vibrate(pattern: [0, 200, 100, 200]);
|
||||
}
|
||||
|
||||
void _removeZongpai(String zongpaiNo) {
|
||||
setState(() {
|
||||
_zongpaiNos.remove(zongpaiNo);
|
||||
});
|
||||
}
|
||||
}
|
||||
55
lib/pages/registration/parts/registration_status_part.dart
Normal file
55
lib/pages/registration/parts/registration_status_part.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
// ignore_for_file: invalid_use_of_protected_member
|
||||
|
||||
part of '../../registration_page.dart';
|
||||
|
||||
extension _RegistrationStatusPart on _RegistrationPageState {
|
||||
void _clearStatusOverride() {
|
||||
_statusOverrideText = null;
|
||||
_statusOverrideDot = null;
|
||||
}
|
||||
|
||||
void _showStatusOverride(String text, StatusDotColor dot, Duration duration) {
|
||||
setState(() {
|
||||
_statusOverrideText = text;
|
||||
_statusOverrideDot = dot;
|
||||
});
|
||||
Future.delayed(duration, () {
|
||||
if (mounted) setState(() => _clearStatusOverride());
|
||||
});
|
||||
}
|
||||
|
||||
void _updateBaseStatus() {
|
||||
if (_isSubmitting) {
|
||||
_statusDot = StatusDotColor.orange;
|
||||
_statusText = '正在提交…';
|
||||
return;
|
||||
}
|
||||
if (_mode == RegistrationMode.multiCode &&
|
||||
_locationCode != null &&
|
||||
_zongpaiNos.isEmpty) {
|
||||
_statusDot = StatusDotColor.blue;
|
||||
_statusText = '多码上架模式,请扫描下一张执行卡';
|
||||
return;
|
||||
}
|
||||
final hasZongpai = _zongpaiNos.isNotEmpty;
|
||||
final hasLocation = _locationCode != null;
|
||||
if (hasZongpai && hasLocation) {
|
||||
_statusDot = StatusDotColor.blue;
|
||||
_statusText = '请确认信息并提交';
|
||||
} else if (hasZongpai) {
|
||||
_statusDot = StatusDotColor.blue;
|
||||
_statusText = '请扫描目标货位号';
|
||||
} else if (hasLocation) {
|
||||
_statusDot = StatusDotColor.blue;
|
||||
_statusText = '请扫描执行卡';
|
||||
} else {
|
||||
_statusDot = StatusDotColor.blue;
|
||||
_statusText = '等待扫描总排号或货位号…';
|
||||
}
|
||||
}
|
||||
|
||||
bool get _canSubmit =>
|
||||
_zongpaiNos.isNotEmpty && _locationCode != null && !_isSubmitting;
|
||||
|
||||
bool get _isTransitTarget => isTransitTarget(_locationType, _locationCode);
|
||||
}
|
||||
317
lib/pages/registration/parts/registration_submit_part.dart
Normal file
317
lib/pages/registration/parts/registration_submit_part.dart
Normal file
@@ -0,0 +1,317 @@
|
||||
// ignore_for_file: invalid_use_of_protected_member
|
||||
|
||||
part of '../../registration_page.dart';
|
||||
|
||||
extension _RegistrationSubmitPart on _RegistrationPageState {
|
||||
Future<void> _submit() async {
|
||||
if (!_canSubmit) return;
|
||||
|
||||
final baseUrl = await _baseUrl();
|
||||
if (baseUrl == null) {
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showStatusOverride(
|
||||
'未配置 API 地址,请前往设置',
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() => _isSubmitting = true);
|
||||
|
||||
// For transit target: block if any scanned item already has a location
|
||||
if (_isTransitTarget) {
|
||||
if (_hasAnyLocatedInScanned()) {
|
||||
final onShelfItems = _findOnShelfItemsInScanned();
|
||||
final transferredItems = _findTransferredItemsInScanned();
|
||||
setState(() => _isSubmitting = false);
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showLocationConflictDialog(
|
||||
onShelfItems: onShelfItems,
|
||||
transferredItems: transferredItems,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (_mode == RegistrationMode.multiCode && _zongpaiNos.length > 1) {
|
||||
if (_isTransitTarget && !await _ensureBatchSamePaicha(baseUrl)) {
|
||||
if (!mounted) return;
|
||||
setState(() => _isSubmitting = false);
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showStatusOverride(
|
||||
batchPaichaMismatchMessage,
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Pre-check: block entire batch if any item already has a location binding
|
||||
if (!_isTransitTarget) {
|
||||
final onShelfItems = _findOnShelfItemsInScanned();
|
||||
final transferredItems = _findTransferredItemsInScanned();
|
||||
if (onShelfItems.isNotEmpty || transferredItems.isNotEmpty) {
|
||||
setState(() => _isSubmitting = false);
|
||||
_feedbackService.trigger(FeedbackEvent.duplicateError);
|
||||
_showLocationConflictDialog(
|
||||
onShelfItems: onShelfItems,
|
||||
transferredItems: transferredItems,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
await _submitBatch(baseUrl);
|
||||
} else {
|
||||
await _submitOne(baseUrl, _zongpaiNos.first);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _ensureBatchSamePaicha(String baseUrl) async {
|
||||
final paichaByCode = <String, String>{};
|
||||
final cachedOverview = _overview;
|
||||
if (cachedOverview?.success == true && cachedOverview!.paichaNo != null) {
|
||||
for (final item in cachedOverview.items) {
|
||||
paichaByCode[item.zongpaiNo] = cachedOverview.paichaNo!;
|
||||
}
|
||||
}
|
||||
|
||||
for (final zongpaiNo in _zongpaiNos) {
|
||||
if (paichaByCode.containsKey(zongpaiNo)) continue;
|
||||
final result = await _apiService.fetchPaichaOverview(
|
||||
baseUrl: baseUrl,
|
||||
zongpaiNo: zongpaiNo,
|
||||
);
|
||||
if (!result.success || result.paichaNo == null) {
|
||||
return false;
|
||||
}
|
||||
for (final item in result.items) {
|
||||
paichaByCode[item.zongpaiNo] = result.paichaNo!;
|
||||
}
|
||||
}
|
||||
|
||||
return allSamePaicha(_zongpaiNos.map((code) => paichaByCode[code]));
|
||||
}
|
||||
|
||||
Future<void> _submitOne(String baseUrl, String zongpaiNo) async {
|
||||
final result = await _apiService.registerLocation(
|
||||
baseUrl: baseUrl,
|
||||
zongpaiNo: zongpaiNo,
|
||||
locationCode: _locationCode!,
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() => _isSubmitting = false);
|
||||
|
||||
if (result.success) {
|
||||
_feedbackService.trigger(FeedbackEvent.submitSuccess);
|
||||
if (_isTransitTarget) {
|
||||
setState(() => _isSubmitting = false);
|
||||
await _navigateToBoxing(
|
||||
mode: BoxingMode.singleCode,
|
||||
codes: [zongpaiNo],
|
||||
codesToClear: [zongpaiNo],
|
||||
clearLocation: _mode == RegistrationMode.singleCode,
|
||||
);
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_zongpaiNos.remove(zongpaiNo);
|
||||
if (_mode == RegistrationMode.singleCode) {
|
||||
_locationCode = null;
|
||||
_locationType = null;
|
||||
}
|
||||
});
|
||||
final msg = result.isOffShelfSuccess
|
||||
? '下架成功'
|
||||
: (_mode == RegistrationMode.multiCode ? '多码上架模式,请扫描下一张执行卡' : '上架成功');
|
||||
_showStatusOverride(
|
||||
msg,
|
||||
StatusDotColor.green,
|
||||
const Duration(milliseconds: 1500),
|
||||
);
|
||||
await _refreshCurrentOverview();
|
||||
} else if (result.isDuplicate) {
|
||||
_feedbackService.trigger(FeedbackEvent.duplicateError);
|
||||
_showDuplicateDialog(zongpaiNo, result.duplicateInfo);
|
||||
} else if (result.isAlreadyOffShelf) {
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showStatusOverride(
|
||||
result.errorMessage ?? '该总排号已下架至转运区域,不可重新上架',
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
} else {
|
||||
final isNetwork = result.errorMessage == '网络异常,请检查网络连接';
|
||||
_feedbackService.trigger(
|
||||
isNetwork ? FeedbackEvent.networkError : FeedbackEvent.submitFailure,
|
||||
);
|
||||
_showStatusOverride(
|
||||
result.errorMessage ?? '提交失败',
|
||||
isNetwork ? StatusDotColor.yellow : StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _submitBatch(String baseUrl) async {
|
||||
int successCount = 0;
|
||||
int offShelfCount = 0;
|
||||
final failed = <String>[];
|
||||
final toRemove = <String>[];
|
||||
final transitCodes = <String>[];
|
||||
|
||||
for (final zongpaiNo in List.of(_zongpaiNos)) {
|
||||
final result = await _apiService.registerLocation(
|
||||
baseUrl: baseUrl,
|
||||
zongpaiNo: zongpaiNo,
|
||||
locationCode: _locationCode!,
|
||||
);
|
||||
if (result.success) {
|
||||
successCount++;
|
||||
if (result.isOffShelfSuccess) {
|
||||
offShelfCount++;
|
||||
}
|
||||
toRemove.add(zongpaiNo);
|
||||
if (_isTransitTarget) {
|
||||
transitCodes.add(zongpaiNo);
|
||||
}
|
||||
} else {
|
||||
failed.add(zongpaiNo);
|
||||
if (result.isDuplicate) {
|
||||
if (_isTransitTarget && transitCodes.isNotEmpty) {
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => toRemove.contains(item));
|
||||
_isSubmitting = false;
|
||||
});
|
||||
await _navigateToBoxing(
|
||||
mode: BoxingMode.multiCode,
|
||||
codes: transitCodes,
|
||||
codesToClear: toRemove,
|
||||
clearLocation: false,
|
||||
returnMessage: '成功 $successCount 条,失败 ${failed.length} 条',
|
||||
);
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => toRemove.contains(item));
|
||||
_isSubmitting = false;
|
||||
});
|
||||
_feedbackService.trigger(FeedbackEvent.duplicateError);
|
||||
_showDuplicateDialog(zongpaiNo, result.duplicateInfo);
|
||||
return;
|
||||
}
|
||||
if (result.isAlreadyOffShelf) {
|
||||
if (_isTransitTarget && transitCodes.isNotEmpty) {
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => toRemove.contains(item));
|
||||
_isSubmitting = false;
|
||||
});
|
||||
await _navigateToBoxing(
|
||||
mode: BoxingMode.multiCode,
|
||||
codes: transitCodes,
|
||||
codesToClear: toRemove,
|
||||
clearLocation: false,
|
||||
returnMessage: '成功 $successCount 条,失败 ${failed.length} 条',
|
||||
);
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => toRemove.contains(item));
|
||||
_isSubmitting = false;
|
||||
});
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showStatusOverride(
|
||||
result.errorMessage ?? '该总排号已下架至转运区域,不可重新上架',
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => toRemove.contains(item));
|
||||
_isSubmitting = false;
|
||||
});
|
||||
|
||||
if (_isTransitTarget && transitCodes.isNotEmpty) {
|
||||
await _navigateToBoxing(
|
||||
mode: BoxingMode.multiCode,
|
||||
codes: transitCodes,
|
||||
codesToClear: toRemove,
|
||||
clearLocation: failed.isEmpty,
|
||||
returnMessage: failed.isEmpty
|
||||
? null
|
||||
: '成功 $successCount 条,失败 ${failed.length} 条',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (failed.isEmpty) {
|
||||
_feedbackService.trigger(FeedbackEvent.submitSuccess);
|
||||
final msg = offShelfCount == successCount
|
||||
? '批量下架成功($successCount 条)'
|
||||
: '批量上架成功($successCount 条)';
|
||||
_showStatusOverride(
|
||||
msg,
|
||||
StatusDotColor.green,
|
||||
const Duration(milliseconds: 1500),
|
||||
);
|
||||
await _refreshCurrentOverview();
|
||||
} else {
|
||||
_feedbackService.trigger(FeedbackEvent.submitFailure);
|
||||
_showStatusOverride(
|
||||
'成功 $successCount 条,失败 ${failed.length} 条',
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _navigateToBoxing({
|
||||
required BoxingMode mode,
|
||||
required List<String> codes,
|
||||
required List<String> codesToClear,
|
||||
required bool clearLocation,
|
||||
String? returnMessage,
|
||||
}) async {
|
||||
await _refreshCurrentOverview();
|
||||
if (!mounted) return;
|
||||
final navigator = Navigator.of(context);
|
||||
await _stopScanListening();
|
||||
await navigator.push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => BoxingPage(
|
||||
arguments: BoxingPageArguments(
|
||||
initialMode: mode,
|
||||
autoScanCodes: codes,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (!mounted) return;
|
||||
await Future<void>.delayed(const Duration(milliseconds: 120));
|
||||
if (!mounted) return;
|
||||
_restartScanListening();
|
||||
setState(() {
|
||||
_zongpaiNos.removeWhere((item) => codesToClear.contains(item));
|
||||
if (clearLocation) {
|
||||
_locationCode = null;
|
||||
_locationType = null;
|
||||
}
|
||||
});
|
||||
await _refreshCurrentOverview();
|
||||
if (!mounted) return;
|
||||
if (returnMessage != null) {
|
||||
_showStatusOverride(
|
||||
returnMessage,
|
||||
StatusDotColor.red,
|
||||
const Duration(seconds: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user