1
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io' show Platform;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cupertino_http/cupertino_http.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../auth/session_store.dart';
|
||||
import '../config/app_config.dart';
|
||||
|
||||
/// 假目标上报 API 客户端(契约见 server/README.md「假目标上报」)。
|
||||
/// 仅上传误报框裁剪图(客户端已重编码剥离元数据)+ 检测框快照字段。
|
||||
class FeedbackApi {
|
||||
final String baseUrl;
|
||||
final SessionStore sessionStore;
|
||||
final http.Client _client;
|
||||
|
||||
FeedbackApi({String? baseUrl, required this.sessionStore, http.Client? client})
|
||||
: baseUrl = baseUrl ?? AppConfig.apiBaseUrl,
|
||||
_client = client ?? _defaultHttpClient();
|
||||
|
||||
static http.Client _defaultHttpClient() {
|
||||
if (!kIsWeb && Platform.isIOS) {
|
||||
return CupertinoClient.defaultSessionConfiguration();
|
||||
}
|
||||
return http.Client();
|
||||
}
|
||||
|
||||
/// 上报假目标:[jpeg] 为上报瞬间的分析帧整图(与推理帧同源同尺寸),
|
||||
/// [detectionsJson] 为当前全部检测框快照 JSON 数组(可为空串)
|
||||
Future<int> reportFalseTarget({
|
||||
required Uint8List jpeg,
|
||||
required String detectionsJson,
|
||||
required int sourceW,
|
||||
required int sourceH,
|
||||
}) async {
|
||||
final token = await sessionStore.readToken();
|
||||
if (token == null || token.isEmpty) {
|
||||
throw Exception('登录已失效');
|
||||
}
|
||||
final req = http.MultipartRequest(
|
||||
'POST',
|
||||
Uri.parse('$baseUrl/api/v1/feedback/false-target'),
|
||||
)
|
||||
..headers['Authorization'] = 'Bearer $token'
|
||||
..fields['detections'] = detectionsJson
|
||||
..fields['sourceW'] = '$sourceW'
|
||||
..fields['sourceH'] = '$sourceH'
|
||||
..files.add(
|
||||
http.MultipartFile.fromBytes('file', jpeg, filename: 'frame.jpg'));
|
||||
final streamed =
|
||||
await _client.send(req).timeout(const Duration(seconds: 30));
|
||||
final res = await http.Response.fromStream(streamed);
|
||||
final Map<String, dynamic> json;
|
||||
try {
|
||||
json = jsonDecode(res.body) as Map<String, dynamic>;
|
||||
} catch (_) {
|
||||
throw Exception('服务端响应异常 (${res.statusCode})');
|
||||
}
|
||||
if (res.statusCode != 200 || json['code'] != 0) {
|
||||
throw Exception(json['message'] as String? ?? '上报失败 (${res.statusCode})');
|
||||
}
|
||||
return ((json['data'] as Map?)?['id'] as num?)?.toInt() ?? 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user