// =========================================== // 多班级版班级管理系统 - Go 后端 // // 开发者: Canglan // 联系方式: admin@sea-studio.top // 版权归属: Sea Network Technology Studio // 许可证: Apache License 2.0 // // 版权所有 © Sea Network Technology Studio // =========================================== package handler import ( "github.com/gin-gonic/gin" "hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/middleware" "hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/schema" "hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/service" "hz-gitea.sea-studio.top/canglan/SharedClassManager/pkg/response" ) // ClassHandler 班级管理处理器 type ClassHandler struct { classService *service.ClassService } // NewClassHandler 创建班级管理处理器 func NewClassHandler(classService *service.ClassService) *ClassHandler { return &ClassHandler{classService: classService} } // ClassList 班级列表 func (h *ClassHandler) ClassList(c *gin.Context) { includeDisabled := c.Query("include_disabled") == "true" result, err := h.classService.ListClasses(includeDisabled) if err != nil { response.InternalError(c, "获取班级列表失败") return } response.Success(c, result, "操作成功") } // ClassDetail 班级详情 func (h *ClassHandler) ClassDetail(c *gin.Context) { classID, ok := parseID(c, "class_id") if !ok { return } result, err := h.classService.GetClassDetail(classID) if err != nil { response.NotFound(c, "班级不存在") return } response.Success(c, result, "操作成功") } // ClassCreate 创建班级 func (h *ClassHandler) ClassCreate(c *gin.Context) { var req schema.ClassCreateRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } result, err := h.classService.CreateClass(req.ClassName, req.Grade, req.Description) if err != nil { response.InternalError(c, err.Error()) return } if success, _ := result["success"].(bool); !success { response.BadRequest(c, result["message"].(string)) return } response.Success(c, result, "班级创建成功") } // ClassUpdate 更新班级 func (h *ClassHandler) ClassUpdate(c *gin.Context) { classID, ok := parseID(c, "class_id") if !ok { return } var req schema.ClassUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } if err := h.classService.UpdateClass(classID, req.ClassName, req.Grade, req.Description, req.Status); err != nil { response.InternalError(c, err.Error()) return } response.SuccessWithMessage(c, "更新成功") } // ClassDelete 删除班级 func (h *ClassHandler) ClassDelete(c *gin.Context) { classID, ok := parseID(c, "class_id") if !ok { return } if err := h.classService.DeleteClass(classID); err != nil { response.InternalError(c, err.Error()) return } response.SuccessWithMessage(c, "删除成功") } // SwitchClass 切换班级上下文 func (h *ClassHandler) SwitchClass(c *gin.Context) { var req schema.SwitchClassRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } userID := middleware.GetUserID(c) result, err := h.classService.SwitchClass(userID, req.ClassID) if err != nil { response.InternalError(c, err.Error()) return } response.Success(c, result, "切换成功") } // GetSettings 获取班级设置 func (h *ClassHandler) GetSettings(c *gin.Context) { classID := middleware.GetClassID(c) result, err := h.classService.GetSettings(classID) if err != nil { response.InternalError(c, "获取设置失败") return } response.Success(c, result, "操作成功") } // allowedSettingKeys 允许通过 SaveSetting 端点写入的配置键白名单 var allowedSettingKeys = map[string]bool{ "initial_password": true, "initial_points": true, "deduction_attendance_absent": true, "deduction_attendance_late": true, "deduction_attendance_leave": true, "deduction_homework_not_submit": true, "deduction_homework_late": true, "reset_frequency": true, "reset_day_of_week": true, "reset_day_of_month": true, } // SaveSetting 保存班级设置 func (h *ClassHandler) SaveSetting(c *gin.Context) { classID := middleware.GetClassID(c) var req schema.SettingRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } if !allowedSettingKeys[req.SettingKey] { response.BadRequest(c, "不允许的配置项: "+req.SettingKey) return } if err := h.classService.SaveSetting(classID, req.SettingKey, req.SettingValue); err != nil { response.InternalError(c, "保存设置失败") return } response.SuccessWithMessage(c, "保存成功") } // GetPointLimits 获取角色加减分配置 func (h *ClassHandler) GetPointLimits(c *gin.Context) { classID := middleware.GetClassID(c) result, err := h.classService.GetSettings(classID) if err != nil { response.InternalError(c, "获取配置失败") return } response.Success(c, result, "操作成功") } // allowedPointLimitKeys 允许的操行分限制配置键白名单(与 conduct_service 读取 key 一致) var allowedPointLimitKeys = map[string]bool{ "point_limit_班长_max": true, "point_limit_班长_min": true, "point_limit_学习委员_max": true, "point_limit_学习委员_min": true, "point_limit_考勤委员_max": true, "point_limit_考勤委员_min": true, "point_limit_劳动委员_max": true, "point_limit_劳动委员_min": true, "point_limit_志愿委员_max": true, "point_limit_志愿委员_min": true, "point_limit_科任老师_max": true, "point_limit_科任老师_min": true, } // SavePointLimits 保存角色加减分配置 func (h *ClassHandler) SavePointLimits(c *gin.Context) { classID := middleware.GetClassID(c) var req map[string]string if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } for key, value := range req { if !allowedPointLimitKeys[key] { response.BadRequest(c, "不允许的配置项: "+key) return } if err := h.classService.SaveSetting(classID, key, value); err != nil { response.InternalError(c, "保存配置失败") return } } response.SuccessWithMessage(c, "保存成功") } // GetFeatures 获取功能开关 func (h *ClassHandler) GetFeatures(c *gin.Context) { classID := middleware.GetClassID(c) result, err := h.classService.GetFeatures(classID) if err != nil { response.InternalError(c, "获取功能开关失败") return } response.Success(c, result, "操作成功") } // allowedFeatureKeys 允许的功能开关键白名单 var allowedFeatureKeys = map[string]bool{ "parent_account_enabled": true, "parent_password_change_enabled": true, "parent_view_attendance": true, "parent_view_ranking": true, "student_view_ranking": true, "homework_management": true, "attendance_management": true, "cadre_homework": true, } // SaveFeature 保存功能开关 func (h *ClassHandler) SaveFeature(c *gin.Context) { classID := middleware.GetClassID(c) var req schema.FeatureToggleRequest if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "参数错误") return } if !allowedFeatureKeys[req.FeatureKey] { response.BadRequest(c, "不允许的功能开关: "+req.FeatureKey) return } if err := h.classService.SaveFeature(classID, req.FeatureKey, req.Enabled); err != nil { response.InternalError(c, "保存功能开关失败") return } response.SuccessWithMessage(c, "保存成功") }