260 lines
8.0 KiB
Dart
260 lines
8.0 KiB
Dart
|
|
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>[];
|
|||
|
|
}
|
|||
|
|
}
|