马良AI写作初始化仓库

This commit is contained in:
邓滨杰
2025-09-10 00:07:52 +08:00
parent 3c06bb1a03
commit 39c0f8840f
1309 changed files with 318528 additions and 0 deletions

View File

@@ -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,
);
}
}