Files
ai_english/client/lib/features/speaking/models/conversation_scenario.dart
2025-11-17 13:39:05 +08:00

193 lines
4.8 KiB
Dart

/// 对话场景数据模型
class ConversationScenario {
final String id;
final String title;
final String subtitle;
final String description;
final String duration;
final String level;
final ScenarioType type;
final List<String> objectives;
final List<String> keyPhrases;
final List<ScenarioStep> steps;
final DateTime createdAt;
ConversationScenario({
required this.id,
required this.title,
required this.subtitle,
required this.description,
required this.duration,
required this.level,
required this.type,
required this.objectives,
required this.keyPhrases,
required this.steps,
required this.createdAt,
});
factory ConversationScenario.fromJson(Map<String, dynamic> json) {
return ConversationScenario(
id: json['id'],
title: json['title'],
subtitle: json['subtitle'],
description: json['description'],
duration: json['duration'],
level: json['level'],
type: ScenarioType.values.firstWhere(
(e) => e.toString().split('.').last == json['type'],
),
objectives: List<String>.from(json['objectives']),
keyPhrases: List<String>.from(json['keyPhrases']),
steps: (json['steps'] as List)
.map((step) => ScenarioStep.fromJson(step))
.toList(),
createdAt: DateTime.parse(json['createdAt']),
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'subtitle': subtitle,
'description': description,
'duration': duration,
'level': level,
'type': type.toString().split('.').last,
'objectives': objectives,
'keyPhrases': keyPhrases,
'steps': steps.map((step) => step.toJson()).toList(),
'createdAt': createdAt.toIso8601String(),
};
}
ConversationScenario copyWith({
String? id,
String? title,
String? subtitle,
String? description,
String? duration,
String? level,
ScenarioType? type,
List<String>? objectives,
List<String>? keyPhrases,
List<ScenarioStep>? steps,
DateTime? createdAt,
}) {
return ConversationScenario(
id: id ?? this.id,
title: title ?? this.title,
subtitle: subtitle ?? this.subtitle,
description: description ?? this.description,
duration: duration ?? this.duration,
level: level ?? this.level,
type: type ?? this.type,
objectives: objectives ?? this.objectives,
keyPhrases: keyPhrases ?? this.keyPhrases,
steps: steps ?? this.steps,
createdAt: createdAt ?? this.createdAt,
);
}
}
/// 场景类型枚举
enum ScenarioType {
restaurant,
interview,
business,
travel,
shopping,
medical,
education,
social,
}
extension ScenarioTypeExtension on ScenarioType {
String get displayName {
switch (this) {
case ScenarioType.restaurant:
return '餐厅用餐';
case ScenarioType.interview:
return '工作面试';
case ScenarioType.business:
return '商务会议';
case ScenarioType.travel:
return '旅行出行';
case ScenarioType.shopping:
return '购物消费';
case ScenarioType.medical:
return '医疗健康';
case ScenarioType.education:
return '教育学习';
case ScenarioType.social:
return '社交聚会';
}
}
String get icon {
switch (this) {
case ScenarioType.restaurant:
return '🍽️';
case ScenarioType.interview:
return '💼';
case ScenarioType.business:
return '🏢';
case ScenarioType.travel:
return '✈️';
case ScenarioType.shopping:
return '🛍️';
case ScenarioType.medical:
return '🏥';
case ScenarioType.education:
return '📚';
case ScenarioType.social:
return '🎉';
}
}
}
/// 场景步骤
class ScenarioStep {
final int stepNumber;
final String title;
final String description;
final String role; // 'user' or 'npc'
final String content;
final List<String> options;
final String? correctOption;
ScenarioStep({
required this.stepNumber,
required this.title,
required this.description,
required this.role,
required this.content,
required this.options,
this.correctOption,
});
factory ScenarioStep.fromJson(Map<String, dynamic> json) {
return ScenarioStep(
stepNumber: json['stepNumber'],
title: json['title'],
description: json['description'],
role: json['role'],
content: json['content'],
options: List<String>.from(json['options']),
correctOption: json['correctOption'],
);
}
Map<String, dynamic> toJson() {
return {
'stepNumber': stepNumber,
'title': title,
'description': description,
'role': role,
'content': content,
'options': options,
'correctOption': correctOption,
};
}
}