课程库 Excel 导入导出已完成:
支持下载标准导入模板。 导出严格沿用当前关键词、学院、分类、课程性质和状态筛选。 以课程编码为唯一键:存在则更新,不存在则新增。 校验学院编码、课程分类、课程性质、学分学时及考核方式。 整批原子导入,任一行错误则全部不写入,并提示具体行号。 学院管理员仍只能维护本学院的专业课和实践课,无法借 Excel 越权。 界面入口沿用现有课程库工具栏样式。
This commit is contained in:
@@ -28,6 +28,7 @@ public sealed class DatabaseInitializer(
|
||||
|
||||
await SeedRolesAsync();
|
||||
await SeedAdministratorAsync();
|
||||
await SeedCourseCategoriesAsync();
|
||||
|
||||
if (environment.IsDevelopment())
|
||||
{
|
||||
@@ -108,6 +109,55 @@ public sealed class DatabaseInitializer(
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SeedCourseCategoriesAsync()
|
||||
{
|
||||
var defaults = new[]
|
||||
{
|
||||
("BASIC", "基础课程", 10),
|
||||
("MORAL", "德育课程", 20),
|
||||
("AESTHETIC", "美育课程", 30),
|
||||
("LABOR", "劳动教育", 40),
|
||||
("INNOVATION", "创新创业", 50),
|
||||
("ENGLISH", "大学英语", 60),
|
||||
("SPORTS", "大学体育", 70),
|
||||
("MILITARY", "国防教育", 80),
|
||||
("MAJOR", "专业教育", 90),
|
||||
("PRACTICE", "实践教学", 100)
|
||||
};
|
||||
var existingCodes = (await db.CourseCategories
|
||||
.Select(x => x.Code)
|
||||
.ToListAsync())
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var (code, name, sortOrder) in defaults)
|
||||
{
|
||||
if (existingCodes.Contains(code)) continue;
|
||||
db.CourseCategories.Add(new CourseCategory
|
||||
{
|
||||
Code = code,
|
||||
Name = name,
|
||||
SortOrder = sortOrder
|
||||
});
|
||||
}
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var categories = await db.CourseCategories
|
||||
.ToDictionaryAsync(x => x.Code, StringComparer.OrdinalIgnoreCase);
|
||||
var uncategorizedCourses = await db.Courses
|
||||
.Where(x => x.CourseCategoryId == null)
|
||||
.ToListAsync();
|
||||
foreach (var course in uncategorizedCourses)
|
||||
{
|
||||
var categoryCode = course.Nature switch
|
||||
{
|
||||
CourseNature.Practice => "PRACTICE",
|
||||
CourseNature.MajorRequired or CourseNature.MajorElective => "MAJOR",
|
||||
_ => "BASIC"
|
||||
};
|
||||
course.CourseCategoryId = categories[categoryCode].Id;
|
||||
}
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private async Task SeedDevelopmentDataAsync()
|
||||
{
|
||||
if (!await db.Campuses.AnyAsync())
|
||||
@@ -242,6 +292,9 @@ public sealed class DatabaseInitializer(
|
||||
});
|
||||
}
|
||||
|
||||
var courseCategories = await db.CourseCategories
|
||||
.ToDictionaryAsync(x => x.Code, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (!await db.Courses.AnyAsync())
|
||||
{
|
||||
db.Courses.AddRange(
|
||||
@@ -251,6 +304,7 @@ public sealed class DatabaseInitializer(
|
||||
Name = "程序设计基础",
|
||||
EnglishName = "Fundamentals of Programming",
|
||||
CollegeId = computerCollege.Id,
|
||||
CourseCategoryId = courseCategories["BASIC"].Id,
|
||||
Credits = 4,
|
||||
TotalHours = 64,
|
||||
LectureHours = 40,
|
||||
@@ -265,6 +319,7 @@ public sealed class DatabaseInitializer(
|
||||
Name = "数据结构",
|
||||
EnglishName = "Data Structures",
|
||||
CollegeId = computerCollege.Id,
|
||||
CourseCategoryId = courseCategories["BASIC"].Id,
|
||||
Credits = 3.5m,
|
||||
TotalHours = 56,
|
||||
LectureHours = 40,
|
||||
@@ -278,6 +333,7 @@ public sealed class DatabaseInitializer(
|
||||
Name = "软件工程实践",
|
||||
EnglishName = "Software Engineering Practice",
|
||||
CollegeId = computerCollege.Id,
|
||||
CourseCategoryId = courseCategories["PRACTICE"].Id,
|
||||
Credits = 2,
|
||||
TotalHours = 48,
|
||||
LectureHours = 8,
|
||||
@@ -286,7 +342,6 @@ public sealed class DatabaseInitializer(
|
||||
AssessmentMethod = AssessmentMethod.Assessment
|
||||
});
|
||||
}
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
if (!await db.CurriculumPlans.AnyAsync())
|
||||
|
||||
Reference in New Issue
Block a user