### 二、基于 AI 生成页面代码
通义灵码 agent 中输入:仔细阅读 apps/samples/src/views/language-learn/Readme.md 文档,根据文档在 apps/samples/src/views/language-learn/ 文件夹下生成 language-learn-app 的页面代码,要使用 TypeDom 前端框架参考项目下的其它页面的代码。
### 三、生成的代码
```typescript
import { TypeDiv, Div, Head, P, Span, Button, addDomClass, removeClass, renderClass } from '@type-dom/framework';
import { TdButton, } from '@type-dom/ui';
export class LanguageLearnApp extends TypeDiv {
className: 'LanguageLearnApp';
appData!: AppData;
currentView: 'home' | 'lessons' | 'vocabulary' | 'quiz' = 'home';
currentLessonIndex: number = 0;
currentVocabIndex: number = 0;
quizScore: number = 0;
totalQuizQuestions: number = 0;
constructor() {
super();
this.className = 'LanguageLearnApp';
this.initializeData();
this.setupStyles();
this.renderHomeView();
}
private initializeData(): void {
this.appData = {
appName: 'Language Master',
appSubtitle: '掌握语言的艺术',
user: {
name: '学习者',
level: '初级',
streak: 5,
totalXP: 1250
},
lessons: [
{
id: 1,
title: '基础问候语',
description: '学习日常问候和基本表达',
level: '入门',
duration: '15 分钟',
completed: false,
content: ['Hello - 你好', 'Good morning - 早上好', 'How are you? - 你好吗?', 'Thank you - 谢谢', 'Goodbye - 再见']
},
{
id: 2,
title: '数字和时间',
description: '掌握数数和询问时间',
level: '入门',
duration: '20 分钟',
completed: false,
content: ['One, Two, Three - 一、二、三', 'What time is it? - 现在几点?', 'Today - 今天', 'Tomorrow - 明天', 'Yesterday - 昨天']
},
{
id: 3,
title: '家庭成员',
description: '认识家庭成员的称呼',
level: '初级',
duration: '18 分钟',
completed: false,
content: ['Father/Mother - 父亲/母亲', 'Brother/Sister - 兄弟/姐妹', 'Grandfather/Grandmother - 祖父/祖母', 'Uncle/Aunt - 叔叔/阿姨', 'Cousin - 表兄弟姐妹']
}
],
vocabulary: [
{
id: 1,
word: 'Hello',
translation: '你好',
pronunciation: '/həˈloʊ/',
example: 'Hello, how are you today?',
exampleTranslation: '你好,今天怎么样?',
category: '问候语'
},
{
id: 2,
word: 'Thank you',
translation: '谢谢',
pronunciation: '/θæŋk juː/',
example: 'Thank you for your help.',
exampleTranslation: '谢谢你的帮助。',
category: '礼貌用语'
},
{
id: 3,
word: 'Family',
translation: '家庭',
pronunciation: '/ˈfæməli/',
example: 'My family is very supportive.',
exampleTranslation: '我的家人很支持我。',
category: '家庭'
},
{
id: 4,
word: 'Learning',
translation: '学习',
pronunciation: '/ˈlɜːrnɪng/',
example: 'I enjoy learning new languages.',
exampleTranslation: '我喜欢学习新语言。',
category: '学习'
},
{
id: 5,
word: 'Practice',
translation: '练习',
pronunciation: '/ˈpræktɪs/',
example: 'Practice makes perfect.',
exampleTranslation: '熟能生巧。',
category: '学习'
}
],
quizQuestions: [
{
id: 1,
question: '"Hello" 的中文意思是?',
options: ['再见', '你好', '谢谢', '对不起'],
correctAnswer: 1,
explanation: '"Hello" 是最基本的英语问候语,中文意思是"你好"'
},
{
id: 2,
question: '如何用英语说"谢谢"?',
options: ['Sorry', 'Thank you', 'Goodbye', 'Please'],
correctAnswer: 1,
explanation: '"Thank you" 是表达感谢的标准英语说法'
},
{
id: 3,
question: '"Family" 的中文翻译是?',
options: ['朋友', '学校', '家庭', '工作'],
correctAnswer: 2,
explanation: '"Family" 指的是家庭成员的集合'
},
{
id: 4,
question: '早上见面时应该说什么?',
options: ['Good night', 'Good evening', 'Good morning', 'Good afternoon'],
correctAnswer: 2,
explanation: '"Good morning" 是早上见面时的标准问候语'
},
{
id: 5,
question: '如何表达"我爱你"?',
options: ['I love you', 'I like you', 'I miss you', 'I need you'],
correctAnswer: 0,
explanation: '"I love you" 是表达爱意的标准英语表达'
}
]
};
}
private setupStyles(): void {
this.setStyleObj({
fontFamily: "'Inter', 'Poppins', Arial, sans-serif",
maxWidth: '1200px',
margin: '0 auto',
padding: '20px',
backgroundColor: '#f8fafc',
minHeight: '100vh'
});
// Add CSS styles
const style = document.createElement('style');
style.textContent = `
.app-container { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; }
.header { background: white; border-radius: 16px; padding: 25px; margin-bottom: 30px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); display: flex; justify-content: space-between; align-items: center; }
.user-info { display: flex; align-items: center; gap: 15px; }
.avatar { width: 50px; height: 50px; border-radius: 50%; background: linear-gradient(45deg, #3498db, #27ae60); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 20px; }
.nav-buttons { display: flex; gap: 12px; }
.nav-btn { background: #3498db; color: white; border: none; padding: 12px 20px; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease; }
.nav-btn:hover { background: #2980b9; transform: translateY(-2px); }
.nav-btn.active { background: #27ae60; }
.content-area { background: white; border-radius: 16px; padding: 30px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); min-height: 500px; }
.home-view { text-align: center; }
.welcome-section { margin-bottom: 40px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 30px 0; }
.stat-card { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 25px; border-radius: 12px; text-align: center; }
.stat-number { font-size: 2.5em; font-weight: bold; margin: 10px 0; }
.lesson-card, .vocab-card { background: #f8f9fa; border-radius: 12px; padding: 20px; margin: 15px 0; border-left: 4px solid #3498db; transition: transform 0.2s ease; }
.lesson-card:hover, .vocab-card:hover { transform: translateX(5px); box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
.card-title { font-size: 1.3em; font-weight: 600; color: #2c3e50; margin-bottom: 10px; }
.card-meta { display: flex; gap: 15px; margin: 10px 0; color: #7f8c8d; font-size: 0.9em; }
.quiz-question { background: #f8f9fa; padding: 25px; border-radius: 12px; margin: 20px 0; }
.option-btn { display: block; width: 100%; padding: 15px; margin: 10px 0; border: 2px solid #ddd; border-radius: 8px; background: white; cursor: pointer; text-align: left; font-size: 1.1em; transition: all 0.3s ease; }
.option-btn:hover { border-color: #3498db; background: #e3f2fd; }
.option-btn.selected { border-color: #3498db; background: #bbdefb; }
.option-btn.correct { border-color: #27ae60; background: #c8e6c9; }
.option-btn.incorrect { border-color: #e74c3c; background: #ffcdd2; }
.progress-bar { height: 12px; background: #ecf0f1; border-radius: 6px; overflow: hidden; margin: 20px 0; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #27ae60, #3498db); transition: width 0.5s ease; }
.action-btn { background: linear-gradient(45deg, #3498db, #27ae60); color: white; border: none; padding: 15px 30px; border-radius: 8px; cursor: pointer; font-size: 1.1em; font-weight: 600; margin: 10px; transition: all 0.3s ease; }
.action-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(0,0,0,0.2); }
.badge { display: inline-block; padding: 5px 12px; border-radius: 20px; font-size: 0.8em; font-weight: 600; }
.badge-primary { background: #3498db; color: white; }
.badge-success { background: #27ae60; color: white; }
.badge-warning { background: #f39c12; color: white; }
`;
document.head.appendChild(style);
}
private renderHomeView(): void {
console.warn('renderHomeView');
this.currentView = 'home';
this.clearChildren();
const container = new Div({ class: 'app-container' });
// Header container
container.addChild(this.createHeader());
// Content Area
const contentArea = new Div({ class: 'content-area' });
const welcomeSection = new Div({ class: 'home-view' });
welcomeSection.addChildren(
new Head({ tag: 'h1', slot: `欢迎来到 ${this.appData.appName}`, styleObj: { fontSize: '2.5em', color: '#2c3e50', marginBottom: '15px' } }),
new P({ slot: this.appData.appSubtitle, styleObj: { fontSize: '1.2em', color: '#7f8c8d', marginBottom: '30px' } }),
new P({ slot: `你好,${this.appData.user.name}!你已经连续学习 ${this.appData.user.streak} 天了。`, styleObj: { fontSize: '1.1em', color: '#27ae60', fontWeight: '600' } })
);
// Stats Grid
const statsGrid = new Div({ class: 'stats-grid' });
statsGrid.addChildren(
this.createStatCard('总经验值', this.appData.user.totalXP.toString(), '🏆'),
this.createStatCard('学习天数', this.appData.user.streak.toString(), '🔥'),
this.createStatCard('课程完成', '3/15', '📚'),
this.createStatCard('词汇掌握', '25/100', '🧠')
);
welcomeSection.addChild(statsGrid);
// Quick Actions
const actions = new Div({ styleObj: { marginTop: '30px' } });
actions.addChildren(
new Button({ slot: '开始今日课程 📚', class: 'action-btn', onClick: () => this.renderLessonsView() }),
new Button({ slot: '复习词汇卡片 🃏', class: 'action-btn', onClick: () => this.renderVocabularyView() }),
new Button({ slot: '挑战小测验 🎯', class: 'action-btn', onClick: () => this.renderQuizView() })
);
welcomeSection.addChild(actions);
contentArea.addChild(welcomeSection);
container.addChild(contentArea);
if (this.isMounted) {
container.mount(this.dom);
} else {
this.addChild(container);
}
}
private createHeader(): Div {
const header = new Div({ class: 'header' });
// Logo and Title
const logoSection = new Div();
logoSection.addChildren(
new Head({ tag: 'h1', slot: this.appData.appName, styleObj: { margin: 0, color: '#2c3e50', fontSize: '1.8em' } }),
new P({ slot: this.appData.user.level, class: 'badge badge-primary' })
);
// User Info
const userInfo = new Div({ class: 'user-info' });
userInfo.addChildren(
new Div({ class: 'avatar', slot: this.appData.user.name.charAt(0) }),
new Div({ slot: [new P({ slot: this.appData.user.name, styleObj: { fontWeight: '600', margin: '0 0 5px 0' } }), new P({ slot: `${this.appData.user.totalXP} XP`, styleObj: { color: '#7f8c8d', margin: 0, fontSize: '0.9em' } })] })
);
// Navigation Buttons
const navButtons = new Div({ class: 'nav-buttons' });
navButtons.addChildren(
new Button({ slot: '首页', class: `nav-btn ${this.currentView === 'home' ? 'active' : ''}`, onClick: () => this.renderHomeView() }),
new Button({ slot: '课程', class: `nav-btn ${this.currentView === 'lessons' ? 'active' : ''}`, onClick: () => this.renderLessonsView() }),
new Button({ slot: '词汇', class: `nav-btn ${this.currentView === 'vocabulary' ? 'active' : ''}`, onClick: () => this.renderVocabularyView() }),
new Button({ slot: '测验', class: `nav-btn ${this.currentView === 'quiz' ? 'active' : ''}`, onClick: () => this.renderQuizView() })
);
header.addChildren(logoSection, userInfo, navButtons);
return header;
}
private createStatCard(title: string, value: string, icon: string): Div {
const card = new Div({ class: 'stat-card' });
card.addChildren(
new Div({ slot: icon, styleObj: { fontSize: '2em', marginBottom: '10px' } }),
new Div({ slot: value, class: 'stat-number' }),
new P({ slot: title, styleObj: { margin: 0, opacity: 0.9 } })
);
return card;
}
private renderLessonsView(): void {
console.warn('renderLessonsView');
this.currentView = 'lessons';
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(new Head({ tag: 'h2', slot: '📖 我的课程', styleObj: { color: '#2c3e50', marginBottom: '25px' } }));
this.appData.lessons.forEach((lesson, index) => {
const lessonCard = new Div({ class: 'lesson-card' });
lessonCard.addChildren(
new Div({ class: 'card-title', slot: `${index + 1}. ${lesson.title}` }),
new P({ slot: lesson.description, styleObj: { color: '#7f8c8d', marginBottom: '15px' } }),
new Div({ class: 'card-meta', slot: [new Span({ slot: `⏱️ ${lesson.duration}`, class: 'badge badge-warning' }), new Span({ slot: `📊 ${lesson.level}`, class: 'badge badge-primary' }), new Span({ slot: lesson.completed ? '✅ 已完成' : '⏳ 未开始', class: `badge ${lesson.completed ? 'badge-success' : 'badge-warning'}` })] }),
new Button({ slot: lesson.completed ? '复习课程' : '开始学习', class: 'action-btn', styleObj: { marginTop: '15px' }, onClick: () => this.startLesson(index) })
);
contentArea.addChild(lessonCard);
});
container.addChild(contentArea);
// this.addChild(container);
container.mount(this.dom);
}
private renderVocabularyView(): void {
console.warn('renderVocabularyView');
this.currentView = 'vocabulary';
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(new Head({ tag: 'h2', slot: '🃏 词汇卡片', styleObj: { color: '#2c3e50', marginBottom: '25px' } }));
this.appData.vocabulary.forEach((vocab, index) => {
const vocabCard = new Div({ class: 'vocab-card' });
vocabCard.addChildren(
new Div({ class: 'card-title', slot: vocab.word }),
new P({ slot: `/${vocab.pronunciation}/`, styleObj: { fontStyle: 'italic', color: '#7f8c8d' } }),
new P({ slot: vocab.translation, styleObj: { fontSize: '1.2em', fontWeight: '600', color: '#27ae60' } }),
new P({ slot: `分类:${vocab.category}`, class: 'badge badge-primary', styleObj: { marginTop: '10px' } }),
new Div({ styleObj: { marginTop: '15px' }, slot: [new P({ slot: `例句:${vocab.example}`, styleObj: { fontStyle: 'italic', color: '#555' } }), new P({ slot: vocab.exampleTranslation, styleObj: { color: '#7f8c8d', marginTop: '5px' } })] })
);
contentArea.addChild(vocabCard);
});
container.addChild(contentArea);
container.mount(this.dom);
}
private renderQuizView(): void {
console.log('renderQuizView');
this.currentView = 'quiz';
this.quizScore = 0;
this.totalQuizQuestions = this.appData.quizQuestions.length;
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
contentArea.addChildren(
new Head({ tag: 'h2', slot: '🎯 语言测验', styleObj: { color: '#2c3e50', marginBottom: '25px' } }),
new P({ slot: '测试你的语言掌握程度!', styleObj: { fontSize: '1.1em', color: '#7f8c8d', marginBottom: '20px' } })
);
const startButton = new Button({ slot: '开始测验', class: 'action-btn', onClick: () => this.startQuiz() });
contentArea.addChild(startButton);
container.addChild(contentArea);
this.addChild(container);
container.mount(this.dom);
}
private startLesson(index: number): void {
alert(`开始学习课程:${this.appData.lessons[index].title} 内容预览:${this.appData.lessons[index].content.join('')}`);
// 这里可以跳转到具体的课程详情页面
}
private startQuiz(): void {
this.currentView = 'quiz';
let currentQuestionIndex = 0;
let selectedAnswer: number | null = null;
const showQuestion = () => {
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area' });
// Progress bar
const progressPercent = ((currentQuestionIndex) / this.totalQuizQuestions) * 100;
const progressBar = new Div({ class: 'progress-bar' });
progressBar.addChild(new Div({ class: 'progress-fill', styleObj: { width: `${progressPercent}%` } }));
contentArea.addChildren(
new P({ slot: `题目 ${currentQuestionIndex + 1} / ${this.totalQuizQuestions}`, styleObj: { textAlign: 'center', color: '#7f8c8d', marginBottom: '10px' } }),
progressBar
);
const question = this.appData.quizQuestions[currentQuestionIndex];
const questionDiv = new Div({ class: 'quiz-question' });
questionDiv.addChildren(new Head({ tag: 'h3', slot: question.question, styleObj: { color: '#2c3e50', marginBottom: '20px' } }));
const optionsDiv = new Div();
question.options.forEach((option, index) => {
const optionBtn = new Button({ slot: `${String.fromCharCode(65 + index)}. ${option}`, class: 'option-btn', onClick: () => {
// Remove previous selections
const allButtons = optionsDiv.children as Button[];
allButtons.forEach(btn => {
// btn.removeClass('selected');
removeClass(btn, 'selected');
});
// Select current option
// optionBtn.addClass('selected');
renderClass(optionBtn, 'selected');
selectedAnswer = index;
}});
optionsDiv.addChild(optionBtn);
});
questionDiv.addChild(optionsDiv);
const submitButton = new Button({ slot: '提交答案', class: 'action-btn', onClick: () => {
console.log('提交答案');
if (selectedAnswer === null) {
alert('请选择一个答案!');
return;
}
// Show result
const allButtons = optionsDiv.children as Button[];
allButtons.forEach((btn, idx) => {
if (idx === question.correctAnswer) {
// btn.addClass('correct');
addDomClass(btn.dom, 'correct');
} else if (idx === selectedAnswer && selectedAnswer !== question.correctAnswer) {
// btn.addClass('incorrect');
addDomClass(btn.dom, 'incorrect');
}
});
setTimeout(() => {
if (selectedAnswer === question.correctAnswer) {
this.quizScore++;
alert(`🎉 回答正确!\n\n解析:${question.explanation}`);
} else {
alert(`❌ 回答错误!\n\n正确答案:${question.options[question.correctAnswer]}\n解析:${question.explanation}`);
}
currentQuestionIndex++;
selectedAnswer = null;
if (currentQuestionIndex < this.totalQuizQuestions) {
showQuestion();
} else {
this.showQuizResults();
}
}, 1500);
}});
questionDiv.addChild(submitButton);
contentArea.addChild(questionDiv);
container.addChild(contentArea);
// this.addChild(container);
container.mount(this.dom);
};
showQuestion();
}
private showQuizResults(): void {
this.clearChildren();
const container = new Div({ class: 'app-container' });
container.addChild(this.createHeader());
const contentArea = new Div({ class: 'content-area', styleObj: { textAlign: 'center' } });
const scorePercent = Math.round((this.quizScore / this.totalQuizQuestions) * 100);
let resultMessage = '';
let resultEmoji = '';
if (scorePercent >= 90) {
resultMessage = '优秀!你是语言天才!';
resultEmoji = '🌟';
} else if (scorePercent >= 70) {
resultMessage = '很好!继续保持!';
resultEmoji = '👍';
} else if (scorePercent >= 50) {
resultMessage = '不错!还有进步空间!';
resultEmoji = '💪';
} else {
resultMessage = '继续努力!多加练习!';
resultEmoji = '📚';
}
contentArea.addChildren(
new Head({ tag: 'h2', slot: '测验结果', styleObj: { color: '#2c3e50', marginBottom: '30px' } }),
new Div({ slot: resultEmoji, styleObj: { fontSize: '4em', marginBottom: '20px' } }),
new Head({ tag: 'h1', slot: `${this.quizScore}/${this.totalQuizQuestions}`, styleObj: { fontSize: '3em', color: '#27ae60', margin: '20px 0' } }),
new P({ slot: `得分率:${scorePercent}%`, styleObj: { fontSize: '1.5em', color: '#7f8c8d', marginBottom: '30px' } }),
new P({ slot: resultMessage, styleObj: { fontSize: '1.3em', color: '#2c3e50', marginBottom: '30px' } }),
new TdButton({ slot: '返回首页', type: 'primary', onClick: () => this.renderHomeView() })
);
container.addChild(contentArea);
// this.addChild(container);
container.mount(this.dom);
}
}
// Data interfaces
interface AppData {
appName: string;
appSubtitle: string;
user: User;
lessons: Lesson[];
vocabulary: VocabularyItem[];
quizQuestions: QuizQuestion[];
}
interface User {
name: string;
level: string;
streak: number;
totalXP: number;
}
interface Lesson {
id: number;
title: string;
description: string;
level: string;
duration: string;
completed: boolean;
content: string[];
}
interface VocabularyItem {
id: number;
word: string;
translation: string;
pronunciation: string;
example: string;
exampleTranslation: string;
category: string;
}
interface QuizQuestion {
id: number;
question: string;
options: string[];
correctAnswer: number;
explanation: string;
}