feat(material): add material handling and routing functionality
Some checks failed
Build Backend / build (push) Failing after 12m1s
Build Backend / build-docker (push) Has been skipped

- Introduced MaterialHandler for managing learning materials and subjects.
- Updated router to include routes for public and admin material management.
- Enhanced database initialization with material subject and file models.
- Implemented seeding logic for material subjects and files.
- Updated wire generation to include MaterialHandler and related services.
This commit is contained in:
lafay
2026-03-25 20:44:12 +08:00
parent 28a45caad3
commit 0ef8e5a7e1
10 changed files with 1122 additions and 22 deletions

View File

@@ -159,6 +159,10 @@ func autoMigrate(db *gorm.DB) error {
&Role{},
&UserRole{},
&CasbinRule{},
// 学习资料相关
&MaterialSubject{},
&MaterialFile{},
)
if err != nil {
return err
@@ -184,6 +188,11 @@ func autoMigrate(db *gorm.DB) error {
return fmt.Errorf("failed to seed channels: %w", err)
}
// 初始化学习资料学科种子数据
if err := seedMaterialSubjects(db); err != nil {
return fmt.Errorf("failed to seed material subjects: %w", err)
}
return nil
}
@@ -321,8 +330,18 @@ func seedPermissions(db *gorm.DB) error {
return nil
}
// seedChannels 初始化频道种子数据(按 slug 幂等
// seedChannels 初始化频道种子数据(仅在表为空时
func seedChannels(db *gorm.DB) error {
// 检查是否已有频道数据
var count int64
if err := db.Model(&Channel{}).Count(&count).Error; err != nil {
return err
}
if count > 0 {
zap.L().Info("Channels already exist, skipping seed", zap.Int64("count", count))
return nil
}
defaultChannels := []Channel{
{Name: "跳蚤市场", Slug: "market", Description: "二手交易与闲置发布", SortOrder: 10, IsActive: true},
{Name: "课程交流", Slug: "courses", Description: "课程资料、选课与学习讨论", SortOrder: 20, IsActive: true},
@@ -331,33 +350,45 @@ func seedChannels(db *gorm.DB) error {
{Name: "保研出国", Slug: "graduate-abroad", Description: "保研、留学申请与经验分享", SortOrder: 50, IsActive: true},
}
for _, item := range defaultChannels {
var existing Channel
err := db.Where("slug = ?", item.Slug).First(&existing).Error
if err == nil {
updates := map[string]any{
"name": item.Name,
"description": item.Description,
"sort_order": item.SortOrder,
"is_active": item.IsActive,
}
if uerr := db.Model(&existing).Updates(updates).Error; uerr != nil {
return uerr
}
continue
}
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
if cerr := db.Create(&item).Error; cerr != nil {
return cerr
}
if err := db.Create(&defaultChannels).Error; err != nil {
return err
}
zap.L().Info("Seeded channels successfully", zap.Int("count", len(defaultChannels)))
return nil
}
// seedMaterialSubjects 初始化学习资料学科种子数据(仅在表为空时)
func seedMaterialSubjects(db *gorm.DB) error {
// 检查是否已有数据
var count int64
if err := db.Model(&MaterialSubject{}).Count(&count).Error; err != nil {
return err
}
if count > 0 {
zap.L().Info("Material subjects already exist, skipping seed", zap.Int64("count", count))
return nil
}
defaultSubjects := []MaterialSubject{
{Name: "数学", Icon: "calculator-variant", Color: "#FF6B6B", Description: "高等数学、线性代数、概率论等", SortOrder: 10, IsActive: true},
{Name: "英语", Icon: "translate", Color: "#4ECDC4", Description: "四六级、考研英语、托福雅思等", SortOrder: 20, IsActive: true},
{Name: "物理", Icon: "atom", Color: "#45B7D1", Description: "大学物理、电磁学、力学等", SortOrder: 30, IsActive: true},
{Name: "化学", Icon: "flask", Color: "#96CEB4", Description: "有机化学、无机化学、分析化学等", SortOrder: 40, IsActive: true},
{Name: "计算机", Icon: "laptop", Color: "#FFEAA7", Description: "数据结构、算法、操作系统等", SortOrder: 50, IsActive: true},
{Name: "经济管理", Icon: "chart-line", Color: "#DDA0DD", Description: "微观经济学、宏观经济学、管理学等", SortOrder: 60, IsActive: true},
{Name: "法学", Icon: "scale-balance", Color: "#F39C12", Description: "民法、刑法、宪法等", SortOrder: 70, IsActive: true},
{Name: "语文文学", Icon: "book-open-page-variant", Color: "#3498DB", Description: "古代文学、现代文学、写作等", SortOrder: 80, IsActive: true},
}
if err := db.Create(&defaultSubjects).Error; err != nil {
return err
}
zap.L().Info("Seeded material subjects successfully", zap.Int("count", len(defaultSubjects)))
return nil
}
// CloseDB 关闭数据库连接
func CloseDB(db *gorm.DB) {
if sqlDB, err := db.DB(); err == nil {