diff --git a/form_angular/src/app/form/form.component.css b/form/src/app/form/form.component.css
similarity index 52%
rename from form_angular/src/app/form/form.component.css
rename to form/src/app/form/form.component.css
index 17e4315a93ac2f8407a3905cd567995c0a357f5d..5d78cd06c5f047021baddbe66edf8dae0954fb5d 100644
--- a/form_angular/src/app/form/form.component.css
+++ b/form/src/app/form/form.component.css
@@ -33,30 +33,3 @@
   padding: 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
diff --git a/form/src/app/form/form.component.html b/form/src/app/form/form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4855aad24209bf9518225bb508d981fb13b5a4fe
--- /dev/null
+++ b/form/src/app/form/form.component.html
@@ -0,0 +1,145 @@
+<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
diff --git a/form/src/app/form/form.component.ts b/form/src/app/form/form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..24e87374a9f2d37ef8b7c77cce6df5c2651dcb42
--- /dev/null
+++ b/form/src/app/form/form.component.ts
@@ -0,0 +1,208 @@
+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