kindergarten_java/reading-platform-backend/prisma/seed.ts

433 lines
13 KiB
TypeScript
Raw Normal View History

2026-02-28 02:11:48 +08:00
// npx prisma migrate dev --name init
import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function main() {
console.log('开始种子数据...');
// 1. 创建测试租户
const tenant = await prisma.tenant.upsert({
where: { id: 1 },
update: {},
create: {
name: '阳光幼儿园',
address: '北京市朝阳区xxx街道',
contactPerson: '张园长',
contactPhone: '13800138000',
packageType: 'STANDARD',
teacherQuota: 20,
studentQuota: 200,
storageQuota: BigInt(5368709120), // 5GB
startDate: '2024-01-01',
expireDate: '2025-12-31',
status: 'ACTIVE',
},
});
console.log('创建租户:', tenant.name);
// 2. 创建教师账号
const passwordHash = await bcrypt.hash('123456', 10);
const teacher = await prisma.teacher.upsert({
where: { loginAccount: 'teacher1' },
update: {},
create: {
tenantId: tenant.id,
name: '李老师',
phone: '13900139000',
email: 'teacher1@example.com',
loginAccount: 'teacher1',
passwordHash: passwordHash,
status: 'ACTIVE',
},
});
console.log('创建教师:', teacher.name);
// 3. 创建班级
const class1 = await prisma.class.upsert({
where: { id: 1 },
update: {},
create: {
tenantId: tenant.id,
name: '中一班',
grade: 'MIDDLE',
teacherId: teacher.id,
studentCount: 25,
},
});
console.log('创建班级:', class1.name);
const class2 = await prisma.class.upsert({
where: { id: 2 },
update: {},
create: {
tenantId: tenant.id,
name: '大一班',
grade: 'BIG',
teacherId: teacher.id,
studentCount: 30,
},
});
console.log('创建班级:', class2.name);
// 4. 更新教师的班级关联
await prisma.teacher.update({
where: { id: teacher.id },
data: {
classIds: JSON.stringify([class1.id, class2.id]),
},
});
// 5. 创建示例学生
const students = [
{ name: '小明', gender: 'MALE', classId: class1.id },
{ name: '小红', gender: 'FEMALE', classId: class1.id },
{ name: '小华', gender: 'MALE', classId: class1.id },
{ name: '小丽', gender: 'FEMALE', classId: class2.id },
{ name: '小强', gender: 'MALE', classId: class2.id },
];
for (const studentData of students) {
await prisma.student.upsert({
where: {
id: students.indexOf(studentData) + 1,
},
update: {},
create: {
tenantId: tenant.id,
classId: studentData.classId,
name: studentData.name,
gender: studentData.gender,
},
});
}
console.log('创建学生:', students.length, '名');
// 6. 创建示例课程包
const course = await prisma.course.upsert({
where: { id: 1 },
update: {},
create: {
name: '好饿的毛毛虫',
description: '这是一本经典的绘本,讲述了一只毛毛虫从孵化到变成蝴蝶的故事。通过这个故事,孩子们可以学习到星期的概念、数字的认知,以及毛毛虫变蝴蝶的科学知识。',
pictureBookName: '好饿的毛毛虫',
gradeTags: JSON.stringify(['SMALL', 'MIDDLE']),
domainTags: JSON.stringify(['LANGUAGE', 'SCIENCE', 'MATH']),
duration: 30,
status: 'PUBLISHED',
version: '1.0',
coverImagePath: '/uploads/covers/caterpillar.jpg',
},
});
console.log('创建课程:', course.name);
// 7. 创建课程脚本6步教学流程
const scripts = [
{
stepIndex: 1,
stepName: '阅读导入',
stepType: 'INTRODUCTION',
duration: 5,
objective: '激发幼儿阅读兴趣,建立阅读期待',
teacherScript: '小朋友们,今天我们要认识一位新朋友——一只小小的毛毛虫。你们见过毛毛虫吗?它长什么样子呢?让我们一起来看看这只特别的毛毛虫的故事吧!',
interactionPoints: JSON.stringify([
'展示毛毛虫图片或玩偶',
'引导幼儿分享见过的毛毛虫',
'预测故事内容',
]),
},
{
stepIndex: 2,
stepName: '绘本共读',
stepType: 'READING',
duration: 10,
objective: '理解故事内容,发展语言能力',
teacherScript: '(逐页讲述)从前,有一颗小小的蛋躺在叶子上...月光下,一条又小又饿的毛毛虫从蛋里爬了出来...',
interactionPoints: JSON.stringify([
'提问预测',
'模仿毛毛虫吃东西的动作',
'一起数食物的数量',
]),
},
{
stepIndex: 3,
stepName: '理解讨论',
stepType: 'DISCUSSION',
duration: 5,
objective: '加深对故事的理解,发展思维能力',
teacherScript: '小朋友们,毛毛虫吃了哪些东西呢?为什么最后它肚子痛了?它最后变成了什么?',
interactionPoints: JSON.stringify([
'回顾毛毛虫吃的食物',
'讨论健康饮食的重要性',
'讨论毛毛虫的成长变化',
]),
},
{
stepIndex: 4,
stepName: '互动游戏',
stepType: 'ACTIVITY',
duration: 5,
objective: '通过游戏巩固学习内容',
teacherScript: '现在我们来玩一个游戏,老师说出星期几,小朋友们来模仿毛毛虫吃了什么!',
interactionPoints: JSON.stringify([
'星期与食物配对游戏',
'毛毛虫动作模仿',
'食物分类活动',
]),
},
{
stepIndex: 5,
stepName: '创意表达',
stepType: 'CREATIVE',
duration: 3,
objective: '发展创造力和表达能力',
teacherScript: '如果你是毛毛虫,你想吃什么?画一画你心目中的毛毛虫吧!',
interactionPoints: JSON.stringify([
'自由绘画',
'分享作品',
'创意表达',
]),
},
{
stepIndex: 6,
stepName: '总结延伸',
stepType: 'SUMMARY',
duration: 2,
objective: '总结学习内容,激发延伸探索兴趣',
teacherScript: '今天我们认识了一只可爱的毛毛虫,它从一颗小蛋,变成毛毛虫,最后变成了漂亮的蝴蝶!回家后可以和爸爸妈妈一起找找看,还有哪些动物会变形呢?',
interactionPoints: JSON.stringify([
'总结毛毛虫的成长过程',
'布置家庭延伸任务',
'预告下次活动',
]),
},
];
for (const script of scripts) {
await prisma.courseScript.upsert({
where: {
courseId_stepIndex: {
courseId: course.id,
stepIndex: script.stepIndex,
},
},
update: {},
create: {
courseId: course.id,
...script,
sortOrder: script.stepIndex,
},
});
}
console.log('创建课程脚本:', scripts.length, '个步骤');
// 8. 创建逐页配置(为绘本共读步骤添加)
const pages = [
{ pageNumber: 1, questions: '你们看到了什么?这是什么颜色的?', teacherNotes: '引导观察封面' },
{ pageNumber: 2, questions: '蛋在哪里?是谁的蛋呢?', teacherNotes: '引入故事悬念' },
{ pageNumber: 3, questions: '毛毛虫从蛋里出来了!它说了什么?', teacherNotes: '模仿毛毛虫的声音' },
{ pageNumber: 4, questions: '星期一,毛毛虫吃了什么?吃了几个?', teacherNotes: '学习星期和数字' },
{ pageNumber: 5, questions: '星期二,它又吃了什么?', teacherNotes: '继续学习星期' },
];
const readingScript = await prisma.courseScript.findFirst({
where: { courseId: course.id, stepType: 'READING' },
});
if (readingScript) {
for (const page of pages) {
await prisma.courseScriptPage.upsert({
where: {
scriptId_pageNumber: {
scriptId: readingScript.id,
pageNumber: page.pageNumber,
},
},
update: {},
create: {
scriptId: readingScript.id,
...page,
},
});
}
console.log('创建逐页配置:', pages.length, '页');
}
// 9. 创建延伸活动
const activities = [
{
name: '毛毛虫手偶制作',
domain: 'ART',
activityType: 'HANDICRAFT',
duration: 20,
onlineMaterials: JSON.stringify(['毛毛虫模板PDF', '制作视频']),
offlineMaterials: '彩纸、剪刀、胶水、眼睛贴纸',
activityGuide: '1. 准备材料\n2. 按照模板剪裁\n3. 粘贴组装\n4. 添加装饰',
objectives: JSON.stringify(['锻炼手部精细动作', '培养创造力', '巩固毛毛虫认知']),
sortOrder: 1,
},
{
name: '健康饮食分类',
domain: 'SCIENCE',
activityType: 'GAME',
duration: 15,
onlineMaterials: JSON.stringify(['食物卡片PPT']),
offlineMaterials: '食物图片卡片、分类筐',
activityGuide: '1. 展示各种食物图片\n2. 讨论健康与不健康食物\n3. 进行分类游戏',
objectives: JSON.stringify(['认识健康饮食', '学习分类', '培养健康饮食习惯']),
sortOrder: 2,
},
{
name: '蝴蝶的生命周期',
domain: 'SCIENCE',
activityType: 'EXPLORATION',
duration: 25,
onlineMaterials: JSON.stringify(['蝴蝶生长视频', '生命周期图']),
offlineMaterials: '绘本、放大镜、观察记录本',
activityGuide: '1. 观看蝴蝶生长视频\n2. 讨论四个阶段\n3. 绘制生命周期图',
objectives: JSON.stringify(['了解变态发育', '培养科学探究精神', '学习观察记录']),
sortOrder: 3,
},
];
for (const activity of activities) {
await prisma.courseActivity.upsert({
where: { id: activities.indexOf(activity) + 1 },
update: {},
create: {
courseId: course.id,
...activity,
},
});
}
console.log('创建延伸活动:', activities.length, '个');
// 10. 为租户授权课程
const tenantCourse = await prisma.tenantCourse.upsert({
where: {
tenantId_courseId: {
tenantId: tenant.id,
courseId: course.id,
},
},
update: {},
create: {
tenantId: tenant.id,
courseId: course.id,
authorized: true,
authorizedAt: new Date(),
},
});
console.log('授权课程给租户:', tenant.id, '->', course.id);
// 11. 创建第二个示例课程
const course2 = await prisma.course.upsert({
where: { id: 2 },
update: {},
create: {
name: '猜猜我有多爱你',
description: '这是一本关于爱的温暖绘本,小兔子和大兔子用各种方式表达彼此的爱。通过这个故事,孩子们可以学习到表达爱的方式,感受亲情的温暖。',
pictureBookName: '猜猜我有多爱你',
gradeTags: JSON.stringify(['MIDDLE', 'BIG']),
domainTags: JSON.stringify(['LANGUAGE', 'SOCIAL']),
duration: 25,
status: 'PUBLISHED',
version: '1.0',
coverImagePath: '/uploads/covers/love.jpg',
},
});
console.log('创建课程:', course2.name);
// 为第二个课程创建简化脚本
const scripts2 = [
{
stepIndex: 1,
stepName: '导入环节',
stepType: 'INTRODUCTION',
duration: 3,
objective: '引入爱的主题',
teacherScript: '小朋友们,你们爱爸爸妈妈吗?你们是怎么表达爱的呢?',
interactionPoints: JSON.stringify(['分享表达爱的方式']),
},
{
stepIndex: 2,
stepName: '绘本共读',
stepType: 'READING',
duration: 10,
objective: '理解故事,感受爱的表达',
teacherScript: '小栗色兔子该上床睡觉了,可是他紧紧地抓住大栗色兔子的长耳朵不放...',
interactionPoints: JSON.stringify(['模仿动作', '感受爱的比较']),
},
{
stepIndex: 3,
stepName: '情感讨论',
stepType: 'DISCUSSION',
duration: 5,
objective: '表达自己的感受',
teacherScript: '小兔子和大兔子谁的爱更多呢?你们觉得呢?',
interactionPoints: JSON.stringify(['讨论爱的深度', '分享感受']),
},
{
stepIndex: 4,
stepName: '爱的表达',
stepType: 'ACTIVITY',
duration: 5,
objective: '学会表达爱',
teacherScript: '让我们也来学学小兔子,用手臂来量量我们有多爱爸爸妈妈!',
interactionPoints: JSON.stringify(['肢体表达', '语言表达']),
},
];
for (const script of scripts2) {
await prisma.courseScript.upsert({
where: {
courseId_stepIndex: {
courseId: course2.id,
stepIndex: script.stepIndex,
},
},
update: {},
create: {
courseId: course2.id,
...script,
sortOrder: script.stepIndex,
},
});
}
// 授权第二个课程
await prisma.tenantCourse.upsert({
where: {
tenantId_courseId: {
tenantId: tenant.id,
courseId: course2.id,
},
},
update: {},
create: {
tenantId: tenant.id,
courseId: course2.id,
authorized: true,
authorizedAt: new Date(),
},
});
console.log('授权课程给租户:', tenant.id, '->', course2.id);
console.log('\n种子数据创建完成');
console.log('====================');
console.log('测试账号信息:');
console.log('超管: admin / 123456');
console.log('教师: teacher1 / 123456');
console.log('====================');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});