Files
MaliangAINovalWriter/AINoval/lib/services/ai_preset_service.dart
2025-09-10 00:07:52 +08:00

321 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:ainoval/models/preset_models.dart';
import 'package:ainoval/services/api_service/repositories/ai_preset_repository.dart';
import 'package:ainoval/services/api_service/repositories/impl/ai_preset_repository_impl.dart';
import 'package:ainoval/services/api_service/base/api_client.dart';
import 'package:ainoval/utils/logger.dart';
/// AI预设服务
/// 提供预设管理的业务逻辑层
class AIPresetService {
final AIPresetRepository _repository;
final String _tag = 'AIPresetService';
AIPresetService({AIPresetRepository? repository})
: _repository = repository ?? AIPresetRepositoryImpl(apiClient: ApiClient());
/// 创建预设
/// [request] 创建预设请求
/// 返回创建的预设
Future<AIPromptPreset> createPreset(CreatePresetRequest request) async {
try {
AppLogger.i(_tag, '创建预设: ${request.presetName}');
final preset = await _repository.createPreset(request);
// 记录预设使用(创建后立即记录)
await _recordUsage(preset.presetId);
AppLogger.i(_tag, '预设创建成功: ${preset.presetId}');
return preset;
} catch (e) {
AppLogger.e(_tag, '创建预设失败', e);
rethrow;
}
}
/// 获取用户的所有预设
/// [userId] 用户ID如果为null则获取当前用户的预设
/// [featureType] 功能类型默认为AI_CHAT
/// 返回预设列表
Future<List<AIPromptPreset>> getUserPresets({String? userId, String featureType = 'AI_CHAT'}) async {
try {
AppLogger.d(_tag, '获取用户预设列表: userId=$userId, featureType=$featureType');
final presets = await _repository.getUserPresets(userId: userId, featureType: featureType);
AppLogger.i(_tag, '获取到 ${presets.length} 个用户预设 (featureType=$featureType)');
return presets;
} catch (e) {
AppLogger.e(_tag, '获取用户预设列表失败', e);
rethrow;
}
}
/// 搜索预设
/// [params] 搜索参数
/// 返回匹配的预设列表
Future<List<AIPromptPreset>> searchPresets(PresetSearchParams params) async {
try {
AppLogger.d(_tag, '搜索预设: ${params.keyword}');
final presets = await _repository.searchPresets(params);
AppLogger.i(_tag, '搜索到 ${presets.length} 个预设');
return presets;
} catch (e) {
AppLogger.e(_tag, '搜索预设失败', e);
rethrow;
}
}
/// 根据ID获取预设详情
/// [presetId] 预设ID
/// 返回预设详情
Future<AIPromptPreset> getPresetById(String presetId) async {
try {
AppLogger.d(_tag, '获取预设详情: $presetId');
final preset = await _repository.getPresetById(presetId);
AppLogger.i(_tag, '获取预设详情成功: ${preset.presetName}');
return preset;
} catch (e) {
AppLogger.e(_tag, '获取预设详情失败: $presetId', e);
rethrow;
}
}
/// 应用预设
/// [presetId] 预设ID
/// 返回预设详情并记录使用
Future<AIPromptPreset> applyPreset(String presetId) async {
try {
AppLogger.i(_tag, '应用预设: $presetId');
final preset = await _repository.getPresetById(presetId);
// 记录预设使用
await _recordUsage(presetId);
AppLogger.i(_tag, '预设应用成功: ${preset.presetName}');
return preset;
} catch (e) {
AppLogger.e(_tag, '应用预设失败: $presetId', e);
rethrow;
}
}
/// 更新预设信息
/// [presetId] 预设ID
/// [request] 更新请求
/// 返回更新后的预设
Future<AIPromptPreset> updatePresetInfo(String presetId, UpdatePresetInfoRequest request) async {
try {
AppLogger.i(_tag, '更新预设信息: $presetId');
final preset = await _repository.updatePresetInfo(presetId, request);
AppLogger.i(_tag, '预设信息更新成功: ${preset.presetName}');
return preset;
} catch (e) {
AppLogger.e(_tag, '更新预设信息失败: $presetId', e);
rethrow;
}
}
/// 更新预设提示词
/// [presetId] 预设ID
/// [request] 更新提示词请求
/// 返回更新后的预设
Future<AIPromptPreset> updatePresetPrompts(String presetId, UpdatePresetPromptsRequest request) async {
try {
AppLogger.i(_tag, '更新预设提示词: $presetId');
final preset = await _repository.updatePresetPrompts(presetId, request);
AppLogger.i(_tag, '预设提示词更新成功');
return preset;
} catch (e) {
AppLogger.e(_tag, '更新预设提示词失败: $presetId', e);
rethrow;
}
}
/// 删除预设
/// [presetId] 预设ID
Future<void> deletePreset(String presetId) async {
try {
AppLogger.i(_tag, '删除预设: $presetId');
await _repository.deletePreset(presetId);
AppLogger.i(_tag, '预设删除成功: $presetId');
} catch (e) {
AppLogger.e(_tag, '删除预设失败: $presetId', e);
rethrow;
}
}
/// 复制预设
/// [presetId] 源预设ID
/// [newName] 新预设名称
/// 返回新创建的预设
Future<AIPromptPreset> duplicatePreset(String presetId, String newName) async {
try {
AppLogger.i(_tag, '复制预设: $presetId -> $newName');
final request = DuplicatePresetRequest(newPresetName: newName);
final preset = await _repository.duplicatePreset(presetId, request);
AppLogger.i(_tag, '预设复制成功: ${preset.presetId}');
return preset;
} catch (e) {
AppLogger.e(_tag, '复制预设失败: $presetId', e);
rethrow;
}
}
/// 切换收藏状态
/// [presetId] 预设ID
/// 返回更新后的预设
Future<AIPromptPreset> toggleFavorite(String presetId) async {
try {
AppLogger.i(_tag, '切换预设收藏状态: $presetId');
final preset = await _repository.toggleFavorite(presetId);
AppLogger.i(_tag, '预设收藏状态切换成功: ${preset.isFavorite ? "已收藏" : "已取消收藏"}');
return preset;
} catch (e) {
AppLogger.e(_tag, '切换预设收藏状态失败: $presetId', e);
rethrow;
}
}
/// 获取预设统计信息
/// 返回统计信息
Future<PresetStatistics> getStatistics() async {
try {
AppLogger.d(_tag, '获取预设统计信息');
final statistics = await _repository.getPresetStatistics();
AppLogger.i(_tag, '获取预设统计信息成功: 总数 ${statistics.totalPresets}');
return statistics;
} catch (e) {
AppLogger.e(_tag, '获取预设统计信息失败', e);
rethrow;
}
}
/// 获取收藏的预设
/// [novelId] 小说ID如果为null则获取全局预设
/// [featureType] 功能类型,如果指定则只返回该类型的预设
/// 返回收藏预设列表
Future<List<AIPromptPreset>> getFavoritePresets({String? novelId, String? featureType}) async {
try {
AppLogger.d(_tag, '获取收藏预设列表: novelId=$novelId, featureType=$featureType');
final presets = await _repository.getFavoritePresets(novelId: novelId, featureType: featureType);
AppLogger.i(_tag, '获取到 ${presets.length} 个收藏预设');
return presets;
} catch (e) {
AppLogger.e(_tag, '获取收藏预设列表失败', e);
rethrow;
}
}
/// 获取最近使用的预设
/// [limit] 返回数量限制默认10个
/// [novelId] 小说ID如果为null则获取全局预设
/// [featureType] 功能类型,如果指定则只返回该类型的预设
/// 返回最近使用预设列表
Future<List<AIPromptPreset>> getRecentlyUsedPresets({int limit = 10, String? novelId, String? featureType}) async {
try {
AppLogger.d(_tag, '获取最近使用预设列表: novelId=$novelId, featureType=$featureType');
final presets = await _repository.getRecentlyUsedPresets(limit: limit, novelId: novelId, featureType: featureType);
AppLogger.i(_tag, '获取到 ${presets.length} 个最近使用预设');
return presets;
} catch (e) {
AppLogger.e(_tag, '获取最近使用预设列表失败', e);
rethrow;
}
}
/// 根据功能类型获取预设
/// [featureType] 功能类型
/// 返回指定功能类型的预设列表
Future<List<AIPromptPreset>> getPresetsByFeatureType(String featureType) async {
try {
AppLogger.d(_tag, '获取指定功能类型预设: $featureType');
final presets = await _repository.getPresetsByFeatureType(featureType);
AppLogger.i(_tag, '获取到 ${presets.length}$featureType 类型预设');
return presets;
} catch (e) {
AppLogger.e(_tag, '获取指定功能类型预设失败: $featureType', e);
rethrow;
}
}
/// 获取推荐预设
/// [featureType] 当前功能类型
/// [limit] 推荐数量默认5个
/// 返回推荐预设列表(基于收藏和使用频率)
Future<List<AIPromptPreset>> getRecommendedPresets(String featureType, {int limit = 5}) async {
try {
AppLogger.d(_tag, '获取推荐预设: $featureType');
// 优先获取同功能类型的收藏预设
final typedFavorites = await getFavoritePresets(featureType: featureType);
final limitedFavorites = typedFavorites.take(limit ~/ 2).toList();
// 补充最近使用的预设
final typedRecent = await getRecentlyUsedPresets(limit: limit, featureType: featureType);
final filteredRecent = typedRecent
.where((preset) => !limitedFavorites.any((fav) => fav.presetId == preset.presetId))
.take(limit - limitedFavorites.length)
.toList();
final recommended = [...limitedFavorites, ...filteredRecent];
AppLogger.i(_tag, '获取到 ${recommended.length} 个推荐预设');
return recommended;
} catch (e) {
AppLogger.e(_tag, '获取推荐预设失败: $featureType', e);
rethrow;
}
}
/// 记录预设使用(内部方法)
Future<void> _recordUsage(String presetId) async {
try {
await _repository.recordPresetUsage(presetId);
} catch (e) {
// 使用记录失败不影响主要流程
AppLogger.w(_tag, '记录预设使用失败: $presetId', e);
}
}
/// 获取功能预设列表(收藏、最近使用、推荐)
/// [featureType] 功能类型
/// [novelId] 小说ID可选
/// 返回分类的预设列表,包含标签信息
Future<PresetListResponse> getFeaturePresetList(String featureType, {String? novelId}) async {
try {
AppLogger.i(_tag, '获取功能预设列表: $featureType, novelId: $novelId');
final response = await _repository.getFeaturePresetList(featureType, novelId: novelId);
AppLogger.i(_tag, '功能预设列表获取成功: 总共${response.totalCount}个预设');
return response;
} catch (e) {
AppLogger.e(_tag, '获取功能预设列表失败: $featureType', e);
rethrow;
}
}
}