118 lines
4.4 KiB
Dart
118 lines
4.4 KiB
Dart
import 'dart:convert';
|
||
import 'package:dio/dio.dart';
|
||
import '../../../../core/consts/http_api_consts.dart';
|
||
import '../../../../core/logging/i_logger_service.dart';
|
||
import '../../domain/entities/region_draft.dart';
|
||
import '../models/region_model.dart';
|
||
|
||
class RegionRemoteDatasource {
|
||
RegionRemoteDatasource(this.dio, this.logger);
|
||
final Dio dio;
|
||
final ILoggerService logger;
|
||
|
||
Future<List<RegionDraft>> loadRegions(int siteId) async {
|
||
logger.logWithLevel(
|
||
'[分区列表] 请求: GET ${HttpApiConsts.regionsBySite}?siteId=$siteId',
|
||
shouldLog: true,
|
||
);
|
||
final response = await dio.get(
|
||
HttpApiConsts.regionsBySite,
|
||
queryParameters: {'siteId': siteId},
|
||
);
|
||
final data = response.data;
|
||
logger.logWithLevel(
|
||
'[分区列表] 响应: HTTP ${response.statusCode}, ${jsonEncode(data)}',
|
||
shouldLog: true,
|
||
);
|
||
if (response.statusCode != 200 ||
|
||
data is! Map ||
|
||
'${data['code']}' != '200') {
|
||
throw Exception(data is Map ? data['msg'] ?? '分区加载失败' : '分区列表响应格式错误');
|
||
}
|
||
final rows = data['data'] ?? const [];
|
||
if (rows is! List) throw const FormatException('分区列表 data 必须为数组');
|
||
final result = <int, RegionDraft>{};
|
||
for (final row in rows) {
|
||
if (row is! Map) continue;
|
||
if (row['delFlag'] == true ||
|
||
row['type'] != null && row['type'] != 'region') {
|
||
continue;
|
||
}
|
||
final region = RegionModel.fromJson(Map<String, dynamic>.from(row));
|
||
if (region.siteId == siteId) result[region.id!] = region;
|
||
}
|
||
return result.values.toList();
|
||
}
|
||
|
||
Future<bool> deleteRegions(List<int> ids) async {
|
||
logger.logWithLevel(
|
||
'[分区删除] 请求: POST ${HttpApiConsts.deleteRegions}, 参数: ${jsonEncode(ids)}',
|
||
shouldLog: true,
|
||
);
|
||
final response = await dio.post(HttpApiConsts.deleteRegions, data: ids);
|
||
final data = response.data;
|
||
logger.logWithLevel(
|
||
'[分区删除] 响应: HTTP ${response.statusCode}, ${jsonEncode(data)}',
|
||
shouldLog: true,
|
||
);
|
||
if (response.statusCode != 200 ||
|
||
data is! Map ||
|
||
'${data['code']}' != '200') {
|
||
throw Exception(data is Map ? data['msg'] ?? '分区删除失败' : '分区删除响应格式错误');
|
||
}
|
||
final result = data['data'];
|
||
if (result == false || result is num && result <= 0) {
|
||
throw Exception('分区未删除,请重试');
|
||
}
|
||
return true;
|
||
}
|
||
|
||
Future<RegionSaveResult> save(RegionDraft draft) async {
|
||
final body = <String, dynamic>{
|
||
if (draft.id != null) 'id': draft.id,
|
||
'regionName': draft.name.trim(),
|
||
'regionCode': draft.code.trim(),
|
||
'siteId': draft.siteId,
|
||
'type': 'region',
|
||
'remark': draft.remark,
|
||
'scope': [
|
||
for (final point in draft.scope) {'lat': point.lat, 'lng': point.lng},
|
||
],
|
||
'status': draft.enabled ? 1 : 0,
|
||
'defaultRoute': draft.defaultRouteId,
|
||
'bindRoutes': draft.boundRouteIds.toSet().toList()..sort(),
|
||
};
|
||
final url = HttpApiConsts.saveRegion;
|
||
logger.logWithLevel('[分区保存] 请求: POST $url', shouldLog: true);
|
||
logger.logWithLevel('[分区保存] 参数: ${jsonEncode(body)}', shouldLog: true);
|
||
try {
|
||
final response = await dio.post(url, data: body);
|
||
logger.logWithLevel(
|
||
'[分区保存] 响应: HTTP ${response.statusCode}, ${jsonEncode(response.data)}',
|
||
shouldLog: true,
|
||
);
|
||
final data = response.data;
|
||
if (response.statusCode != 200 ||
|
||
data is! Map ||
|
||
'${data['code']}' != '200') {
|
||
throw Exception(data is Map ? data['msg'] ?? '分区保存失败' : '分区保存响应格式错误');
|
||
}
|
||
final result = data['data'];
|
||
if (result == false || result is num && result <= 0) {
|
||
throw Exception('分区未保存,请重试');
|
||
}
|
||
// 数字 data 视为保存数量;只有对象内明确的 id 才能用作后续更新主键。
|
||
final returnedId = result is Map ? int.tryParse('${result['id']}') : null;
|
||
final id = returnedId != null && returnedId > 0 ? returnedId : draft.id;
|
||
logger.logWithLevel(
|
||
'[分区保存] 成功,${draft.id == null ? '新建' : '修改'}分区,id=$id',
|
||
shouldLog: true,
|
||
);
|
||
return RegionSaveResult(id: id);
|
||
} catch (error) {
|
||
logger.logWithLevel('[分区保存] 异常: $error', shouldLog: true);
|
||
rethrow;
|
||
}
|
||
}
|
||
}
|