feat: improve one-to-many boxing workflow
This commit is contained in:
@@ -32,11 +32,13 @@ class RegistrationResult {
|
||||
|
||||
/// 箱号内单个总排号明细
|
||||
class BoxItemData {
|
||||
final int? boxItemId;
|
||||
final String zongpaiNo;
|
||||
final String? workOrderNo;
|
||||
final int quantity;
|
||||
|
||||
BoxItemData({
|
||||
this.boxItemId,
|
||||
required this.zongpaiNo,
|
||||
this.workOrderNo,
|
||||
required this.quantity,
|
||||
@@ -44,6 +46,7 @@ class BoxItemData {
|
||||
|
||||
factory BoxItemData.fromJson(Map<String, dynamic> json) {
|
||||
return BoxItemData(
|
||||
boxItemId: json['box_item_id'] as int?,
|
||||
zongpaiNo: json['zongpai_no'] as String,
|
||||
workOrderNo: json['work_order_no']?.toString(),
|
||||
quantity: json['quantity'] as int,
|
||||
@@ -68,6 +71,27 @@ class BoxDetailData {
|
||||
}
|
||||
}
|
||||
|
||||
/// 当前总排号已分配的装箱明细
|
||||
class CurrentZongpaiBoxData {
|
||||
final int boxItemId;
|
||||
final int boxNo;
|
||||
final int quantity;
|
||||
|
||||
CurrentZongpaiBoxData({
|
||||
required this.boxItemId,
|
||||
required this.boxNo,
|
||||
required this.quantity,
|
||||
});
|
||||
|
||||
factory CurrentZongpaiBoxData.fromJson(Map<String, dynamic> json) {
|
||||
return CurrentZongpaiBoxData(
|
||||
boxItemId: json['box_item_id'] as int,
|
||||
boxNo: json['box_no'] as int,
|
||||
quantity: json['quantity'] as int,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 装箱信息查询结果
|
||||
class BoxInfoResult {
|
||||
final bool success;
|
||||
@@ -76,6 +100,7 @@ class BoxInfoResult {
|
||||
final String? paichanNo;
|
||||
final String? workOrderNo;
|
||||
final int? quantity;
|
||||
final List<CurrentZongpaiBoxData> currentZongpaiBoxes;
|
||||
final List<BoxDetailData> existingBoxes;
|
||||
final int maxBoxNo;
|
||||
final int suggestedBoxNo;
|
||||
@@ -87,6 +112,7 @@ class BoxInfoResult {
|
||||
this.paichanNo,
|
||||
this.workOrderNo,
|
||||
this.quantity,
|
||||
this.currentZongpaiBoxes = const [],
|
||||
this.existingBoxes = const [],
|
||||
this.maxBoxNo = 0,
|
||||
this.suggestedBoxNo = 1,
|
||||
@@ -98,12 +124,20 @@ class BoxInfoResult {
|
||||
?.map((b) => BoxDetailData.fromJson(b as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
[];
|
||||
final currentBoxes =
|
||||
(json['current_zongpai_boxes'] as List<dynamic>?)
|
||||
?.map(
|
||||
(b) => CurrentZongpaiBoxData.fromJson(b as Map<String, dynamic>),
|
||||
)
|
||||
.toList() ??
|
||||
[];
|
||||
return BoxInfoResult(
|
||||
success: true,
|
||||
zongpaiNo: json['zongpai_no'] as String?,
|
||||
paichanNo: json['paichan_no'] as String?,
|
||||
workOrderNo: json['work_order_no']?.toString(),
|
||||
quantity: json['quantity'] as int?,
|
||||
currentZongpaiBoxes: currentBoxes,
|
||||
existingBoxes: boxes,
|
||||
maxBoxNo: json['max_box_no'] as int? ?? 0,
|
||||
suggestedBoxNo: json['suggested_box_no'] as int? ?? 1,
|
||||
@@ -120,22 +154,28 @@ class BoxSaveResult {
|
||||
final bool success;
|
||||
final bool isDuplicate;
|
||||
final String? errorMessage;
|
||||
final int? boxItemId;
|
||||
final String? paichanNo;
|
||||
final int? boxNo;
|
||||
final int? quantity;
|
||||
|
||||
BoxSaveResult({
|
||||
required this.success,
|
||||
this.isDuplicate = false,
|
||||
this.errorMessage,
|
||||
this.boxItemId,
|
||||
this.paichanNo,
|
||||
this.boxNo,
|
||||
this.quantity,
|
||||
});
|
||||
|
||||
factory BoxSaveResult.ok(Map<String, dynamic> json) {
|
||||
return BoxSaveResult(
|
||||
success: true,
|
||||
boxItemId: json['box_item_id'] as int?,
|
||||
paichanNo: json['paichan_no'] as String?,
|
||||
boxNo: json['box_no'] as int?,
|
||||
quantity: json['quantity'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -153,6 +193,13 @@ class BoxSaveResult {
|
||||
}
|
||||
}
|
||||
|
||||
class BoxDeleteResult {
|
||||
final bool success;
|
||||
final String? errorMessage;
|
||||
|
||||
BoxDeleteResult({required this.success, this.errorMessage});
|
||||
}
|
||||
|
||||
class ApiService {
|
||||
final http.Client _client;
|
||||
final Duration timeout;
|
||||
@@ -275,6 +322,75 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新装箱明细 — PATCH /CargoTrace/box/{boxItemId}
|
||||
Future<BoxSaveResult> updateBoxRecord({
|
||||
required String baseUrl,
|
||||
required int boxItemId,
|
||||
required int boxNo,
|
||||
required int quantity,
|
||||
}) async {
|
||||
final uri = Uri.parse('$baseUrl/CargoTrace/box/$boxItemId');
|
||||
try {
|
||||
final response = await _client
|
||||
.patch(
|
||||
uri,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
'box_no': boxNo,
|
||||
'quantity': quantity,
|
||||
'box_mode': 'one-to-many',
|
||||
}),
|
||||
)
|
||||
.timeout(timeout);
|
||||
|
||||
switch (response.statusCode) {
|
||||
case 200:
|
||||
final body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
return BoxSaveResult.ok(body);
|
||||
case 400:
|
||||
final body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final msg = body['message']?.toString() ?? '请求参数错误';
|
||||
return BoxSaveResult.error(msg);
|
||||
case 409:
|
||||
final body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
return BoxSaveResult.duplicate(body);
|
||||
case 404:
|
||||
return BoxSaveResult.error('指定装箱明细不存在');
|
||||
default:
|
||||
return BoxSaveResult.error('修改失败 (${response.statusCode})');
|
||||
}
|
||||
} catch (e) {
|
||||
return BoxSaveResult.error('网络异常,请检查网络连接');
|
||||
}
|
||||
}
|
||||
|
||||
/// 删除装箱明细 — DELETE /CargoTrace/box/{boxItemId}
|
||||
Future<BoxDeleteResult> deleteBoxRecord({
|
||||
required String baseUrl,
|
||||
required int boxItemId,
|
||||
}) async {
|
||||
final uri = Uri.parse('$baseUrl/CargoTrace/box/$boxItemId');
|
||||
try {
|
||||
final response = await _client
|
||||
.delete(uri, headers: {'Content-Type': 'application/json'})
|
||||
.timeout(timeout);
|
||||
|
||||
switch (response.statusCode) {
|
||||
case 200:
|
||||
return BoxDeleteResult(success: true);
|
||||
case 404:
|
||||
return BoxDeleteResult(success: false, errorMessage: '指定装箱明细不存在');
|
||||
default:
|
||||
return BoxDeleteResult(
|
||||
success: false,
|
||||
errorMessage: '删除失败 (${response.statusCode})',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
return BoxDeleteResult(success: false, errorMessage: '网络异常,请检查网络连接');
|
||||
}
|
||||
}
|
||||
|
||||
/// Test connectivity by making a HEAD request to the base URL.
|
||||
Future<bool> testConnection(String baseUrl) async {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user