Spaces:
Running
Running
| const mongoose = require('mongoose'); | |
| // ... (Previous Models: School, User, Student, Course, Score, Class, Subject, Exam Models - No Change) | |
| const SchoolSchema = new mongoose.Schema({ name: String, code: String }); | |
| const School = mongoose.model('School', SchoolSchema); | |
| const UserSchema = new mongoose.Schema({ | |
| username: String, | |
| password: String, | |
| trueName: String, | |
| phone: String, | |
| email: String, | |
| schoolId: String, | |
| role: String, | |
| status: String, | |
| avatar: String, | |
| createTime: Date, | |
| teachingSubject: String, | |
| homeroomClass: String, | |
| studentNo: String, | |
| parentName: String, | |
| parentPhone: String, | |
| address: String, | |
| gender: String, | |
| seatNo: String, | |
| idCard: String, | |
| aiAccess: { type: Boolean, default: false }, | |
| // UPDATED: Stores Doubao Context State | |
| doubaoState: { | |
| responseId: String, // previous_response_id | |
| thinkingState: Boolean // Last thinking state (enabled/disabled) | |
| }, | |
| menuOrder: [String], | |
| classApplication: { | |
| type: { type: String }, | |
| targetClass: String, | |
| status: String | |
| }, | |
| pendingSchoolData: { | |
| name: String, | |
| code: String, | |
| type: { type: String } | |
| } | |
| }); | |
| const User = mongoose.model('User', UserSchema); | |
| // ... (Student, Course, Score, Class, Subject, Exam Models - No Change) | |
| const StudentSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| studentNo: String, | |
| seatNo: String, | |
| name: String, | |
| gender: String, | |
| birthday: String, | |
| idCard: String, | |
| phone: String, | |
| className: String, | |
| status: String, | |
| parentName: String, | |
| parentPhone: String, | |
| address: String, | |
| teamId: String, | |
| drawAttempts: { type: Number, default: 0 }, | |
| dailyDrawLog: { date: String, count: { type: Number, default: 0 } }, | |
| flowerBalance: { type: Number, default: 0 }, | |
| // Seating Fields | |
| height: Number, | |
| vision: { type: String, default: 'Normal' }, // Normal, Near-Mild, Near-Severe, Far | |
| character: { type: String, default: 'Normal' }, // Active, Quiet, Normal | |
| seatRow: Number, | |
| seatCol: Number | |
| }); | |
| const Student = mongoose.model('Student', StudentSchema); | |
| const CourseSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| courseCode: String, | |
| courseName: String, | |
| className: String, | |
| teacherName: String, | |
| teacherId: String, | |
| credits: Number, | |
| capacity: Number, | |
| enrolled: Number | |
| }); | |
| CourseSchema.index({ schoolId: 1, className: 1, courseName: 1 }, { unique: true }); | |
| const Course = mongoose.model('Course', CourseSchema); | |
| const ScoreSchema = new mongoose.Schema({ schoolId: String, studentName: String, studentNo: String, courseName: String, score: Number, semester: String, type: String, examName: String, status: String }); | |
| const Score = mongoose.model('Score', ScoreSchema); | |
| // UPDATED CLASS SCHEMA | |
| const ClassSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| grade: String, | |
| className: String, | |
| teacherName: String, | |
| homeroomTeacherIds: [String], | |
| periodConfig: [{ period: Number, name: String, startTime: String, endTime: String }], | |
| seatingConfig: { rows: Number, cols: Number } | |
| }); | |
| const ClassModel = mongoose.model('Class', ClassSchema); | |
| const SubjectSchema = new mongoose.Schema({ schoolId: String, name: String, code: String, color: String, excellenceThreshold: Number, thresholds: { type: Map, of: Number } }); | |
| const SubjectModel = mongoose.model('Subject', SubjectSchema); | |
| const ExamSchema = new mongoose.Schema({ schoolId: String, name: String, date: String, type: String, semester: String }); | |
| const ExamModel = mongoose.model('Exam', ExamSchema); | |
| const ScheduleSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| className: String, | |
| teacherName: String, | |
| subject: String, | |
| dayOfWeek: Number, | |
| period: Number, | |
| weekType: { type: String, default: 'ALL' } // ALL, ODD, EVEN | |
| }); | |
| const ScheduleModel = mongoose.model('Schedule', ScheduleSchema); | |
| const ConfigSchema = new mongoose.Schema({ | |
| key: String, | |
| systemName: String, | |
| semester: String, | |
| semesters: [String], | |
| allowRegister: Boolean, | |
| allowAdminRegister: Boolean, | |
| allowPrincipalRegister: Boolean, | |
| allowStudentRegister: Boolean, | |
| maintenanceMode: Boolean, | |
| emailNotify: Boolean, | |
| enableAI: { type: Boolean, default: true }, | |
| aiTotalCalls: { type: Number, default: 0 }, | |
| // Updated default to include DOUBAO | |
| aiProviderOrder: { type: [String], default: ['GEMINI', 'OPENROUTER', 'DOUBAO', 'GEMMA'] }, | |
| periodConfig: [{ period: Number, name: String, startTime: String, endTime: String }], | |
| apiKeys: { | |
| gemini: [String], | |
| openrouter: [String], | |
| doubao: [String] // NEW: Doubao Key Pool | |
| }, | |
| // NEW: Doubao Custom Models (Endpoints) | |
| doubaoModels: [{ | |
| modelId: String, // The Model ID (e.g. doubao-pro-32k) | |
| endpointId: String, // Endpoint ID (e.g. ep-2024xxxx) | |
| name: String // Friendly Name | |
| }], | |
| openRouterModels: [{ | |
| id: String, | |
| name: String, | |
| apiUrl: String, // NEW: Custom API URL for this model | |
| isCustom: { type: Boolean, default: false } | |
| }] | |
| }); | |
| const ConfigModel = mongoose.model('Config', ConfigSchema); | |
| // ... (Notification, GameSession, StudentReward, LuckyDrawConfig, etc.) | |
| const NotificationSchema = new mongoose.Schema({ schoolId: String, targetRole: String, targetUserId: String, title: String, content: String, type: String, createTime: { type: Date, default: Date.now } }); | |
| const NotificationModel = mongoose.model('Notification', NotificationSchema); | |
| const GameSessionSchema = new mongoose.Schema({ schoolId: String, className: String, isEnabled: Boolean, maxSteps: Number, teams: [{ id: String, name: String, score: Number, avatar: String, color: String, members: [String] }], rewardsConfig: [{ scoreThreshold: Number, rewardType: String, rewardName: String, rewardValue: { type: Number, default: 1 }, achievementId: String }] }); // Added rewardValue default | |
| const GameSessionModel = mongoose.model('GameSession', GameSessionSchema); | |
| const StudentRewardSchema = new mongoose.Schema({ schoolId: String, studentId: String, studentName: String, rewardType: String, name: String, count: { type: Number, default: 1 }, status: String, source: String, createTime: { type: Date, default: Date.now }, ownerId: String }); | |
| const StudentRewardModel = mongoose.model('StudentReward', StudentRewardSchema); | |
| const LuckyDrawConfigSchema = new mongoose.Schema({ schoolId: String, className: String, ownerId: String, prizes: [{ id: String, name: String, probability: Number, count: Number, icon: String }], dailyLimit: Number, cardCount: Number, defaultPrize: String, consolationWeight: { type: Number, default: 0 } }); | |
| const LuckyDrawConfigModel = mongoose.model('LuckyDrawConfig', LuckyDrawConfigSchema); | |
| const GameMonsterConfigSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| className: String, | |
| ownerId: String, | |
| duration: { type: Number, default: 300 }, | |
| sensitivity: { type: Number, default: 25 }, | |
| difficulty: { type: Number, default: 5 }, | |
| useKeyboardMode: { type: Boolean, default: false }, | |
| rewardConfig: { | |
| enabled: Boolean, | |
| type: { type: String }, | |
| val: String, | |
| count: Number | |
| } | |
| }); | |
| const GameMonsterConfigModel = mongoose.model('GameMonsterConfig', GameMonsterConfigSchema); | |
| const GameZenConfigSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| className: String, | |
| ownerId: String, | |
| durationMinutes: { type: Number, default: 40 }, | |
| threshold: { type: Number, default: 30 }, | |
| passRate: { type: Number, default: 90 }, | |
| rewardConfig: { | |
| enabled: Boolean, | |
| type: { type: String }, | |
| val: String, | |
| count: Number | |
| } | |
| }); | |
| const GameZenConfigModel = mongoose.model('GameZenConfig', GameZenConfigSchema); | |
| const AchievementConfigSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| className: String, | |
| achievements: [{ | |
| id: String, | |
| name: String, | |
| icon: String, | |
| points: Number, | |
| description: String, | |
| addedBy: String, | |
| addedByName: String | |
| }], | |
| exchangeRules: [{ id: String, cost: Number, rewardType: String, rewardName: String, rewardValue: Number }] | |
| }); | |
| const AchievementConfigModel = mongoose.model('AchievementConfig', AchievementConfigSchema); | |
| const TeacherExchangeConfigSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| teacherId: String, | |
| teacherName: String, | |
| rules: [{ id: String, cost: Number, rewardType: String, rewardName: String, rewardValue: Number }] | |
| }); | |
| const TeacherExchangeConfigModel = mongoose.model('TeacherExchangeConfig', TeacherExchangeConfigSchema); | |
| // Updated: Added points field | |
| const StudentAchievementSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| studentId: String, | |
| studentName: String, | |
| achievementId: String, | |
| achievementName: String, | |
| achievementIcon: String, | |
| points: { type: Number, default: 0 }, | |
| semester: String, | |
| createTime: { type: Date, default: Date.now } | |
| }); | |
| const StudentAchievementModel = mongoose.model('StudentAchievement', StudentAchievementSchema); | |
| const AttendanceSchema = new mongoose.Schema({ schoolId: String, studentId: String, studentName: String, className: String, date: String, status: String, checkInTime: Date }); | |
| const AttendanceModel = mongoose.model('Attendance', AttendanceSchema); | |
| const LeaveRequestSchema = new mongoose.Schema({ schoolId: String, studentId: String, studentName: String, className: String, reason: String, startDate: String, endDate: String, status: { type: String, default: 'Pending' }, createTime: { type: Date, default: Date.now } }); | |
| const LeaveRequestModel = mongoose.model('LeaveRequest', LeaveRequestSchema); | |
| const SchoolCalendarSchema = new mongoose.Schema({ schoolId: String, className: String, type: String, startDate: String, endDate: String, name: String }); | |
| const SchoolCalendarModel = mongoose.model('SchoolCalendar', SchoolCalendarSchema); | |
| const WishSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| studentId: String, | |
| studentName: String, | |
| className: String, | |
| teacherId: String, | |
| teacherName: String, | |
| content: String, | |
| status: { type: String, default: 'PENDING' }, | |
| createTime: { type: Date, default: Date.now }, | |
| fulfillTime: Date | |
| }); | |
| const WishModel = mongoose.model('Wish', WishSchema); | |
| const FeedbackSchema = new mongoose.Schema({ | |
| schoolId: String, | |
| creatorId: String, | |
| creatorName: String, | |
| creatorRole: String, | |
| targetId: String, | |
| targetName: String, | |
| content: String, | |
| type: String, | |
| status: { type: String, default: 'PENDING' }, | |
| reply: String, | |
| createTime: { type: Date, default: Date.now }, | |
| updateTime: Date | |
| }); | |
| const FeedbackModel = mongoose.model('Feedback', FeedbackSchema); | |
| const TodoSchema = new mongoose.Schema({ | |
| userId: String, | |
| content: String, | |
| isCompleted: { type: Boolean, default: false }, | |
| createTime: { type: Date, default: Date.now } | |
| }); | |
| const TodoModel = mongoose.model('Todo', TodoSchema); | |
| // NEW: Detailed AI Usage Stats | |
| const AIUsageSchema = new mongoose.Schema({ | |
| date: String, // Format: YYYY-MM-DD | |
| model: String, | |
| provider: String, | |
| count: { type: Number, default: 0 } | |
| }); | |
| // Optimize lookups by date and model | |
| AIUsageSchema.index({ date: 1, model: 1, provider: 1 }, { unique: true }); | |
| const AIUsageModel = mongoose.model('AIUsage', AIUsageSchema); | |
| // NEW: Persistent Chat History | |
| const ChatHistorySchema = new mongoose.Schema({ | |
| userId: { type: String, required: true, index: true }, | |
| role: { type: String, enum: ['user', 'model'], required: true }, | |
| text: { type: String, required: true }, | |
| timestamp: { type: Number, default: Date.now } | |
| }); | |
| // Create index for fast retrieval of latest messages | |
| ChatHistorySchema.index({ userId: 1, timestamp: -1 }); | |
| const ChatHistoryModel = mongoose.model('ChatHistory', ChatHistorySchema); | |
| module.exports = { | |
| School, User, Student, Course, Score, ClassModel, SubjectModel, ExamModel, ScheduleModel, | |
| ConfigModel, NotificationModel, GameSessionModel, StudentRewardModel, LuckyDrawConfigModel, GameMonsterConfigModel, GameZenConfigModel, | |
| AchievementConfigModel, TeacherExchangeConfigModel, StudentAchievementModel, AttendanceModel, LeaveRequestModel, SchoolCalendarModel, | |
| WishModel, FeedbackModel, TodoModel, AIUsageModel, ChatHistoryModel | |
| }; |