重构路径规划生成接口使其完全符合 Clean Architecture 规范

This commit is contained in:
2026-02-28 17:18:27 +08:00
parent bcaebade9a
commit 7ff79ee0b5
4 changed files with 73 additions and 43 deletions

View File

@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:maibu_satabot_v2/core/infrastructure/logging/sentry_logger_impl.dart';
import 'package:maibu_satabot_v2/core/logging/i_logger_service.dart';
import 'package:maibu_satabot_v2/features/devices/data/datasources/impl/device_http_datasource_impl.dart';
import 'package:maibu_satabot_v2/features/devices/data/datasources/impl/path_http_datasource_impl.dart';
import 'package:maibu_satabot_v2/features/devices/domain/repositories/device_repository.dart';
import 'package:maibu_satabot_v2/features/devices/domain/usecases/get_user_device_usecase.dart';
import 'package:maibu_satabot_v2/features/devices/domain/usecases/select_work_record_usecase.dart';
@@ -24,6 +25,7 @@ import '../../features/auth/presentation/bloc/auth_cubit.dart';
import '../../features/auth/presentation/bloc/login_bloc.dart';
import '../../features/auth/presentation/bloc/login_cubit.dart';
import '../../features/devices/data/datasources/device_http_datasource.dart';
import '../../features/devices/data/datasources/path_http_datasource.dart';
import '../../features/devices/data/repositories/device_hostriry_work_impl.dart';
import '../../features/devices/data/repositories/device_repository_impl.dart';
import '../../features/devices/data/repositories/generate_path_repository_Impl.dart';
@@ -121,7 +123,14 @@ Future<void> init() async {
sl.registerFactory(() => RemoteControlCubit(sl()));
/// . 路径生成
sl.registerLazySingleton<PathRepository>(() => PathRepositoryImpl());
sl.registerLazySingleton<PathHttpDatasource>(
() => PathHttpDatasourceImpl(// 需先注册 http.Client(见下方)
sl<UserStorage>(),
),
);
sl.registerLazySingleton<PathRepository>(
() => PathRepositoryImpl(datasource: sl<PathHttpDatasource>()),
);
sl.registerLazySingleton<GeneratePathUseCase>(
() => GeneratePathUseCaseImpl(sl<PathRepository>()),
);

View File

@@ -0,0 +1,48 @@
import 'dart:convert';
import '../../../../../core/storage/user_storage.dart';
import '../../models/device_add_path_point_model.dart';
import '../path_http_datasource.dart';
import 'package:http/http.dart' as http;
class PathHttpDatasourceImpl implements PathHttpDatasource {
final UserStorage _userStorage;
PathHttpDatasourceImpl(this._userStorage);
@override
Future<List<DeviceAddPathPointModel>> generatePathRaw({required Map<String, dynamic> body}) async {
final token = (await _userStorage.getUser())?.token;
if (token == null) throw Exception('Token missing');
final response = await http.post(
Uri.parse('https://servicepathplan.satabot.com/api/path'),
headers: {
'Content-Type': 'application/json',
'Authorization': token,
},
body: jsonEncode(body),
);
print('响应体: ${response.body}');
try {
final decoded = jsonDecode(response.body) as Map<String, dynamic>;
if (decoded['code'] == 200) {
final pathJson = decoded['path'];
if (pathJson == null) {
throw Exception('API returned null for "path"');
}
if (pathJson is! List) {
throw Exception('Expected "path" to be a List, but got ${pathJson.runtimeType}');
}
final List<dynamic> jsonData = pathJson;
return jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList();
} else {
throw Exception('Failed to load path: ${response.statusCode}');
}
} catch (e) {
throw Exception('Network error: $e');
}
}
}

View File

@@ -0,0 +1,7 @@
import '../models/device_add_path_point_model.dart';
abstract class PathHttpDatasource {
Future<List<DeviceAddPathPointModel>> generatePathRaw({
required Map<String, dynamic> body,
});
}

View File

@@ -6,15 +6,15 @@ import 'dart:convert';
import '../../../../core/di/injection.dart';
import '../../../../core/storage/user_storage.dart';
import '../../domain/repositories/path_repository.dart';
import '../datasources/path_http_datasource.dart';
import '../models/device_add_path_point_model.dart';
import '../models/device_work_area_param_model.dart';
class PathRepositoryImpl implements PathRepository {
/* final String baseUrl = 'https://serviceri.satabot.com'; // 后端接口地址*/
/* final UserStorage localTokenStorage;
final PathHttpDatasource _datasource;
PathRepositoryImpl({
required this.localTokenStorage, // 👈 关键:注入依赖
});*/
required PathHttpDatasource datasource,
}) : _datasource = datasource;
// 生成路径
@override
Future<List<DeviceAddPathPointModel>> generatePath({
@@ -24,49 +24,15 @@ class PathRepositoryImpl implements PathRepository {
required List<HoleBoundary> holes,
required int workType,
}) async {
final url = Uri.parse('https://servicepathplan.satabot.com/api/path');
// ✅ 直接从 GetIt 获取 UserStorage(无需构造函数传参)
final userStorage = sl<UserStorage>();
final userEntity = await userStorage.getUser();
final String? token = userEntity?.token;
if (token == null) throw Exception('请先登录');
// ✅ 设置带 token 的 headers
final headers = {'Content-Type': 'application/json', 'Authorization': token};
final body = jsonEncode({
final body = {
'reference': reference.toJson(),
'heading': heading,
'outer': outer.toJson(),
'holes': holes.map((hole) => hole.toJson()).toList(),
'holes': holes.map((h) => h.toJson()).toList(),
'workType': workType,
});
print('请求体: $body'); // 调试输出请求体
};
return await _datasource.generatePathRaw(body: body);
try {
final response = await http.post(url, headers: headers, body: body);
print('响应体: ${response.body}');
final decoded = jsonDecode(response.body) as Map<String, dynamic>;
print('解码后的响应: $decoded'); // 调试输出解码后的响应
if (decoded['success'] == true) {
final pathJson = decoded['data']?['path'];
print('路径数据: $pathJson'); // 调试输出路径数据
if (pathJson == null) {
throw Exception('API returned null for "path"');
}
if (pathJson is! List) {
throw Exception('Expected "path" to be a List, but got ${pathJson.runtimeType}');
}
final List<dynamic> jsonData = pathJson;
print('路径数据1111: $jsonData'); // 调试输出路径数据
print('路径数据11112222: ${jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList()}');
return jsonData.map((item) => DeviceAddPathPointModel.fromJson(item)).toList();
} else {
throw Exception('Failed to load path: ${response.statusCode}');
}
} catch (e) {
throw Exception('Network error: $e');
}
}
// 保存工作记录