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