Files
CloudHome-Ops/lib/services/intro_service.dart

260 lines
8.0 KiB
Dart
Raw Permalink Normal View History

import 'package:dio/dio.dart';
import '../models/intro_category.dart';
import 'api_client.dart';
import '../utils/session_org_scope.dart';
/// 介绍页管理服务:分类、子分类、详情。
///
/// 对接真实「爱视后台」/api/company/* 接口。
/// 响应已由 [ApiInterceptor] 解包 `{code,msg,data}` 信封,直接消费 data。
class IntroService {
IntroService({Dio? dio}) : _dio = dio ?? ApiClient.instance.dio;
final Dio _dio;
// ================ 分类管理 ================
/// 获取介绍页分类列表(分页)。
///
/// GET /company/introCategory/list?page=&limit=&orgId=
Future<List<IntroCategory>> getIntroCategoryList({
int page = 1,
int limit = 20,
dynamic orgId,
}) async {
// 受限账号(SessionOrgScope 启用)未显式传入 orgId 时,自动带上当前组织,
// 避免列表接口忽略组织过滤而返回全量跨组织分类。
final effectiveOrgId = orgId ??
(SessionOrgScope.instance.enabled
? SessionOrgScope.instance.currentOrgId
: null);
final params = <String, dynamic>{'page': page, 'limit': limit};
if (effectiveOrgId != null && effectiveOrgId.toString().isNotEmpty) {
params['orgId'] = effectiveOrgId;
}
final response = await _dio.get<dynamic>(
'/company/introCategory/list',
queryParameters: params,
);
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroCategory.fromJson)
.toList();
}
/// 获取全部分类(不分页,用于下拉选择)。
///
/// GET /company/introCategory/all
Future<List<IntroCategory>> getIntroCategoryAll() async {
final response = await _dio.get<dynamic>('/company/introCategory/all');
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroCategory.fromJson)
.toList();
}
/// 获取分类详情。
///
/// GET /company/introCategory/info/{id}
Future<IntroCategory> getIntroCategoryInfo(String id) async {
final response =
await _dio.get<dynamic>('/company/introCategory/info/$id');
final data = response.data;
if (data is! Map<String, dynamic>) {
throw ApiException(500, '分类信息加载失败:$id');
}
return IntroCategory.fromJson(data);
}
/// 新增或修改分类。
///
/// 有 id 则 POST /company/introCategory/update,否则 POST /company/introCategory/save。
Future<void> saveIntroCategory(Map<String, dynamic> data) async {
final hasId = data['id'] != null &&
data['id'].toString().isNotEmpty &&
data['id'].toString() != '0';
final url = hasId
? '/company/introCategory/update'
: '/company/introCategory/save';
await _dio.post<dynamic>(url, data: data);
}
/// 批量删除分类。
///
/// POST /company/introCategory/delete,body 为 `{ids: [...]}`。
Future<void> deleteIntroCategory(List<int> ids) async {
await _dio.post<dynamic>(
'/company/introCategory/delete',
data: {'ids': ids},
);
}
// ================ 子分类管理 ================
/// 获取子分类列表(分页)。
///
/// GET /company/introSubcategory/list?page=&limit=
Future<List<IntroSubcategory>> getIntroSubcategoryList({
int page = 1,
int limit = 20,
}) async {
final response = await _dio.get<dynamic>(
'/company/introSubcategory/list',
queryParameters: {'page': page, 'limit': limit},
);
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroSubcategory.fromJson)
.toList();
}
/// 按分类 ID 获取子分类列表。
///
/// GET /company/introSubcategory/listByCategory/{categoryId}
Future<List<IntroSubcategory>> getIntroSubcategoryListByCategory(
String categoryId,
) async {
final response = await _dio.get<dynamic>(
'/company/introSubcategory/listByCategory/$categoryId',
);
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroSubcategory.fromJson)
.toList();
}
/// 获取子分类详情。
///
/// GET /company/introSubcategory/info/{id}
Future<IntroSubcategory> getIntroSubcategoryInfo(String id) async {
final response =
await _dio.get<dynamic>('/company/introSubcategory/info/$id');
final data = response.data;
if (data is! Map<String, dynamic>) {
throw ApiException(500, '子分类信息加载失败:$id');
}
return IntroSubcategory.fromJson(data);
}
/// 新增或修改子分类。
///
/// 有 id 则 POST /company/introSubcategory/update,否则 POST /company/introSubcategory/save。
Future<void> saveIntroSubcategory(Map<String, dynamic> data) async {
final hasId = data['id'] != null &&
data['id'].toString().isNotEmpty &&
data['id'].toString() != '0';
final url = hasId
? '/company/introSubcategory/update'
: '/company/introSubcategory/save';
await _dio.post<dynamic>(url, data: data);
}
/// 批量删除子分类。
///
/// POST /company/introSubcategory/delete,body 为 `{ids: [...]}`。
Future<void> deleteIntroSubcategory(List<int> ids) async {
await _dio.post<dynamic>(
'/company/introSubcategory/delete',
data: {'ids': ids},
);
}
// ================ 详情管理 ================
/// 获取介绍页详情列表(分页)。
///
/// GET /company/introDetail/list?page=&limit=
Future<List<IntroDetail>> getIntroDetailList({
int page = 1,
int limit = 20,
}) async {
final response = await _dio.get<dynamic>(
'/company/introDetail/list',
queryParameters: {'page': page, 'limit': limit},
);
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroDetail.fromJson)
.toList();
}
/// 按子分类 ID 获取详情列表。
///
/// GET /company/introDetail/listBySubcategory/{subcategoryId}
Future<List<IntroDetail>> getIntroDetailListBySubcategory(
String subcategoryId,
) async {
final response = await _dio.get<dynamic>(
'/company/introDetail/listBySubcategory/$subcategoryId',
);
final list = _extractList(response.data);
return list
.whereType<Map<String, dynamic>>()
.map(IntroDetail.fromJson)
.toList();
}
/// 获取详情信息。
///
/// GET /company/introDetail/info/{id}
Future<IntroDetail> getIntroDetailInfo(String id) async {
final response =
await _dio.get<dynamic>('/company/introDetail/info/$id');
final data = response.data;
if (data is! Map<String, dynamic>) {
throw ApiException(500, '详情信息加载失败:$id');
}
return IntroDetail.fromJson(data);
}
/// 新增或修改详情。
///
/// 有 id 则 POST /company/introDetail/update,否则 POST /company/introDetail/save。
Future<void> saveIntroDetail(Map<String, dynamic> data) async {
final hasId = data['id'] != null &&
data['id'].toString().isNotEmpty &&
data['id'].toString() != '0';
final url = hasId
? '/company/introDetail/update'
: '/company/introDetail/save';
await _dio.post<dynamic>(url, data: data);
}
/// 批量删除详情。
///
/// POST /company/introDetail/delete,body 为 `{ids: [...]}`。
Future<void> deleteIntroDetail(List<int> ids) async {
await _dio.post<dynamic>(
'/company/introDetail/delete',
data: {'ids': ids},
);
}
// ================ 工具方法 ================
/// 兼容列表响应的三种形态:
/// `{list: [...], totalCount}` / `{page: {list, totalCount}}` / 直接数组。
static List<dynamic> _extractList(dynamic data) {
if (data is List) {
return data;
}
if (data is Map<String, dynamic>) {
final list = data['list'];
if (list is List) {
return list;
}
final page = data['page'];
if (page is Map<String, dynamic> && page['list'] is List) {
return page['list'] as List;
}
}
return const <dynamic>[];
}
}