init
This commit is contained in:
139
client/lib/features/speaking/data/ai_tutor_data.dart
Normal file
139
client/lib/features/speaking/data/ai_tutor_data.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
import '../models/ai_tutor.dart';
|
||||
|
||||
/// AI导师静态数据
|
||||
class AITutorData {
|
||||
static final List<AITutor> _tutors = [
|
||||
AITutor(
|
||||
id: 'tutor_business_001',
|
||||
type: TutorType.business,
|
||||
name: 'Emma Wilson',
|
||||
avatar: '👩💼',
|
||||
introduction: '我是Emma,拥有10年国际商务经验的专业导师。我将帮助你掌握商务英语,提升职场沟通能力。',
|
||||
specialties: [
|
||||
'商务会议主持',
|
||||
'产品演示与推介',
|
||||
'商务谈判技巧',
|
||||
'邮件沟通礼仪',
|
||||
'客户关系维护',
|
||||
'团队协作沟通',
|
||||
],
|
||||
sampleQuestions: [
|
||||
'Could you tell me about your company\'s main products?',
|
||||
'What\'s your strategy for the next quarter?',
|
||||
'How do you handle difficult clients?',
|
||||
'Can you walk me through your proposal?',
|
||||
'What are the key benefits of this solution?',
|
||||
],
|
||||
personality: '专业、严谨、富有耐心,善于引导学员进行深度商务对话',
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 30)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
),
|
||||
|
||||
AITutor(
|
||||
id: 'tutor_daily_001',
|
||||
type: TutorType.daily,
|
||||
name: 'Mike Johnson',
|
||||
avatar: '👨🦱',
|
||||
introduction: '嗨!我是Mike,一个热爱生活的英语导师。让我们一起在轻松愉快的氛围中提升你的日常英语交流能力!',
|
||||
specialties: [
|
||||
'日常生活对话',
|
||||
'购物与消费',
|
||||
'餐厅用餐',
|
||||
'交通出行',
|
||||
'社交聚会',
|
||||
'兴趣爱好分享',
|
||||
],
|
||||
sampleQuestions: [
|
||||
'What did you do over the weekend?',
|
||||
'How was your day today?',
|
||||
'What\'s your favorite type of food?',
|
||||
'Do you have any hobbies?',
|
||||
'What\'s the weather like today?',
|
||||
],
|
||||
personality: '友好、幽默、平易近人,善于创造轻松的对话氛围',
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 25)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
),
|
||||
|
||||
AITutor(
|
||||
id: 'tutor_travel_001',
|
||||
type: TutorType.travel,
|
||||
name: 'Sarah Chen',
|
||||
avatar: '👩✈️',
|
||||
introduction: '我是Sarah,环游过50多个国家的旅行达人。我会教你在世界各地都能自信交流的旅行英语!',
|
||||
specialties: [
|
||||
'机场办理手续',
|
||||
'酒店预订入住',
|
||||
'问路与导航',
|
||||
'景点游览',
|
||||
'紧急情况处理',
|
||||
'文化交流',
|
||||
],
|
||||
sampleQuestions: [
|
||||
'Where would you like to go for your next trip?',
|
||||
'Have you ever been to any foreign countries?',
|
||||
'What\'s your favorite travel destination?',
|
||||
'How do you usually plan your trips?',
|
||||
'What would you do if you got lost in a foreign city?',
|
||||
],
|
||||
personality: '热情、冒险、见多识广,能分享丰富的旅行经验',
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 20)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
),
|
||||
|
||||
AITutor(
|
||||
id: 'tutor_academic_001',
|
||||
type: TutorType.academic,
|
||||
name: 'Dr. Robert Smith',
|
||||
avatar: '👨🎓',
|
||||
introduction: '我是Robert博士,在学术界工作了15年。我将帮助你掌握学术英语,提升演讲和论文写作能力。',
|
||||
specialties: [
|
||||
'学术演讲技巧',
|
||||
'论文讨论',
|
||||
'研究方法论述',
|
||||
'学术会议参与',
|
||||
'同行评议',
|
||||
'批判性思维表达',
|
||||
],
|
||||
sampleQuestions: [
|
||||
'What\'s your research focus?',
|
||||
'How would you approach this research problem?',
|
||||
'What are the limitations of this study?',
|
||||
'Can you explain your methodology?',
|
||||
'What are the implications of these findings?',
|
||||
],
|
||||
personality: '博学、严谨、启发性强,善于引导深度学术思考',
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 15)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
),
|
||||
];
|
||||
|
||||
/// 获取所有AI导师
|
||||
static List<AITutor> getAllTutors() {
|
||||
return List.unmodifiable(_tutors);
|
||||
}
|
||||
|
||||
/// 根据ID获取AI导师
|
||||
static AITutor? getTutorById(String id) {
|
||||
try {
|
||||
return _tutors.firstWhere((tutor) => tutor.id == id);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 根据类型获取AI导师
|
||||
static AITutor? getTutorByType(TutorType type) {
|
||||
try {
|
||||
return _tutors.firstWhere((tutor) => tutor.type == type);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取推荐的AI导师
|
||||
static List<AITutor> getRecommendedTutors() {
|
||||
// 返回所有导师,实际应用中可以根据用户偏好推荐
|
||||
return getAllTutors();
|
||||
}
|
||||
}
|
||||
304
client/lib/features/speaking/data/pronunciation_data.dart
Normal file
304
client/lib/features/speaking/data/pronunciation_data.dart
Normal file
@@ -0,0 +1,304 @@
|
||||
import '../models/pronunciation_item.dart';
|
||||
|
||||
/// 发音练习静态数据
|
||||
class PronunciationData {
|
||||
static final List<PronunciationItem> _wordPronunciation = [
|
||||
PronunciationItem(
|
||||
id: 'word_001',
|
||||
text: 'pronunciation',
|
||||
phonetic: '/prəˌnʌnsiˈeɪʃn/',
|
||||
audioUrl: 'assets/audio/pronunciation.mp3',
|
||||
type: PronunciationType.word,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '学习词汇',
|
||||
tips: [
|
||||
'注意重音在第四个音节',
|
||||
'末尾的-tion读作/ʃn/',
|
||||
'中间的nun要清晰发音'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'word_002',
|
||||
text: 'communication',
|
||||
phonetic: '/kəˌmjuːnɪˈkeɪʃn/',
|
||||
audioUrl: 'assets/audio/communication.mp3',
|
||||
type: PronunciationType.word,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '商务词汇',
|
||||
tips: [
|
||||
'重音在第五个音节',
|
||||
'注意/mju:/的发音',
|
||||
'末尾-tion读作/ʃn/'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'word_003',
|
||||
text: 'restaurant',
|
||||
phonetic: '/ˈrestərɑːnt/',
|
||||
audioUrl: 'assets/audio/restaurant.mp3',
|
||||
type: PronunciationType.word,
|
||||
difficulty: DifficultyLevel.beginner,
|
||||
category: '日常词汇',
|
||||
tips: [
|
||||
'重音在第一个音节',
|
||||
'注意/r/音的发音',
|
||||
'末尾的t通常不发音'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'word_004',
|
||||
text: 'schedule',
|
||||
phonetic: '/ˈʃedjuːl/',
|
||||
audioUrl: 'assets/audio/schedule.mp3',
|
||||
type: PronunciationType.word,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '工作词汇',
|
||||
tips: [
|
||||
'英式发音以/ʃ/开头',
|
||||
'美式发音以/sk/开头',
|
||||
'重音在第一个音节'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'word_005',
|
||||
text: 'comfortable',
|
||||
phonetic: '/ˈkʌmftəbl/',
|
||||
audioUrl: 'assets/audio/comfortable.mp3',
|
||||
type: PronunciationType.word,
|
||||
difficulty: DifficultyLevel.advanced,
|
||||
category: '形容词',
|
||||
tips: [
|
||||
'注意弱读音节',
|
||||
'中间的or通常省略',
|
||||
'末尾的-able读作/əbl/'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
];
|
||||
|
||||
static final List<PronunciationItem> _sentencePronunciation = [
|
||||
PronunciationItem(
|
||||
id: 'sentence_001',
|
||||
text: 'How are you doing today?',
|
||||
phonetic: '/haʊ ɑːr juː ˈduːɪŋ təˈdeɪ/',
|
||||
audioUrl: 'assets/audio/how_are_you.mp3',
|
||||
type: PronunciationType.sentence,
|
||||
difficulty: DifficultyLevel.beginner,
|
||||
category: '日常问候',
|
||||
tips: [
|
||||
'注意连读:How are → /haʊər/',
|
||||
'语调上扬表示疑问',
|
||||
'today重音在第二个音节'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'sentence_002',
|
||||
text: 'Could you please help me with this?',
|
||||
phonetic: '/kʊd juː pliːz help miː wɪð ðɪs/',
|
||||
audioUrl: 'assets/audio/could_you_help.mp3',
|
||||
type: PronunciationType.sentence,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '请求帮助',
|
||||
tips: [
|
||||
'礼貌的语调,温和下降',
|
||||
'注意could的弱读',
|
||||
'with this连读'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'sentence_003',
|
||||
text: 'I would like to make a reservation.',
|
||||
phonetic: '/aɪ wʊd laɪk tuː meɪk ə ˌrezərˈveɪʃn/',
|
||||
audioUrl: 'assets/audio/reservation.mp3',
|
||||
type: PronunciationType.sentence,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '预订服务',
|
||||
tips: [
|
||||
'正式语调,清晰发音',
|
||||
'would like连读',
|
||||
'reservation重音在第三个音节'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'sentence_004',
|
||||
text: 'The weather is absolutely beautiful today.',
|
||||
phonetic: '/ðə ˈweðər ɪz ˌæbsəˈluːtli ˈbjuːtɪfl təˈdeɪ/',
|
||||
audioUrl: 'assets/audio/weather_beautiful.mp3',
|
||||
type: PronunciationType.sentence,
|
||||
difficulty: DifficultyLevel.advanced,
|
||||
category: '天气描述',
|
||||
tips: [
|
||||
'注意节奏和重音分布',
|
||||
'absolutely的重音模式',
|
||||
'形容词的语调变化'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'sentence_005',
|
||||
text: 'I am looking forward to hearing from you.',
|
||||
phonetic: '/aɪ æm ˈlʊkɪŋ ˈfɔːrwərd tuː ˈhɪrɪŋ frəm juː/',
|
||||
audioUrl: 'assets/audio/looking_forward.mp3',
|
||||
type: PronunciationType.sentence,
|
||||
difficulty: DifficultyLevel.advanced,
|
||||
category: '商务表达',
|
||||
tips: [
|
||||
'正式商务语调',
|
||||
'注意短语的完整性',
|
||||
'forward to连读'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
];
|
||||
|
||||
static final List<PronunciationItem> _phrasePronunciation = [
|
||||
PronunciationItem(
|
||||
id: 'phrase_001',
|
||||
text: 'Nice to meet you',
|
||||
phonetic: '/naɪs tuː miːt juː/',
|
||||
audioUrl: 'assets/audio/nice_to_meet.mp3',
|
||||
type: PronunciationType.phrase,
|
||||
difficulty: DifficultyLevel.beginner,
|
||||
category: '问候语',
|
||||
tips: [
|
||||
'连读:Nice to → /naɪstə/',
|
||||
'友好的语调',
|
||||
'重音在Nice和meet上'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'phrase_002',
|
||||
text: 'Thank you very much',
|
||||
phonetic: '/θæŋk juː ˈveri mʌtʃ/',
|
||||
audioUrl: 'assets/audio/thank_you_much.mp3',
|
||||
type: PronunciationType.phrase,
|
||||
difficulty: DifficultyLevel.beginner,
|
||||
category: '感谢语',
|
||||
tips: [
|
||||
'注意th音的发音',
|
||||
'very much重音分布',
|
||||
'真诚的语调'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'phrase_003',
|
||||
text: 'Excuse me',
|
||||
phonetic: '/ɪkˈskjuːz miː/',
|
||||
audioUrl: 'assets/audio/excuse_me.mp3',
|
||||
type: PronunciationType.phrase,
|
||||
difficulty: DifficultyLevel.beginner,
|
||||
category: '礼貌用语',
|
||||
tips: [
|
||||
'重音在excuse的第二个音节',
|
||||
'礼貌的上升语调',
|
||||
'清晰的/z/音'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
];
|
||||
|
||||
static final List<PronunciationItem> _phonemePronunciation = [
|
||||
PronunciationItem(
|
||||
id: 'phoneme_001',
|
||||
text: '/θ/ - think, three, thank',
|
||||
phonetic: '/θ/',
|
||||
audioUrl: 'assets/audio/th_sound.mp3',
|
||||
type: PronunciationType.phoneme,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '辅音',
|
||||
tips: [
|
||||
'舌尖轻触上齿',
|
||||
'气流从舌齿间通过',
|
||||
'不要发成/s/或/f/'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'phoneme_002',
|
||||
text: '/r/ - red, right, very',
|
||||
phonetic: '/r/',
|
||||
audioUrl: 'assets/audio/r_sound.mp3',
|
||||
type: PronunciationType.phoneme,
|
||||
difficulty: DifficultyLevel.advanced,
|
||||
category: '辅音',
|
||||
tips: [
|
||||
'舌尖向上卷起',
|
||||
'不要触碰口腔任何部位',
|
||||
'声带振动'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
PronunciationItem(
|
||||
id: 'phoneme_003',
|
||||
text: '/æ/ - cat, hat, bad',
|
||||
phonetic: '/æ/',
|
||||
audioUrl: 'assets/audio/ae_sound.mp3',
|
||||
type: PronunciationType.phoneme,
|
||||
difficulty: DifficultyLevel.intermediate,
|
||||
category: '元音',
|
||||
tips: [
|
||||
'嘴巴张得比/e/大',
|
||||
'舌位较低',
|
||||
'短元音,发音清脆'
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
];
|
||||
|
||||
/// 获取所有发音练习项目
|
||||
static List<PronunciationItem> getAllItems() {
|
||||
return [
|
||||
..._wordPronunciation,
|
||||
..._sentencePronunciation,
|
||||
..._phrasePronunciation,
|
||||
..._phonemePronunciation,
|
||||
];
|
||||
}
|
||||
|
||||
/// 根据类型获取发音练习项目
|
||||
static List<PronunciationItem> getItemsByType(PronunciationType type) {
|
||||
switch (type) {
|
||||
case PronunciationType.word:
|
||||
return _wordPronunciation;
|
||||
case PronunciationType.sentence:
|
||||
return _sentencePronunciation;
|
||||
case PronunciationType.phrase:
|
||||
return _phrasePronunciation;
|
||||
case PronunciationType.phoneme:
|
||||
return _phonemePronunciation;
|
||||
}
|
||||
}
|
||||
|
||||
/// 根据难度获取发音练习项目
|
||||
static List<PronunciationItem> getItemsByDifficulty(DifficultyLevel difficulty) {
|
||||
return getAllItems().where((item) => item.difficulty == difficulty).toList();
|
||||
}
|
||||
|
||||
/// 根据分类获取发音练习项目
|
||||
static List<PronunciationItem> getItemsByCategory(String category) {
|
||||
return getAllItems().where((item) => item.category == category).toList();
|
||||
}
|
||||
|
||||
/// 根据ID获取发音练习项目
|
||||
static PronunciationItem? getItemById(String id) {
|
||||
try {
|
||||
return getAllItems().firstWhere((item) => item.id == id);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取所有分类
|
||||
static List<String> getAllCategories() {
|
||||
return getAllItems().map((item) => item.category).toSet().toList();
|
||||
}
|
||||
}
|
||||
304
client/lib/features/speaking/data/scenario_data.dart
Normal file
304
client/lib/features/speaking/data/scenario_data.dart
Normal file
@@ -0,0 +1,304 @@
|
||||
import '../models/conversation_scenario.dart';
|
||||
|
||||
/// 对话场景静态数据
|
||||
class ScenarioData {
|
||||
static final List<ConversationScenario> _scenarios = [
|
||||
ConversationScenario(
|
||||
id: 'restaurant_ordering',
|
||||
title: 'Ordering Food at Restaurant',
|
||||
subtitle: '餐厅点餐对话',
|
||||
description: '学习在餐厅点餐的常用英语表达,包括询问菜单、下订单、特殊要求等。',
|
||||
duration: '10分钟',
|
||||
level: 'B1',
|
||||
type: ScenarioType.restaurant,
|
||||
objectives: [
|
||||
'学会阅读英文菜单',
|
||||
'掌握点餐的基本表达',
|
||||
'学会提出特殊要求',
|
||||
'了解餐厅服务流程',
|
||||
],
|
||||
keyPhrases: [
|
||||
'I\'d like to order...',
|
||||
'What do you recommend?',
|
||||
'Could I have the menu, please?',
|
||||
'I\'m allergic to...',
|
||||
'Could you make it less spicy?',
|
||||
'Check, please.',
|
||||
],
|
||||
steps: [
|
||||
ScenarioStep(
|
||||
stepNumber: 1,
|
||||
title: '入座问候',
|
||||
description: '服务员引导您入座并提供菜单',
|
||||
role: 'npc',
|
||||
content: 'Good evening! Welcome to our restaurant. How many people are in your party?',
|
||||
options: [
|
||||
'Just one, please.',
|
||||
'Table for two, please.',
|
||||
'We have a reservation under Smith.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 2,
|
||||
title: '查看菜单',
|
||||
description: '服务员询问您是否需要时间看菜单',
|
||||
role: 'npc',
|
||||
content: 'Here\'s your table. Would you like to see the menu, or do you need a few minutes?',
|
||||
options: [
|
||||
'Could I have the menu, please?',
|
||||
'I need a few minutes to decide.',
|
||||
'What do you recommend?',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 3,
|
||||
title: '点餐',
|
||||
description: '服务员准备为您点餐',
|
||||
role: 'npc',
|
||||
content: 'Are you ready to order, or would you like to hear about our specials?',
|
||||
options: [
|
||||
'I\'d like to hear about the specials.',
|
||||
'I\'m ready to order.',
|
||||
'Could you give me a few more minutes?',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 4,
|
||||
title: '下订单',
|
||||
description: '告诉服务员您想要什么',
|
||||
role: 'user',
|
||||
content: 'What would you like to order?',
|
||||
options: [
|
||||
'I\'d like the grilled salmon, please.',
|
||||
'Could I have the pasta with marinara sauce?',
|
||||
'I\'ll have the chicken Caesar salad.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 5,
|
||||
title: '特殊要求',
|
||||
description: '提出任何特殊的饮食要求',
|
||||
role: 'npc',
|
||||
content: 'How would you like that cooked? Any special requests?',
|
||||
options: [
|
||||
'Medium rare, please.',
|
||||
'Could you make it less spicy?',
|
||||
'I\'m allergic to nuts, please make sure there are none.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
ConversationScenario(
|
||||
id: 'job_interview',
|
||||
title: 'Job Interview Practice',
|
||||
subtitle: '工作面试练习',
|
||||
description: '模拟真实的英语工作面试场景,练习自我介绍、回答常见问题和提问技巧。',
|
||||
duration: '15分钟',
|
||||
level: 'B2',
|
||||
type: ScenarioType.interview,
|
||||
objectives: [
|
||||
'掌握自我介绍技巧',
|
||||
'学会回答常见面试问题',
|
||||
'练习询问公司信息',
|
||||
'提高面试自信心',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Tell me about yourself.',
|
||||
'What are your strengths?',
|
||||
'Why do you want this job?',
|
||||
'Where do you see yourself in 5 years?',
|
||||
'Do you have any questions for us?',
|
||||
'Thank you for your time.',
|
||||
],
|
||||
steps: [
|
||||
ScenarioStep(
|
||||
stepNumber: 1,
|
||||
title: '面试开始',
|
||||
description: '面试官欢迎您并开始面试',
|
||||
role: 'npc',
|
||||
content: 'Good morning! Please have a seat. Thank you for coming in today.',
|
||||
options: [
|
||||
'Good morning! Thank you for having me.',
|
||||
'Hello! I\'m excited to be here.',
|
||||
'Thank you for the opportunity.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 2,
|
||||
title: '自我介绍',
|
||||
description: '面试官要求您进行自我介绍',
|
||||
role: 'npc',
|
||||
content: 'Let\'s start with you telling me a little bit about yourself.',
|
||||
options: [
|
||||
'I have 5 years of experience in marketing...',
|
||||
'I\'m a recent graduate with a degree in...',
|
||||
'I\'m currently working as a... and looking for new challenges.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 3,
|
||||
title: '优势询问',
|
||||
description: '面试官询问您的优势',
|
||||
role: 'npc',
|
||||
content: 'What would you say are your greatest strengths?',
|
||||
options: [
|
||||
'I\'m very detail-oriented and organized.',
|
||||
'I work well under pressure and meet deadlines.',
|
||||
'I\'m a strong team player with good communication skills.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 4,
|
||||
title: '职业规划',
|
||||
description: '面试官询问您的职业规划',
|
||||
role: 'npc',
|
||||
content: 'Where do you see yourself in five years?',
|
||||
options: [
|
||||
'I see myself in a leadership role, managing a team.',
|
||||
'I want to become an expert in my field.',
|
||||
'I hope to have grown professionally and taken on more responsibilities.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 5,
|
||||
title: '提问环节',
|
||||
description: '面试官询问您是否有问题',
|
||||
role: 'npc',
|
||||
content: 'Do you have any questions about the company or the position?',
|
||||
options: [
|
||||
'What does a typical day look like in this role?',
|
||||
'What are the opportunities for professional development?',
|
||||
'What do you enjoy most about working here?',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
ConversationScenario(
|
||||
id: 'business_meeting',
|
||||
title: 'Business Meeting Discussion',
|
||||
subtitle: '商务会议讨论',
|
||||
description: '参与英语商务会议,学习表达观点、提出建议和进行专业讨论。',
|
||||
duration: '20分钟',
|
||||
level: 'C1',
|
||||
type: ScenarioType.business,
|
||||
objectives: [
|
||||
'学会在会议中表达观点',
|
||||
'掌握商务讨论技巧',
|
||||
'练习提出建议和反对意见',
|
||||
'提高商务英语水平',
|
||||
],
|
||||
keyPhrases: [
|
||||
'I\'d like to propose...',
|
||||
'From my perspective...',
|
||||
'I agree with your point, however...',
|
||||
'Could we consider...',
|
||||
'Let\'s move on to the next item.',
|
||||
'To summarize...',
|
||||
],
|
||||
steps: [
|
||||
ScenarioStep(
|
||||
stepNumber: 1,
|
||||
title: '会议开始',
|
||||
description: '会议主持人开始会议并介绍议程',
|
||||
role: 'npc',
|
||||
content: 'Good morning, everyone. Let\'s begin today\'s meeting. Our main agenda is to discuss the new marketing strategy.',
|
||||
options: [
|
||||
'Good morning! I\'m looking forward to the discussion.',
|
||||
'Thank you for organizing this meeting.',
|
||||
'I have some ideas I\'d like to share.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 2,
|
||||
title: '观点表达',
|
||||
description: '主持人邀请您分享观点',
|
||||
role: 'npc',
|
||||
content: 'What are your thoughts on our current marketing approach?',
|
||||
options: [
|
||||
'I think we should focus more on digital marketing.',
|
||||
'From my perspective, we need to target younger demographics.',
|
||||
'I believe our current strategy is effective, but we could improve...',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 3,
|
||||
title: '建议提出',
|
||||
description: '有人提出了一个建议,您需要回应',
|
||||
role: 'npc',
|
||||
content: 'I propose we increase our social media budget by 30%. What do you think?',
|
||||
options: [
|
||||
'That\'s an interesting proposal. Could we see some data first?',
|
||||
'I agree, but we should also consider the ROI.',
|
||||
'I have some concerns about that approach.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 4,
|
||||
title: '讨论深入',
|
||||
description: '深入讨论具体实施方案',
|
||||
role: 'npc',
|
||||
content: 'How do you suggest we implement this new strategy?',
|
||||
options: [
|
||||
'We could start with a pilot program.',
|
||||
'I recommend we form a dedicated team.',
|
||||
'Let\'s set clear milestones and deadlines.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
ScenarioStep(
|
||||
stepNumber: 5,
|
||||
title: '会议总结',
|
||||
description: '总结会议要点和下一步行动',
|
||||
role: 'npc',
|
||||
content: 'Let\'s summarize what we\'ve discussed and assign action items.',
|
||||
options: [
|
||||
'I can take responsibility for the market research.',
|
||||
'Should we schedule a follow-up meeting?',
|
||||
'I\'ll prepare a detailed proposal by next week.',
|
||||
],
|
||||
correctOption: null,
|
||||
),
|
||||
],
|
||||
createdAt: DateTime.now(),
|
||||
),
|
||||
];
|
||||
|
||||
/// 获取所有场景
|
||||
static List<ConversationScenario> getAllScenarios() {
|
||||
return List.from(_scenarios);
|
||||
}
|
||||
|
||||
/// 根据ID获取场景
|
||||
static ConversationScenario? getScenarioById(String id) {
|
||||
try {
|
||||
return _scenarios.firstWhere((scenario) => scenario.id == id);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 根据类型获取场景
|
||||
static List<ConversationScenario> getScenariosByType(ScenarioType type) {
|
||||
return _scenarios.where((scenario) => scenario.type == type).toList();
|
||||
}
|
||||
|
||||
/// 根据难度级别获取场景
|
||||
static List<ConversationScenario> getScenariosByLevel(String level) {
|
||||
return _scenarios.where((scenario) => scenario.level == level).toList();
|
||||
}
|
||||
}
|
||||
338
client/lib/features/speaking/data/speaking_static_data.dart
Normal file
338
client/lib/features/speaking/data/speaking_static_data.dart
Normal file
@@ -0,0 +1,338 @@
|
||||
import '../models/speaking_scenario.dart';
|
||||
|
||||
/// 口语练习静态数据
|
||||
class SpeakingStaticData {
|
||||
static final List<SpeakingTask> _tasks = [
|
||||
// 日常对话场景
|
||||
SpeakingTask(
|
||||
id: 'daily_001',
|
||||
title: '自我介绍',
|
||||
description: '学习如何进行基本的自我介绍',
|
||||
scenario: SpeakingScenario.dailyConversation,
|
||||
difficulty: SpeakingDifficulty.beginner,
|
||||
objectives: [
|
||||
'能够清晰地介绍自己的姓名、年龄和职业',
|
||||
'掌握基本的问候语和礼貌用语',
|
||||
'学会询问他人的基本信息',
|
||||
],
|
||||
keyPhrases: [
|
||||
'My name is...',
|
||||
'I am from...',
|
||||
'I work as...',
|
||||
'Nice to meet you',
|
||||
'How about you?',
|
||||
],
|
||||
backgroundInfo: '在日常生活中,自我介绍是最基本的社交技能。无论是在工作场合还是社交聚会,都需要用到这项技能。',
|
||||
estimatedDuration: 10,
|
||||
isRecommended: true,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 30)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 30)),
|
||||
),
|
||||
|
||||
SpeakingTask(
|
||||
id: 'daily_002',
|
||||
title: '询问方向',
|
||||
description: '学习如何询问和指示方向',
|
||||
scenario: SpeakingScenario.dailyConversation,
|
||||
difficulty: SpeakingDifficulty.elementary,
|
||||
objectives: [
|
||||
'能够礼貌地询问方向',
|
||||
'理解和给出简单的方向指示',
|
||||
'掌握常用的地点和方向词汇',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Excuse me, where is...?',
|
||||
'How can I get to...?',
|
||||
'Go straight',
|
||||
'Turn left/right',
|
||||
'It\'s on your left/right',
|
||||
],
|
||||
estimatedDuration: 15,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 25)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 25)),
|
||||
),
|
||||
|
||||
// 商务会议场景
|
||||
SpeakingTask(
|
||||
id: 'business_001',
|
||||
title: '会议开场',
|
||||
description: '学习如何主持和参与会议开场',
|
||||
scenario: SpeakingScenario.businessMeeting,
|
||||
difficulty: SpeakingDifficulty.intermediate,
|
||||
objectives: [
|
||||
'能够正式地开始会议',
|
||||
'介绍会议议程和参与者',
|
||||
'掌握商务会议的基本礼仪',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Let\'s get started',
|
||||
'Today\'s agenda includes...',
|
||||
'I\'d like to introduce...',
|
||||
'The purpose of this meeting is...',
|
||||
'Any questions before we begin?',
|
||||
],
|
||||
backgroundInfo: '商务会议是职场中重要的沟通方式,掌握会议开场技巧能够提升专业形象。',
|
||||
estimatedDuration: 20,
|
||||
isRecommended: true,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 20)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 20)),
|
||||
),
|
||||
|
||||
SpeakingTask(
|
||||
id: 'business_002',
|
||||
title: '产品介绍',
|
||||
description: '学习如何向客户介绍产品',
|
||||
scenario: SpeakingScenario.businessMeeting,
|
||||
difficulty: SpeakingDifficulty.upperIntermediate,
|
||||
objectives: [
|
||||
'能够清晰地描述产品特点',
|
||||
'强调产品的优势和价值',
|
||||
'回答客户的疑问',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Our product features...',
|
||||
'The main benefit is...',
|
||||
'This will help you...',
|
||||
'Compared to competitors...',
|
||||
'Would you like to know more about...?',
|
||||
],
|
||||
estimatedDuration: 25,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 18)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 18)),
|
||||
),
|
||||
|
||||
// 求职面试场景
|
||||
SpeakingTask(
|
||||
id: 'interview_001',
|
||||
title: '面试自我介绍',
|
||||
description: '学习面试中的专业自我介绍',
|
||||
scenario: SpeakingScenario.jobInterview,
|
||||
difficulty: SpeakingDifficulty.intermediate,
|
||||
objectives: [
|
||||
'能够简洁有力地介绍自己',
|
||||
'突出相关工作经验和技能',
|
||||
'展现对职位的兴趣和热情',
|
||||
],
|
||||
keyPhrases: [
|
||||
'I have X years of experience in...',
|
||||
'My background includes...',
|
||||
'I\'m particularly skilled at...',
|
||||
'I\'m excited about this opportunity because...',
|
||||
'I believe I would be a good fit because...',
|
||||
],
|
||||
backgroundInfo: '面试自我介绍是求职过程中的关键环节,需要在短时间内给面试官留下深刻印象。',
|
||||
estimatedDuration: 15,
|
||||
isRecommended: true,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 15)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 15)),
|
||||
),
|
||||
|
||||
// 购物场景
|
||||
SpeakingTask(
|
||||
id: 'shopping_001',
|
||||
title: '服装购买',
|
||||
description: '学习在服装店购物的对话',
|
||||
scenario: SpeakingScenario.shopping,
|
||||
difficulty: SpeakingDifficulty.elementary,
|
||||
objectives: [
|
||||
'能够询问商品信息',
|
||||
'表达对尺寸和颜色的需求',
|
||||
'进行价格谈判和付款',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Do you have this in size...?',
|
||||
'Can I try this on?',
|
||||
'How much does this cost?',
|
||||
'Do you accept credit cards?',
|
||||
'I\'ll take it',
|
||||
],
|
||||
estimatedDuration: 12,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 12)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 12)),
|
||||
),
|
||||
|
||||
// 餐厅场景
|
||||
SpeakingTask(
|
||||
id: 'restaurant_001',
|
||||
title: '餐厅点餐',
|
||||
description: '学习在餐厅点餐的完整流程',
|
||||
scenario: SpeakingScenario.restaurant,
|
||||
difficulty: SpeakingDifficulty.elementary,
|
||||
objectives: [
|
||||
'能够预订餐桌',
|
||||
'阅读菜单并点餐',
|
||||
'处理特殊饮食要求',
|
||||
],
|
||||
keyPhrases: [
|
||||
'I\'d like to make a reservation',
|
||||
'Can I see the menu?',
|
||||
'I\'ll have the...',
|
||||
'I\'m allergic to...',
|
||||
'Could I get the check, please?',
|
||||
],
|
||||
estimatedDuration: 18,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 10)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 10)),
|
||||
),
|
||||
|
||||
// 旅行场景
|
||||
SpeakingTask(
|
||||
id: 'travel_001',
|
||||
title: '机场办理登机',
|
||||
description: '学习在机场办理登机手续',
|
||||
scenario: SpeakingScenario.travel,
|
||||
difficulty: SpeakingDifficulty.intermediate,
|
||||
objectives: [
|
||||
'能够办理登机手续',
|
||||
'处理行李托运',
|
||||
'询问航班信息',
|
||||
],
|
||||
keyPhrases: [
|
||||
'I\'d like to check in',
|
||||
'Here\'s my passport',
|
||||
'I have one bag to check',
|
||||
'What gate is my flight?',
|
||||
'What time is boarding?',
|
||||
],
|
||||
backgroundInfo: '机场是国际旅行的重要场所,掌握相关英语对话能够让旅行更加顺利。',
|
||||
estimatedDuration: 20,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 8)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 8)),
|
||||
),
|
||||
|
||||
// 学术讨论场景
|
||||
SpeakingTask(
|
||||
id: 'academic_001',
|
||||
title: '课堂讨论',
|
||||
description: '学习参与学术课堂讨论',
|
||||
scenario: SpeakingScenario.academic,
|
||||
difficulty: SpeakingDifficulty.advanced,
|
||||
objectives: [
|
||||
'能够表达学术观点',
|
||||
'进行逻辑性论证',
|
||||
'礼貌地反驳不同观点',
|
||||
],
|
||||
keyPhrases: [
|
||||
'In my opinion...',
|
||||
'The evidence suggests...',
|
||||
'I disagree because...',
|
||||
'That\'s an interesting point, however...',
|
||||
'Could you elaborate on...?',
|
||||
],
|
||||
estimatedDuration: 30,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 5)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 5)),
|
||||
),
|
||||
|
||||
// 社交聚会场景
|
||||
SpeakingTask(
|
||||
id: 'social_001',
|
||||
title: '聚会闲聊',
|
||||
description: '学习在社交聚会中的轻松对话',
|
||||
scenario: SpeakingScenario.socializing,
|
||||
difficulty: SpeakingDifficulty.intermediate,
|
||||
objectives: [
|
||||
'能够进行轻松的闲聊',
|
||||
'分享个人兴趣和经历',
|
||||
'保持对话的自然流畅',
|
||||
],
|
||||
keyPhrases: [
|
||||
'How do you know the host?',
|
||||
'What do you do for fun?',
|
||||
'Have you been here before?',
|
||||
'That sounds interesting!',
|
||||
'I should probably get going',
|
||||
],
|
||||
estimatedDuration: 15,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 3)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 3)),
|
||||
),
|
||||
|
||||
// 演讲展示场景
|
||||
SpeakingTask(
|
||||
id: 'presentation_001',
|
||||
title: '产品演示',
|
||||
description: '学习进行产品演示和展示',
|
||||
scenario: SpeakingScenario.presentation,
|
||||
difficulty: SpeakingDifficulty.advanced,
|
||||
objectives: [
|
||||
'能够结构化地组织演示内容',
|
||||
'使用视觉辅助工具',
|
||||
'处理观众的问题和反馈',
|
||||
],
|
||||
keyPhrases: [
|
||||
'Today I\'ll be presenting...',
|
||||
'As you can see in this slide...',
|
||||
'Let me demonstrate...',
|
||||
'Are there any questions?',
|
||||
'Thank you for your attention',
|
||||
],
|
||||
backgroundInfo: '产品演示是商务环境中的重要技能,需要结合专业知识和演讲技巧。',
|
||||
estimatedDuration: 35,
|
||||
isRecommended: true,
|
||||
createdAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
updatedAt: DateTime.now().subtract(const Duration(days: 1)),
|
||||
),
|
||||
];
|
||||
|
||||
/// 获取所有任务
|
||||
static List<SpeakingTask> getAllTasks() {
|
||||
return List.from(_tasks);
|
||||
}
|
||||
|
||||
/// 根据场景获取任务
|
||||
static List<SpeakingTask> getTasksByScenario(SpeakingScenario scenario) {
|
||||
return _tasks.where((task) => task.scenario == scenario).toList();
|
||||
}
|
||||
|
||||
/// 根据难度获取任务
|
||||
static List<SpeakingTask> getTasksByDifficulty(SpeakingDifficulty difficulty) {
|
||||
return _tasks.where((task) => task.difficulty == difficulty).toList();
|
||||
}
|
||||
|
||||
/// 获取推荐任务
|
||||
static List<SpeakingTask> getRecommendedTasks() {
|
||||
return _tasks.where((task) => task.isRecommended).toList();
|
||||
}
|
||||
|
||||
/// 获取最近任务
|
||||
static List<SpeakingTask> getRecentTasks() {
|
||||
final sortedTasks = List<SpeakingTask>.from(_tasks);
|
||||
sortedTasks.sort((a, b) => b.updatedAt.compareTo(a.updatedAt));
|
||||
return sortedTasks.take(5).toList();
|
||||
}
|
||||
|
||||
/// 获取热门任务(按完成次数排序)
|
||||
static List<SpeakingTask> getPopularTasks() {
|
||||
final sortedTasks = List<SpeakingTask>.from(_tasks);
|
||||
sortedTasks.sort((a, b) => b.completionCount.compareTo(a.completionCount));
|
||||
return sortedTasks.take(5).toList();
|
||||
}
|
||||
|
||||
/// 根据ID获取任务
|
||||
static SpeakingTask? getTaskById(String id) {
|
||||
try {
|
||||
return _tasks.firstWhere((task) => task.id == id);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取场景统计
|
||||
static Map<SpeakingScenario, int> getScenarioStats() {
|
||||
final stats = <SpeakingScenario, int>{};
|
||||
for (final scenario in SpeakingScenario.values) {
|
||||
stats[scenario] = _tasks.where((task) => task.scenario == scenario).length;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
/// 获取难度统计
|
||||
static Map<SpeakingDifficulty, int> getDifficultyStats() {
|
||||
final stats = <SpeakingDifficulty, int>{};
|
||||
for (final difficulty in SpeakingDifficulty.values) {
|
||||
stats[difficulty] = _tasks.where((task) => task.difficulty == difficulty).length;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user