Migrate project from typing_practiceweb
This commit is contained in:
137
server/models/Vocabulary.ts
Normal file
137
server/models/Vocabulary.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import mongoose, { Document, Schema } from 'mongoose';
|
||||
|
||||
// 单词接口
|
||||
export interface IWord extends Document {
|
||||
word: string;
|
||||
translation: string;
|
||||
pronunciation?: string;
|
||||
example?: string;
|
||||
wordSet: mongoose.Types.ObjectId;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// 单词集接口
|
||||
export interface IWordSet extends Document {
|
||||
name: string;
|
||||
description?: string;
|
||||
owner: mongoose.Types.ObjectId;
|
||||
totalWords: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
// 单词学习记录接口
|
||||
export interface IWordRecord extends Document {
|
||||
user: mongoose.Types.ObjectId;
|
||||
word: mongoose.Types.ObjectId;
|
||||
mode: 'chinese-to-english' | 'audio-to-english' | 'multiple-choice';
|
||||
streak: number;
|
||||
totalCorrect: number;
|
||||
totalWrong: number;
|
||||
mastered: boolean;
|
||||
inWrongBook: boolean;
|
||||
lastTestedAt: Date;
|
||||
lastMasteredAt: Date;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
// 单词测试记录接口
|
||||
export interface IVocabularyTestRecord extends Document {
|
||||
user: mongoose.Types.ObjectId;
|
||||
wordSet: mongoose.Types.ObjectId;
|
||||
testType: 'chinese-to-english' | 'audio-to-english' | 'multiple-choice';
|
||||
stats: {
|
||||
totalWords: number;
|
||||
correctWords: number;
|
||||
accuracy: number;
|
||||
startTime: Date;
|
||||
endTime: Date;
|
||||
duration: number;
|
||||
};
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
// 单词模式
|
||||
const WordSchema = new Schema<IWord>({
|
||||
word: { type: String, required: true, trim: true },
|
||||
translation: { type: String, required: true, trim: true },
|
||||
pronunciation: { type: String, trim: true },
|
||||
example: { type: String, trim: true },
|
||||
wordSet: { type: Schema.Types.ObjectId, ref: 'WordSet', required: true },
|
||||
}, { timestamps: true });
|
||||
|
||||
// 为单词模型添加索引
|
||||
WordSchema.index({ word: 1, wordSet: 1 }, { unique: true });
|
||||
WordSchema.index({ translation: 'text', word: 'text' });
|
||||
|
||||
// 单词集模式
|
||||
const WordSetSchema = new Schema<IWordSet>({
|
||||
name: { type: String, required: true, trim: true },
|
||||
description: { type: String, trim: true },
|
||||
owner: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||
totalWords: { type: Number, default: 0 },
|
||||
}, { timestamps: true });
|
||||
|
||||
// 为单词集模型添加索引
|
||||
WordSetSchema.index({ name: 1, owner: 1 }, { unique: true });
|
||||
|
||||
// 简化的嵌套模式统计
|
||||
const ModeStatsSchema = new Schema({
|
||||
streak: { type: Number, default: 0 },
|
||||
totalCorrect: { type: Number, default: 0 },
|
||||
totalWrong: { type: Number, default: 0 },
|
||||
mastered: { type: Boolean, default: false },
|
||||
inWrongBook: { type: Boolean, default: false },
|
||||
lastTestedAt: Date
|
||||
}, { _id: false });
|
||||
|
||||
// 简化后的主记录模式
|
||||
const WordRecordSchema = new Schema({
|
||||
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||
word: { type: Schema.Types.ObjectId, ref: 'Word', required: true },
|
||||
|
||||
// 各模式的基础统计数据
|
||||
multipleChoice: { type: ModeStatsSchema, default: () => ({}) },
|
||||
audioToEnglish: { type: ModeStatsSchema, default: () => ({}) },
|
||||
chineseToEnglish: { type: ModeStatsSchema, default: () => ({}) },
|
||||
|
||||
// 只在顶层保留整体掌握状态
|
||||
isFullyMastered: { type: Boolean, default: false },
|
||||
lastFullyMasteredAt: Date,
|
||||
|
||||
createdAt: { type: Date, default: Date.now }
|
||||
});
|
||||
|
||||
// 单词测试记录模式
|
||||
const VocabularyTestRecordSchema = new Schema<IVocabularyTestRecord>({
|
||||
user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
|
||||
wordSet: { type: Schema.Types.ObjectId, ref: 'WordSet', required: true },
|
||||
testType: {
|
||||
type: String,
|
||||
enum: ['chinese-to-english', 'audio-to-english', 'multiple-choice'],
|
||||
required: true
|
||||
},
|
||||
stats: {
|
||||
totalWords: { type: Number, required: true },
|
||||
correctWords: { type: Number, required: true },
|
||||
accuracy: { type: Number, required: true },
|
||||
startTime: { type: Date, required: true },
|
||||
endTime: { type: Date, required: true },
|
||||
duration: { type: Number, required: true }
|
||||
},
|
||||
createdAt: { type: Date, default: Date.now }
|
||||
});
|
||||
|
||||
// 创建和导出模型
|
||||
export const Word = mongoose.model<IWord>('Word', WordSchema);
|
||||
export const WordSet = mongoose.model<IWordSet>('WordSet', WordSetSchema);
|
||||
export const WordRecord = mongoose.model('WordRecord', WordRecordSchema);
|
||||
export const VocabularyTestRecord = mongoose.model<IVocabularyTestRecord>('VocabularyTestRecord', VocabularyTestRecordSchema);
|
||||
|
||||
export default {
|
||||
Word,
|
||||
WordSet,
|
||||
WordRecord,
|
||||
VocabularyTestRecord
|
||||
};
|
||||
Reference in New Issue
Block a user