马良AI写作初始化仓库
This commit is contained in:
3457
AINoval/lib/blocs/setting_generation/setting_generation_bloc.dart
Normal file
3457
AINoval/lib/blocs/setting_generation/setting_generation_bloc.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,482 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class SettingGenerationBlocEvent extends Equatable {
|
||||
const SettingGenerationBlocEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// 加载可用策略
|
||||
class LoadStrategiesEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final String? userId;
|
||||
|
||||
const LoadStrategiesEvent({
|
||||
this.novelId,
|
||||
this.userId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [novelId, userId];
|
||||
}
|
||||
|
||||
/// 加载历史记录
|
||||
class LoadHistoriesEvent extends SettingGenerationBlocEvent {
|
||||
final String novelId;
|
||||
final String userId;
|
||||
final int page;
|
||||
final int size;
|
||||
|
||||
const LoadHistoriesEvent({
|
||||
required this.novelId,
|
||||
required this.userId,
|
||||
this.page = 0,
|
||||
this.size = 20,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [novelId, userId, page, size];
|
||||
}
|
||||
|
||||
/// 从小说设定创建编辑会话
|
||||
class StartSessionFromNovelEvent extends SettingGenerationBlocEvent {
|
||||
final String novelId;
|
||||
final String editReason;
|
||||
final String modelConfigId;
|
||||
final bool createNewSnapshot;
|
||||
|
||||
const StartSessionFromNovelEvent({
|
||||
required this.novelId,
|
||||
required this.editReason,
|
||||
required this.modelConfigId,
|
||||
required this.createNewSnapshot,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [novelId, editReason, modelConfigId, createNewSnapshot];
|
||||
}
|
||||
|
||||
/// 开始生成设定
|
||||
class StartGenerationEvent extends SettingGenerationBlocEvent {
|
||||
final String initialPrompt;
|
||||
final String promptTemplateId;
|
||||
final String? novelId;
|
||||
final String modelConfigId;
|
||||
final String? userId;
|
||||
// 文本阶段公共模型透传(仅记录,不改变文本阶段默认使用私有模型)
|
||||
final bool? usePublicTextModel;
|
||||
final String? textPhasePublicProvider;
|
||||
final String? textPhasePublicModelId;
|
||||
|
||||
const StartGenerationEvent({
|
||||
required this.initialPrompt,
|
||||
required this.promptTemplateId,
|
||||
this.novelId,
|
||||
required this.modelConfigId,
|
||||
this.userId,
|
||||
this.usePublicTextModel,
|
||||
this.textPhasePublicProvider,
|
||||
this.textPhasePublicModelId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
initialPrompt,
|
||||
promptTemplateId,
|
||||
novelId,
|
||||
modelConfigId,
|
||||
userId,
|
||||
usePublicTextModel,
|
||||
textPhasePublicProvider,
|
||||
textPhasePublicModelId,
|
||||
];
|
||||
}
|
||||
|
||||
/// 基于当前会话进行整体调整生成
|
||||
class AdjustGenerationEvent extends SettingGenerationBlocEvent {
|
||||
final String sessionId;
|
||||
final String adjustmentPrompt;
|
||||
final String modelConfigId;
|
||||
final String? promptTemplateId;
|
||||
|
||||
const AdjustGenerationEvent({
|
||||
required this.sessionId,
|
||||
required this.adjustmentPrompt,
|
||||
required this.modelConfigId,
|
||||
this.promptTemplateId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [sessionId, adjustmentPrompt, modelConfigId, promptTemplateId];
|
||||
}
|
||||
|
||||
/// 修改节点
|
||||
class UpdateNodeEvent extends SettingGenerationBlocEvent {
|
||||
final String nodeId;
|
||||
final String modificationPrompt;
|
||||
final String modelConfigId;
|
||||
final String scope; // 'self' | 'self_and_children' | 'children_only'
|
||||
|
||||
const UpdateNodeEvent({
|
||||
required this.nodeId,
|
||||
required this.modificationPrompt,
|
||||
required this.modelConfigId,
|
||||
this.scope = 'self',
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
nodeId,
|
||||
modificationPrompt,
|
||||
modelConfigId,
|
||||
scope,
|
||||
];
|
||||
}
|
||||
|
||||
/// 选择节点
|
||||
class SelectNodeEvent extends SettingGenerationBlocEvent {
|
||||
final String? nodeId;
|
||||
|
||||
const SelectNodeEvent(this.nodeId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nodeId];
|
||||
}
|
||||
|
||||
/// 切换视图模式
|
||||
class ToggleViewModeEvent extends SettingGenerationBlocEvent {
|
||||
final String viewMode; // 'compact' | 'detailed'
|
||||
|
||||
const ToggleViewModeEvent(this.viewMode);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [viewMode];
|
||||
}
|
||||
|
||||
/// 应用待处理的更改
|
||||
class ApplyPendingChangesEvent extends SettingGenerationBlocEvent {
|
||||
const ApplyPendingChangesEvent();
|
||||
}
|
||||
|
||||
/// 取消待处理的更改
|
||||
class CancelPendingChangesEvent extends SettingGenerationBlocEvent {
|
||||
const CancelPendingChangesEvent();
|
||||
}
|
||||
|
||||
/// 撤销节点更改
|
||||
class UndoNodeChangeEvent extends SettingGenerationBlocEvent {
|
||||
final String nodeId;
|
||||
|
||||
const UndoNodeChangeEvent(this.nodeId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nodeId];
|
||||
}
|
||||
|
||||
/// 保存生成的设定
|
||||
class SaveGeneratedSettingsEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId; // 改为可空,支持独立快照
|
||||
final bool updateExisting; // 是否更新现有历史记录
|
||||
final String? targetHistoryId; // 目标历史记录ID
|
||||
|
||||
const SaveGeneratedSettingsEvent(
|
||||
this.novelId, {
|
||||
this.updateExisting = false,
|
||||
this.targetHistoryId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [novelId, updateExisting, targetHistoryId];
|
||||
}
|
||||
|
||||
/// 创建新会话
|
||||
class CreateNewSessionEvent extends SettingGenerationBlocEvent {
|
||||
const CreateNewSessionEvent();
|
||||
}
|
||||
|
||||
/// 选择会话
|
||||
class SelectSessionEvent extends SettingGenerationBlocEvent {
|
||||
final String sessionId;
|
||||
final bool isHistorySession;
|
||||
|
||||
const SelectSessionEvent(
|
||||
this.sessionId, {
|
||||
this.isHistorySession = false,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [sessionId, isHistorySession];
|
||||
}
|
||||
|
||||
/// 从历史记录创建编辑会话
|
||||
class CreateSessionFromHistoryEvent extends SettingGenerationBlocEvent {
|
||||
final String historyId;
|
||||
final String userId;
|
||||
final String editReason;
|
||||
final String modelConfigId;
|
||||
|
||||
const CreateSessionFromHistoryEvent({
|
||||
required this.historyId,
|
||||
required this.userId,
|
||||
this.editReason = '从历史记录编辑',
|
||||
required this.modelConfigId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [historyId, userId, editReason, modelConfigId];
|
||||
}
|
||||
|
||||
/// 更新调整提示词
|
||||
class UpdateAdjustmentPromptEvent extends SettingGenerationBlocEvent {
|
||||
final String prompt;
|
||||
|
||||
const UpdateAdjustmentPromptEvent(this.prompt);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [prompt];
|
||||
}
|
||||
|
||||
/// 重置状态事件
|
||||
class ResetEvent extends SettingGenerationBlocEvent {
|
||||
const ResetEvent();
|
||||
}
|
||||
|
||||
/// 重试事件(从错误状态恢复)
|
||||
class RetryEvent extends SettingGenerationBlocEvent {
|
||||
const RetryEvent();
|
||||
}
|
||||
|
||||
/// 开始渲染节点事件
|
||||
class StartNodeRenderEvent extends SettingGenerationBlocEvent {
|
||||
final String nodeId;
|
||||
|
||||
const StartNodeRenderEvent(this.nodeId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nodeId];
|
||||
}
|
||||
|
||||
/// 完成节点渲染事件
|
||||
class CompleteNodeRenderEvent extends SettingGenerationBlocEvent {
|
||||
final String nodeId;
|
||||
|
||||
const CompleteNodeRenderEvent(this.nodeId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nodeId];
|
||||
}
|
||||
|
||||
/// 处理渲染队列事件
|
||||
class ProcessRenderQueueEvent extends SettingGenerationBlocEvent {
|
||||
const ProcessRenderQueueEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// 更新节点内容事件
|
||||
class UpdateNodeContentEvent extends SettingGenerationBlocEvent {
|
||||
final String nodeId;
|
||||
final String content;
|
||||
|
||||
const UpdateNodeContentEvent({
|
||||
required this.nodeId,
|
||||
required this.content,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nodeId, content];
|
||||
}
|
||||
|
||||
/// 获取会话状态事件
|
||||
class GetSessionStatusEvent extends SettingGenerationBlocEvent {
|
||||
final String sessionId;
|
||||
|
||||
const GetSessionStatusEvent(this.sessionId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [sessionId];
|
||||
}
|
||||
|
||||
/// 取消会话事件
|
||||
class CancelSessionEvent extends SettingGenerationBlocEvent {
|
||||
final String sessionId;
|
||||
|
||||
const CancelSessionEvent(this.sessionId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [sessionId];
|
||||
}
|
||||
|
||||
// ==================== NOVEL_COMPOSE 事件族 ====================
|
||||
|
||||
/// 启动:只生成大纲
|
||||
class StartComposeOutlineEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final String userId;
|
||||
final String modelConfigId;
|
||||
final bool? isPublicModel;
|
||||
final String? publicModelConfigId;
|
||||
final String? settingSessionId; // 方案A:后端拉取会话转换
|
||||
final Map<String, dynamic>? contextSelections; // 直接透传已选上下文(可选)
|
||||
final String? prompt; // 自由提示词
|
||||
final String? instructions; // 生成指令
|
||||
final int chapterCount; // 按章大纲数量(支持黄金三章=3)
|
||||
final Map<String, dynamic> parameters; // 其他采样/模式参数
|
||||
|
||||
const StartComposeOutlineEvent({
|
||||
required this.userId,
|
||||
required this.modelConfigId,
|
||||
this.isPublicModel,
|
||||
this.publicModelConfigId,
|
||||
this.novelId,
|
||||
this.settingSessionId,
|
||||
this.contextSelections,
|
||||
this.prompt,
|
||||
this.instructions,
|
||||
this.chapterCount = 3,
|
||||
this.parameters = const {},
|
||||
});
|
||||
}
|
||||
|
||||
/// 启动:直接生成章节(黄金三章或指定N章)
|
||||
class StartComposeChaptersEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final String userId;
|
||||
final String modelConfigId;
|
||||
final bool? isPublicModel;
|
||||
final String? publicModelConfigId;
|
||||
final String? settingSessionId;
|
||||
final Map<String, dynamic>? contextSelections;
|
||||
final String? prompt;
|
||||
final String? instructions;
|
||||
final int chapterCount; // 生成章节数
|
||||
final Map<String, dynamic> parameters;
|
||||
|
||||
const StartComposeChaptersEvent({
|
||||
required this.userId,
|
||||
required this.modelConfigId,
|
||||
this.isPublicModel,
|
||||
this.publicModelConfigId,
|
||||
this.novelId,
|
||||
this.settingSessionId,
|
||||
this.contextSelections,
|
||||
this.prompt,
|
||||
this.instructions,
|
||||
this.chapterCount = 3,
|
||||
this.parameters = const {},
|
||||
});
|
||||
}
|
||||
|
||||
/// 启动:先大纲后章节(outline_plus_chapters)
|
||||
class StartComposeBundleEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final String userId;
|
||||
final String modelConfigId;
|
||||
final bool? isPublicModel;
|
||||
final String? publicModelConfigId;
|
||||
final String? settingSessionId;
|
||||
final Map<String, dynamic>? contextSelections;
|
||||
final String? prompt;
|
||||
final String? instructions;
|
||||
final int chapterCount; // 需要的大纲/章节数量
|
||||
final Map<String, dynamic> parameters;
|
||||
|
||||
const StartComposeBundleEvent({
|
||||
required this.userId,
|
||||
required this.modelConfigId,
|
||||
this.isPublicModel,
|
||||
this.publicModelConfigId,
|
||||
this.novelId,
|
||||
this.settingSessionId,
|
||||
this.contextSelections,
|
||||
this.prompt,
|
||||
this.instructions,
|
||||
this.chapterCount = 3,
|
||||
this.parameters = const {},
|
||||
});
|
||||
}
|
||||
|
||||
/// 微调:针对已生成的大纲或章节进行整体或定向调整
|
||||
class RefineComposeEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final String userId;
|
||||
final String modelConfigId;
|
||||
final String? settingSessionId;
|
||||
final Map<String, dynamic>? contextSelections;
|
||||
final String? instructions; // 具体微调指令
|
||||
final Map<String, dynamic> parameters; // 可包含 chapterIndex、outlineText 等
|
||||
|
||||
const RefineComposeEvent({
|
||||
required this.userId,
|
||||
required this.modelConfigId,
|
||||
this.novelId,
|
||||
this.settingSessionId,
|
||||
this.contextSelections,
|
||||
this.instructions,
|
||||
this.parameters = const {},
|
||||
});
|
||||
}
|
||||
|
||||
/// 取消写作编排流
|
||||
class CancelComposeEvent extends SettingGenerationBlocEvent {
|
||||
final String connectionId; // SSE连接ID或业务自定义ID
|
||||
const CancelComposeEvent(this.connectionId);
|
||||
@override
|
||||
List<Object?> get props => [connectionId];
|
||||
}
|
||||
|
||||
/// 获取用户历史记录事件
|
||||
class GetUserHistoriesEvent extends SettingGenerationBlocEvent {
|
||||
final String? novelId;
|
||||
final int page;
|
||||
final int size;
|
||||
|
||||
const GetUserHistoriesEvent({
|
||||
this.novelId,
|
||||
this.page = 0,
|
||||
this.size = 20,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [novelId, page, size];
|
||||
}
|
||||
|
||||
/// 删除历史记录事件
|
||||
class DeleteHistoryEvent extends SettingGenerationBlocEvent {
|
||||
final String historyId;
|
||||
|
||||
const DeleteHistoryEvent(this.historyId);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [historyId];
|
||||
}
|
||||
|
||||
/// 复制历史记录事件
|
||||
class CopyHistoryEvent extends SettingGenerationBlocEvent {
|
||||
final String historyId;
|
||||
final String copyReason;
|
||||
|
||||
const CopyHistoryEvent({
|
||||
required this.historyId,
|
||||
required this.copyReason,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [historyId, copyReason];
|
||||
}
|
||||
|
||||
/// 恢复历史记录到小说事件
|
||||
class RestoreHistoryToNovelEvent extends SettingGenerationBlocEvent {
|
||||
final String historyId;
|
||||
final String novelId;
|
||||
|
||||
const RestoreHistoryToNovelEvent({
|
||||
required this.historyId,
|
||||
required this.novelId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [historyId, novelId];
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../../models/setting_generation_session.dart';
|
||||
import '../../models/setting_node.dart';
|
||||
import '../../models/setting_generation_event.dart' as event_model;
|
||||
import '../../models/compose_preview.dart';
|
||||
import '../../models/strategy_template_info.dart';
|
||||
import '../../utils/setting_node_utils.dart'; // 导入工具类
|
||||
|
||||
abstract class SettingGenerationState extends Equatable {
|
||||
const SettingGenerationState();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// 初始状态
|
||||
class SettingGenerationInitial extends SettingGenerationState {
|
||||
const SettingGenerationInitial();
|
||||
}
|
||||
|
||||
/// 加载中
|
||||
class SettingGenerationLoading extends SettingGenerationState {
|
||||
final String? message;
|
||||
|
||||
const SettingGenerationLoading({this.message});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
||||
|
||||
/// 策略已加载
|
||||
class StrategiesLoaded extends SettingGenerationState {
|
||||
final List<StrategyTemplateInfo> strategies;
|
||||
|
||||
const StrategiesLoaded(this.strategies);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [strategies];
|
||||
}
|
||||
|
||||
/// 待机状态(准备开始生成)
|
||||
class SettingGenerationReady extends SettingGenerationState {
|
||||
final List<StrategyTemplateInfo> strategies;
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String? activeSessionId;
|
||||
final String adjustmentPrompt;
|
||||
final String viewMode;
|
||||
|
||||
const SettingGenerationReady({
|
||||
required this.strategies,
|
||||
this.sessions = const [],
|
||||
this.activeSessionId,
|
||||
this.adjustmentPrompt = '',
|
||||
this.viewMode = 'compact',
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
strategies,
|
||||
sessions,
|
||||
activeSessionId,
|
||||
adjustmentPrompt,
|
||||
viewMode,
|
||||
];
|
||||
|
||||
SettingGenerationReady copyWith({
|
||||
List<StrategyTemplateInfo>? strategies,
|
||||
List<SettingGenerationSession>? sessions,
|
||||
String? activeSessionId,
|
||||
String? adjustmentPrompt,
|
||||
String? viewMode,
|
||||
}) {
|
||||
return SettingGenerationReady(
|
||||
strategies: strategies ?? this.strategies,
|
||||
sessions: sessions ?? this.sessions,
|
||||
activeSessionId: activeSessionId ?? this.activeSessionId,
|
||||
adjustmentPrompt: adjustmentPrompt ?? this.adjustmentPrompt,
|
||||
viewMode: viewMode ?? this.viewMode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 节点渲染状态枚举
|
||||
enum NodeRenderState {
|
||||
pending, // 待渲染(在队列中)
|
||||
rendering, // 正在渲染(动画中)
|
||||
rendered, // 已渲染完成
|
||||
}
|
||||
|
||||
/// 节点渲染信息
|
||||
class NodeRenderInfo {
|
||||
final String nodeId;
|
||||
final NodeRenderState state;
|
||||
final DateTime? renderStartTime;
|
||||
final Duration? renderDuration;
|
||||
|
||||
const NodeRenderInfo({
|
||||
required this.nodeId,
|
||||
required this.state,
|
||||
this.renderStartTime,
|
||||
this.renderDuration,
|
||||
});
|
||||
|
||||
NodeRenderInfo copyWith({
|
||||
NodeRenderState? state,
|
||||
DateTime? renderStartTime,
|
||||
Duration? renderDuration,
|
||||
}) {
|
||||
return NodeRenderInfo(
|
||||
nodeId: nodeId,
|
||||
state: state ?? this.state,
|
||||
renderStartTime: renderStartTime ?? this.renderStartTime,
|
||||
renderDuration: renderDuration ?? this.renderDuration,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 生成中
|
||||
class SettingGenerationInProgress extends SettingGenerationState {
|
||||
final List<StrategyTemplateInfo> strategies;
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String activeSessionId;
|
||||
final SettingGenerationSession activeSession;
|
||||
final String? selectedNodeId;
|
||||
final String viewMode;
|
||||
final String adjustmentPrompt;
|
||||
final Map<String, SettingNode> pendingChanges;
|
||||
final Set<String> highlightedNodeIds;
|
||||
final Map<String, List<SettingNode>> editHistory;
|
||||
final List<event_model.SettingGenerationEvent> events;
|
||||
final bool isGenerating;
|
||||
final String? currentOperation;
|
||||
// 新增:写作编排流的预览缓存(仅前端展示,不落库)
|
||||
final List<ComposeChapterPreview> composePreview;
|
||||
|
||||
// 新增的渲染状态管理字段
|
||||
final Map<String, NodeRenderInfo> nodeRenderStates;
|
||||
final List<String> renderQueue;
|
||||
final Set<String> renderedNodeIds;
|
||||
|
||||
final List<event_model.NodeCreatedEvent> pendingNodes;
|
||||
// 粘性警告(例如余额不足提醒),不会被后续普通事件覆盖
|
||||
final String? stickyWarning;
|
||||
|
||||
const SettingGenerationInProgress({
|
||||
required this.strategies,
|
||||
required this.sessions,
|
||||
required this.activeSessionId,
|
||||
required this.activeSession,
|
||||
this.selectedNodeId,
|
||||
this.viewMode = 'compact',
|
||||
this.adjustmentPrompt = '',
|
||||
this.pendingChanges = const {},
|
||||
this.highlightedNodeIds = const {},
|
||||
this.editHistory = const {},
|
||||
this.isGenerating = false,
|
||||
this.currentOperation,
|
||||
this.composePreview = const [],
|
||||
this.events = const [],
|
||||
this.nodeRenderStates = const {},
|
||||
this.renderQueue = const [],
|
||||
this.renderedNodeIds = const {},
|
||||
this.pendingNodes = const [],
|
||||
this.stickyWarning,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
strategies,
|
||||
sessions,
|
||||
activeSessionId,
|
||||
activeSession,
|
||||
selectedNodeId,
|
||||
viewMode,
|
||||
adjustmentPrompt,
|
||||
pendingChanges,
|
||||
highlightedNodeIds,
|
||||
editHistory,
|
||||
isGenerating,
|
||||
currentOperation,
|
||||
composePreview,
|
||||
events,
|
||||
nodeRenderStates,
|
||||
renderQueue,
|
||||
renderedNodeIds,
|
||||
stickyWarning,
|
||||
];
|
||||
|
||||
SettingGenerationInProgress copyWith({
|
||||
List<StrategyTemplateInfo>? strategies,
|
||||
List<SettingGenerationSession>? sessions,
|
||||
String? activeSessionId,
|
||||
SettingGenerationSession? activeSession,
|
||||
String? selectedNodeId,
|
||||
String? viewMode,
|
||||
String? adjustmentPrompt,
|
||||
Map<String, SettingNode>? pendingChanges,
|
||||
Set<String>? highlightedNodeIds,
|
||||
Map<String, List<SettingNode>>? editHistory,
|
||||
bool? isGenerating,
|
||||
String? currentOperation,
|
||||
List<ComposeChapterPreview>? composePreview,
|
||||
List<event_model.SettingGenerationEvent>? events,
|
||||
Map<String, NodeRenderInfo>? nodeRenderStates,
|
||||
List<String>? renderQueue,
|
||||
Set<String>? renderedNodeIds,
|
||||
List<event_model.NodeCreatedEvent>? pendingNodes,
|
||||
String? stickyWarning,
|
||||
}) {
|
||||
return SettingGenerationInProgress(
|
||||
strategies: strategies ?? this.strategies,
|
||||
sessions: sessions ?? this.sessions,
|
||||
activeSessionId: activeSessionId ?? this.activeSessionId,
|
||||
activeSession: activeSession ?? this.activeSession,
|
||||
selectedNodeId: selectedNodeId ?? this.selectedNodeId,
|
||||
viewMode: viewMode ?? this.viewMode,
|
||||
adjustmentPrompt: adjustmentPrompt ?? this.adjustmentPrompt,
|
||||
pendingChanges: pendingChanges ?? this.pendingChanges,
|
||||
highlightedNodeIds: highlightedNodeIds ?? this.highlightedNodeIds,
|
||||
editHistory: editHistory ?? this.editHistory,
|
||||
isGenerating: isGenerating ?? this.isGenerating,
|
||||
currentOperation: currentOperation ?? this.currentOperation,
|
||||
composePreview: composePreview ?? this.composePreview,
|
||||
events: events ?? this.events,
|
||||
nodeRenderStates: nodeRenderStates ?? this.nodeRenderStates,
|
||||
renderQueue: renderQueue ?? this.renderQueue,
|
||||
renderedNodeIds: renderedNodeIds ?? this.renderedNodeIds,
|
||||
pendingNodes: pendingNodes ?? this.pendingNodes,
|
||||
stickyWarning: stickyWarning ?? this.stickyWarning,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取当前选中的节点
|
||||
SettingNode? get selectedNode {
|
||||
if (selectedNodeId == null) return null;
|
||||
return SettingNodeUtils.findNodeInTree(activeSession.rootNodes, selectedNodeId!);
|
||||
}
|
||||
|
||||
/// 获取可以渲染的节点列表(父节点为空或已渲染)
|
||||
List<String> get renderableNodeIds {
|
||||
return SettingNodeUtils.getRenderableNodeIds(
|
||||
activeSession.rootNodes,
|
||||
renderQueue,
|
||||
renderedNodeIds,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 生成完成
|
||||
class SettingGenerationCompleted extends SettingGenerationState {
|
||||
final List<StrategyTemplateInfo> strategies;
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String activeSessionId;
|
||||
final SettingGenerationSession activeSession;
|
||||
final String? selectedNodeId;
|
||||
final String viewMode;
|
||||
final String adjustmentPrompt;
|
||||
final Map<String, SettingNode> pendingChanges;
|
||||
final Set<String> highlightedNodeIds;
|
||||
final Map<String, List<SettingNode>> editHistory;
|
||||
final List<event_model.SettingGenerationEvent> events;
|
||||
final String message;
|
||||
|
||||
// 新增的渲染状态管理字段
|
||||
final Map<String, NodeRenderInfo> nodeRenderStates;
|
||||
final Set<String> renderedNodeIds;
|
||||
final String? stickyWarning;
|
||||
|
||||
const SettingGenerationCompleted({
|
||||
required this.strategies,
|
||||
required this.sessions,
|
||||
required this.activeSessionId,
|
||||
required this.activeSession,
|
||||
this.selectedNodeId,
|
||||
this.viewMode = 'compact',
|
||||
this.adjustmentPrompt = '',
|
||||
this.pendingChanges = const {},
|
||||
this.highlightedNodeIds = const {},
|
||||
this.editHistory = const {},
|
||||
this.events = const [],
|
||||
required this.message,
|
||||
this.nodeRenderStates = const {},
|
||||
this.renderedNodeIds = const {},
|
||||
this.stickyWarning,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
strategies,
|
||||
sessions,
|
||||
activeSessionId,
|
||||
activeSession,
|
||||
selectedNodeId,
|
||||
viewMode,
|
||||
adjustmentPrompt,
|
||||
pendingChanges,
|
||||
highlightedNodeIds,
|
||||
editHistory,
|
||||
events,
|
||||
message,
|
||||
nodeRenderStates,
|
||||
renderedNodeIds,
|
||||
stickyWarning,
|
||||
];
|
||||
|
||||
SettingGenerationCompleted copyWith({
|
||||
List<StrategyTemplateInfo>? strategies,
|
||||
List<SettingGenerationSession>? sessions,
|
||||
String? activeSessionId,
|
||||
SettingGenerationSession? activeSession,
|
||||
String? selectedNodeId,
|
||||
String? viewMode,
|
||||
String? adjustmentPrompt,
|
||||
Map<String, SettingNode>? pendingChanges,
|
||||
Set<String>? highlightedNodeIds,
|
||||
Map<String, List<SettingNode>>? editHistory,
|
||||
List<event_model.SettingGenerationEvent>? events,
|
||||
String? message,
|
||||
Map<String, NodeRenderInfo>? nodeRenderStates,
|
||||
Set<String>? renderedNodeIds,
|
||||
String? stickyWarning,
|
||||
}) {
|
||||
return SettingGenerationCompleted(
|
||||
strategies: strategies ?? this.strategies,
|
||||
sessions: sessions ?? this.sessions,
|
||||
activeSessionId: activeSessionId ?? this.activeSessionId,
|
||||
activeSession: activeSession ?? this.activeSession,
|
||||
selectedNodeId: selectedNodeId ?? this.selectedNodeId,
|
||||
viewMode: viewMode ?? this.viewMode,
|
||||
adjustmentPrompt: adjustmentPrompt ?? this.adjustmentPrompt,
|
||||
pendingChanges: pendingChanges ?? this.pendingChanges,
|
||||
highlightedNodeIds: highlightedNodeIds ?? this.highlightedNodeIds,
|
||||
editHistory: editHistory ?? this.editHistory,
|
||||
events: events ?? this.events,
|
||||
message: message ?? this.message,
|
||||
nodeRenderStates: nodeRenderStates ?? this.nodeRenderStates,
|
||||
renderedNodeIds: renderedNodeIds ?? this.renderedNodeIds,
|
||||
stickyWarning: stickyWarning ?? this.stickyWarning,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取当前选中的节点
|
||||
SettingNode? get selectedNode {
|
||||
if (selectedNodeId == null) return null;
|
||||
return SettingNodeUtils.findNodeInTree(activeSession.rootNodes, selectedNodeId!);
|
||||
}
|
||||
}
|
||||
|
||||
/// 节点修改中状态(专门用于节点修改,避免整个设定树重新渲染)
|
||||
class SettingGenerationNodeUpdating extends SettingGenerationState {
|
||||
final List<StrategyTemplateInfo> strategies;
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String activeSessionId;
|
||||
final SettingGenerationSession activeSession;
|
||||
final String? selectedNodeId;
|
||||
final String viewMode;
|
||||
final String adjustmentPrompt;
|
||||
final Map<String, SettingNode> pendingChanges;
|
||||
final Set<String> highlightedNodeIds;
|
||||
final Map<String, List<SettingNode>> editHistory;
|
||||
final List<event_model.SettingGenerationEvent> events;
|
||||
final String message;
|
||||
|
||||
// 节点修改特有字段
|
||||
final String updatingNodeId; // 正在修改的节点ID
|
||||
final String modificationPrompt; // 修改提示词
|
||||
final String scope; // 修改范围
|
||||
final bool isUpdating; // 是否正在更新中
|
||||
|
||||
// 渲染状态管理字段
|
||||
final Map<String, NodeRenderInfo> nodeRenderStates;
|
||||
final Set<String> renderedNodeIds;
|
||||
|
||||
const SettingGenerationNodeUpdating({
|
||||
required this.strategies,
|
||||
required this.sessions,
|
||||
required this.activeSessionId,
|
||||
required this.activeSession,
|
||||
this.selectedNodeId,
|
||||
this.viewMode = 'compact',
|
||||
this.adjustmentPrompt = '',
|
||||
this.pendingChanges = const {},
|
||||
this.highlightedNodeIds = const {},
|
||||
this.editHistory = const {},
|
||||
this.events = const [],
|
||||
this.message = '',
|
||||
required this.updatingNodeId,
|
||||
this.modificationPrompt = '',
|
||||
this.scope = 'self',
|
||||
this.isUpdating = false,
|
||||
this.nodeRenderStates = const {},
|
||||
this.renderedNodeIds = const {},
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
strategies,
|
||||
sessions,
|
||||
activeSessionId,
|
||||
activeSession,
|
||||
selectedNodeId,
|
||||
viewMode,
|
||||
adjustmentPrompt,
|
||||
pendingChanges,
|
||||
highlightedNodeIds,
|
||||
editHistory,
|
||||
events,
|
||||
message,
|
||||
updatingNodeId,
|
||||
modificationPrompt,
|
||||
scope,
|
||||
isUpdating,
|
||||
nodeRenderStates,
|
||||
renderedNodeIds,
|
||||
];
|
||||
|
||||
SettingGenerationNodeUpdating copyWith({
|
||||
List<StrategyTemplateInfo>? strategies,
|
||||
List<SettingGenerationSession>? sessions,
|
||||
String? activeSessionId,
|
||||
SettingGenerationSession? activeSession,
|
||||
String? selectedNodeId,
|
||||
String? viewMode,
|
||||
String? adjustmentPrompt,
|
||||
Map<String, SettingNode>? pendingChanges,
|
||||
Set<String>? highlightedNodeIds,
|
||||
Map<String, List<SettingNode>>? editHistory,
|
||||
List<event_model.SettingGenerationEvent>? events,
|
||||
String? message,
|
||||
String? updatingNodeId,
|
||||
String? modificationPrompt,
|
||||
String? scope,
|
||||
bool? isUpdating,
|
||||
Map<String, NodeRenderInfo>? nodeRenderStates,
|
||||
Set<String>? renderedNodeIds,
|
||||
}) {
|
||||
return SettingGenerationNodeUpdating(
|
||||
strategies: strategies ?? this.strategies,
|
||||
sessions: sessions ?? this.sessions,
|
||||
activeSessionId: activeSessionId ?? this.activeSessionId,
|
||||
activeSession: activeSession ?? this.activeSession,
|
||||
selectedNodeId: selectedNodeId ?? this.selectedNodeId,
|
||||
viewMode: viewMode ?? this.viewMode,
|
||||
adjustmentPrompt: adjustmentPrompt ?? this.adjustmentPrompt,
|
||||
pendingChanges: pendingChanges ?? this.pendingChanges,
|
||||
highlightedNodeIds: highlightedNodeIds ?? this.highlightedNodeIds,
|
||||
editHistory: editHistory ?? this.editHistory,
|
||||
events: events ?? this.events,
|
||||
message: message ?? this.message,
|
||||
updatingNodeId: updatingNodeId ?? this.updatingNodeId,
|
||||
modificationPrompt: modificationPrompt ?? this.modificationPrompt,
|
||||
scope: scope ?? this.scope,
|
||||
isUpdating: isUpdating ?? this.isUpdating,
|
||||
nodeRenderStates: nodeRenderStates ?? this.nodeRenderStates,
|
||||
renderedNodeIds: renderedNodeIds ?? this.renderedNodeIds,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取当前选中的节点
|
||||
SettingNode? get selectedNode {
|
||||
if (selectedNodeId == null) return null;
|
||||
return SettingNodeUtils.findNodeInTree(activeSession.rootNodes, selectedNodeId!);
|
||||
}
|
||||
|
||||
/// 获取正在修改的节点
|
||||
SettingNode? get updatingNode {
|
||||
return SettingNodeUtils.findNodeInTree(activeSession.rootNodes, updatingNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
/// 保存成功
|
||||
class SettingGenerationSaved extends SettingGenerationState {
|
||||
final List<String> savedSettingIds;
|
||||
final String message;
|
||||
// 新增:保留会话列表和当前活跃会话ID,避免UI刷新
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String? activeSessionId;
|
||||
|
||||
const SettingGenerationSaved({
|
||||
required this.savedSettingIds,
|
||||
this.message = '设定已成功保存',
|
||||
this.sessions = const [],
|
||||
this.activeSessionId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [savedSettingIds, message, sessions, activeSessionId];
|
||||
}
|
||||
|
||||
/// 错误状态
|
||||
class SettingGenerationError extends SettingGenerationState {
|
||||
final String message;
|
||||
final dynamic error;
|
||||
final StackTrace? stackTrace;
|
||||
final bool isRecoverable;
|
||||
// 新增:保留会话列表和当前活跃会话 ID,避免 UI 在错误时丢失历史记录
|
||||
final List<SettingGenerationSession> sessions;
|
||||
final String? activeSessionId;
|
||||
|
||||
const SettingGenerationError({
|
||||
required this.message,
|
||||
this.error,
|
||||
this.stackTrace,
|
||||
this.isRecoverable = true,
|
||||
this.sessions = const [],
|
||||
this.activeSessionId,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
message,
|
||||
error,
|
||||
stackTrace,
|
||||
isRecoverable,
|
||||
sessions,
|
||||
activeSessionId,
|
||||
];
|
||||
|
||||
SettingGenerationError copyWith({
|
||||
String? message,
|
||||
dynamic error,
|
||||
StackTrace? stackTrace,
|
||||
bool? isRecoverable,
|
||||
List<SettingGenerationSession>? sessions,
|
||||
String? activeSessionId,
|
||||
}) {
|
||||
return SettingGenerationError(
|
||||
message: message ?? this.message,
|
||||
error: error ?? this.error,
|
||||
stackTrace: stackTrace ?? this.stackTrace,
|
||||
isRecoverable: isRecoverable ?? this.isRecoverable,
|
||||
sessions: sessions ?? this.sessions,
|
||||
activeSessionId: activeSessionId ?? this.activeSessionId,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user