Commit de18c9f4 authored by chunsen's avatar chunsen

feat: 增加学习单词配置表单

parent f623cc43
...@@ -33,30 +33,3 @@ ...@@ -33,30 +33,3 @@
padding: 10px; padding: 10px;
margin: 10px; margin: 10px;
} }
.button-right {
border-style: dotted;
border-color: rgb(42, 142, 72);
width: 100px;
height: 50px;
color: rgb(42, 142, 72);
background-color: white;
}
.button-wrong {
border-style: dotted;
border-color: rgb(180, 0, 0);
width: 100px;
height: 50px;
color: rgb(180, 0, 0);
background-color: white;
}
.button-disable {
border-style: dotted;
border-color: black;
width: 100px;
height: 50px;
color: black;
background-color: white;
}
\ No newline at end of file
<div style="margin: 30px;">
<!-- 单词表单数据 -->
<div style="border: 2px #ccc solid; border-radius: 15px; width: 1000px; margin: 30px">
<div style="padding: 20px; margin-bottom: 20px;">
<h2>单词表编辑</h2>
<button nz-button nzType="primary" (click)="addNewWord()" style="margin-bottom: 20px;">
<i nz-icon nzType="plus"></i> 添加新单词
</button>
<div *ngFor="let word of item.data; let i = index"
style="border: 1px #ccc solid; border-radius: 15px; padding: 20px; margin-bottom: 15px; background-color: rgb(255, 250, 243);">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px;">
<h3>单词 #{{i+1}}</h3>
<button nz-button nzType="danger" (click)="deleteWord(i)">
<i nz-icon nzType="delete"></i> 删除
</button>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
<!-- 左侧列 -->
<div>
<!-- 单词 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">单词:</span>
<input type="text" nz-input [(ngModel)]="word.word" (blur)="save()" style="width: 250px;">
</div>
<!-- 词性 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">词性:</span>
<div style="width: 250px;">
<a nz-dropdown [nzDropdownMenu]="menu">
{{word.partOfSpeech || '无'}}
<i nz-icon nzType="down"></i>
</a>
<button style="margin-left: 10px;" nz-button (click)="word.partOfSpeech = ''; save()">
x
</button>
<nz-dropdown-menu #menu="nzDropdownMenu">
<ul nz-menu nzSelectable>
<div nz-menu-item *ngFor="let pos of posArr;" align="center" (click)="word.partOfSpeech = pos; save()">
{{pos}}
</div>
</ul>
</nz-dropdown-menu>
</div>
</div>
<!-- 单词音频 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">单词音频:</span>
<app-audio-recorder [audioUrl]="word.wordAudioUrl"
(audioUploaded)="onItemAudioUploadSuccess($event, word, 'wordAudioUrl')">
</app-audio-recorder>
</div>
<!-- 翻译 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">单词翻译:</span>
<input type="text" nz-input [(ngModel)]="word.wordTranslation" (blur)="save()" style="width: 250px;">
</div>
<div style="margin-top: 20px; border-top: 1px dashed #eee; padding-top: 15px;">
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">显示类型:</span>
<div style="width: auto; display: flex; align-items: center;">
<label style="margin-right: 10px; font-size: 14px;">
<input type="radio" [(ngModel)]="word.displayType" [value]="1" (change)="save()"> 高亮
</label>
<label style="margin-right: 10px; font-size: 14px;">
<input type="radio" [(ngModel)]="word.displayType" [value]="2" (change)="save()"> 单词卡
</label>
<label style="font-size: 14px;">
<input type="radio" [(ngModel)]="word.displayType" [value]="3" (change)="save()" checked> 高亮&单词卡
</label>
</div>
</div>
</div>
</div>
<!-- 右侧列 -->
<div>
<!-- 例句 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">例句:</span>
<input type="text" nz-input [(ngModel)]="word.exampleSentence" (blur)="save()" style="width: 250px;">
</div>
<!-- 例句音频 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">例句音频:</span>
<app-audio-recorder [audioUrl]="word.exampleSentenceAudioUrl"
(audioUploaded)="onItemAudioUploadSuccess($event, word, 'exampleSentenceAudioUrl')">
</app-audio-recorder>
</div>
<!-- 图片 -->
<div style="margin-bottom: 10px; display: flex;">
<span style="width: 120px; text-align: right;">图片:</span>
<div style="width: 250px;">
<app-upload-image-with-preview [picUrl]="word.imageUrl"
(imageUploaded)="onItemImgUploadSuccess($event, word, 'imageUrl')">
</app-upload-image-with-preview>
</div>
<button *ngIf="word.imageUrl" style="margin-left: 10px;" nz-button (click)="onDeletaImg(word, 'imageUrl')">
x
</button>
</div>
<!-- 其他可选字段 -->
<div style="margin-top: 20px; border-top: 1px dashed #eee; padding-top: 15px;">
<!-- 英式音标 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">英式音标:</span>
<input type="text" nz-input [(ngModel)]="word.britishPhonetic" (blur)="save()" style="width: 250px;">
</div>
<!-- 美式音标 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">美式音标:</span>
<input type="text" nz-input [(ngModel)]="word.americanPhonetic" (blur)="save()" style="width: 250px;">
</div>
<!-- 英文定义 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">英文定义:</span>
<input type="text" nz-input [(ngModel)]="word.englishDefinition" (blur)="save()" style="width: 250px;">
</div>
<!-- 例句翻译 -->
<div style="margin-bottom: 10px; display: flex; align-items: center;">
<span style="width: 120px; text-align: right;">例句翻译:</span>
<input type="text" nz-input [(ngModel)]="word.exampleSentenceTranslation" (blur)="save()" style="width: 250px;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef } from '@angular/core';
import { JsonPipe } from '@angular/common';
import { NzMessageService } from 'ng-zorro-antd/message';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用
saveKey = "learn_word";
// 储存对象
item;
posArr = [
'n.',
'adj.',
'v.',
'pron.',
'adv.',
'prep.',
'conj.',
'interj.',
'art.',
'num.',
'abbr.',
'verb phrase',
'noun phrase',
'prep phrase',
'ordinal number',
];
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef,
private message: NzMessageService) {
}
ngOnInit() {
this.item = {};
// 获取存储的数据
(<any>window).courseware.getData((data) => {
if (data) {
this.item = data;
// 删除可能存在的quesArr属性
if (this.item.quesArr) {
delete this.item.quesArr;
}
}
this.initItem();
console.log("this.item: ", JSON.stringify(this.item));
this.init();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
this.refresh();
}, this.saveKey);
}
initItem() {
// 确保item有正确的数据结构
if (!this.item.data) {
this.item.data = [];
}
}
init() {
// 如果没有任何数据,可以添加示例数据
if (this.item.data.length === 0) {
this.addSampleData();
}
}
// 添加示例数据
addSampleData() {
this.item.data.push({
id:'',
pictureBookId: '',
word: '',
displayType: '',
partOfSpeech: '',
exampleSentence: '',
wordAudioUrl: '',
exampleSentenceAudioUrl: '',
wordTranslation: '',
exampleSentenceTranslation: '',
imageUrl: '',
britishPhonetic: '',
americanPhonetic: '',
englishDefinition: '',
backContent: {},
createdTime: new Date().toISOString()
});
}
ngOnChanges() {
}
ngOnDestroy() {
}
onItemImgUploadSuccess(e, item, key='imageUrl') {
item[key] = e.url;
this.save();
}
onItemAudioUploadSuccess(e, item, key='wordAudioUrl') {
item[key] = e.url;
this.save();
}
onDeletaImg(item, key) {
item[key] = '';
this.save();
}
getNewSortItem() {
// 深拷贝item对象
const newItem = JSON.parse(JSON.stringify(this.item));
// 删除可能存在的quesArr属性
if (newItem.quesArr) {
delete newItem.quesArr;
}
return newItem;
}
/**
* 储存数据
*/
save() {
// 更新data中的时间戳
// if (this.item.data && this.item.data.length > 0) {
// const now = new Date().toISOString();
// this.item.data.forEach(item => {
// if (!item.createdTime) {
// item.createdTime = now;
// }
// });
// }
// 删除item中可能存在的quesArr属性
// if (this.item.quesArr) {
// delete this.item.quesArr;
// }
const newItem = this.getNewSortItem();
(<any>window).courseware.setData(newItem, null, this.saveKey);
this.refresh();
console.log('this.item = ' + JSON.stringify(this.item));
this.message.create('success', "保存成功");
}
/**
* 刷新 渲染页面
*/
refresh() {
setTimeout(() => {
this.appRef.tick();
}, 1);
}
// 添加新单词到data数组中
addNewWord() {
this.item.data.push({
id: '',
pictureBookId: '',
word: '',
displayType: '',
partOfSpeech: '',
exampleSentence: '',
wordAudioUrl: '',
exampleSentenceAudioUrl: '',
wordTranslation: '',
exampleSentenceTranslation: '',
imageUrl: '',
britishPhonetic: '',
americanPhonetic: '',
englishDefinition: '',
backContent: {},
createdTime: new Date().toISOString()
});
this.save();
}
// 删除data数组中的单词
deleteWord(index) {
this.item.data.splice(index, 1);
this.save();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment