From b859a9cea231ca871a842037c750d077c6461363 Mon Sep 17 00:00:00 2001 From: Misaka_Company Date: Sat, 9 May 2026 14:23:53 +0800 Subject: [PATCH] feat: rewrite ApiService for registration API, remove ScanRecord model Co-Authored-By: Claude Opus 4.6 --- lib/models/scan_record.dart | 21 ----------- lib/services/api_service.dart | 71 +++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 32 deletions(-) delete mode 100644 lib/models/scan_record.dart diff --git a/lib/models/scan_record.dart b/lib/models/scan_record.dart deleted file mode 100644 index 39cfe09..0000000 --- a/lib/models/scan_record.dart +++ /dev/null @@ -1,21 +0,0 @@ -enum SendStatus { pending, success, failed } - -class ScanRecord { - final String barcode; - final String codeType; - final DateTime timestamp; - SendStatus status; - - ScanRecord({ - required this.barcode, - required this.codeType, - required this.timestamp, - this.status = SendStatus.pending, - }); - - Map toJson() => { - 'barcode': barcode, - 'code_type': codeType, - 'timestamp': timestamp.toUtc().toIso8601String(), - }; -} diff --git a/lib/services/api_service.dart b/lib/services/api_service.dart index b57454e..ebf8bf6 100644 --- a/lib/services/api_service.dart +++ b/lib/services/api_service.dart @@ -1,29 +1,78 @@ import 'dart:convert'; import 'package:http/http.dart' as http; +/// Result of a registration API call. +class RegistrationResult { + final bool success; + final bool isDuplicate; + final String? errorMessage; + final Map? duplicateInfo; + + RegistrationResult({ + required this.success, + this.isDuplicate = false, + this.errorMessage, + this.duplicateInfo, + }); + + factory RegistrationResult.ok() => + RegistrationResult(success: true); + + factory RegistrationResult.duplicate(Map info) => + RegistrationResult(success: false, isDuplicate: true, duplicateInfo: info); + + factory RegistrationResult.error(String message) => + RegistrationResult(success: false, errorMessage: message); +} + class ApiService { final http.Client _client; + final Duration timeout; - ApiService({http.Client? client}) : _client = client ?? http.Client(); + ApiService({http.Client? client, this.timeout = const Duration(seconds: 5)}) + : _client = client ?? http.Client(); - Future sendScanData( - String url, { - required String barcode, - required String codeType, + /// Submit a shelf registration (上架登记). + Future registerLocation({ + required String baseUrl, + required String zongpaiNo, + required String locationCode, }) async { + final uri = Uri.parse('$baseUrl/CargoTrace/location'); try { final response = await _client .post( - Uri.parse(url), + uri, headers: {'Content-Type': 'application/json'}, body: jsonEncode({ - 'barcode': barcode, - 'code_type': codeType, - 'timestamp': DateTime.now().toUtc().toIso8601String(), + 'zongpai_no': zongpaiNo, + 'location_code': locationCode, }), ) - .timeout(const Duration(seconds: 5)); - return response.statusCode >= 200 && response.statusCode < 300; + .timeout(timeout); + + switch (response.statusCode) { + case 200: + return RegistrationResult.ok(); + case 409: + final body = jsonDecode(response.body) as Map; + return RegistrationResult.duplicate(body); + default: + final body = jsonDecode(response.body) as Map; + final msg = body['error'] ?? body['message'] ?? 'Unknown error (${response.statusCode})'; + return RegistrationResult.error(msg.toString()); + } + } catch (e) { + return RegistrationResult.error('网络异常,请检查网络连接'); + } + } + + /// Test connectivity by making a HEAD request to the base URL. + Future testConnection(String baseUrl) async { + try { + final uri = Uri.parse(baseUrl); + final response = await _client.head(uri).timeout(timeout); + return response.statusCode < 500; } catch (_) { return false; }