package controllers import ( // 根据实际项目结构调整导入路径 "Tech/models" "encoding/json" "github.com/beego/beego/v2/client/orm" beego "github.com/beego/beego/v2/server/web" // 新增导入 ) type EvaController struct { beego.Controller } // /eva/list 获取课程评价列表 func (c *EvaController) List() { type Request struct { CourseID int `json:"courseID"` } var req Request requestBody := c.Ctx.Input.RequestBody println("Request Body:", string(requestBody)) if err := json.Unmarshal(requestBody, &req); err != nil { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "请求参数格式错误: " + err.Error(), } c.ServeJSON() return } if req.CourseID == 0 { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "缺少课程ID参数", } c.ServeJSON() return } o := orm.NewOrm() var evaList []*models.CourseEvaList // 根据课程ID查询评价列表 count, err := o.QueryTable(new(models.CourseEvaList)). Filter("CourseID", req.CourseID). All(&evaList) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询评价列表失败: " + err.Error(), } c.ServeJSON() return } // 获取所有角色信息用于关联角色名称 var roleInfos []*models.RoleInfo _, err = o.QueryTable(new(models.RoleInfo)).All(&roleInfos) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询角色信息失败: " + err.Error(), } c.ServeJSON() return } // 创建角色ID到角色名称的映射 roleMap := make(map[int]string) for _, role := range roleInfos { roleMap[role.RoleID] = role.RoleName } // 为每个评价项添加角色名称 type EvaWithRoleName struct { *models.CourseEvaList RoleName string `json:"roleName"` } evaWithRoles := make([]EvaWithRoleName, len(evaList)) for i, eva := range evaList { evaWithRoles[i] = EvaWithRoleName{ CourseEvaList: eva, RoleName: roleMap[eva.EvaTargetRole], } } c.Data["json"] = map[string]interface{}{ "code": 200, "count": count, "msg": "成功", "data": evaWithRoles, } c.ServeJSON() } // /eva/add 添加课程评价 func (c *EvaController) Add() { var eva models.CourseEvaList requestBody := c.Ctx.Input.RequestBody println("Request Body:", string(requestBody)) if err := json.Unmarshal(requestBody, &eva); err != nil { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "请求参数格式错误: " + err.Error(), } c.ServeJSON() return } if eva.CourseID == 0 { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "缺少课程ID参数", } c.ServeJSON() return } o := orm.NewOrm() // 如果SeqNo为0,则查询该课程下最大的SeqNo并加1 if eva.SeqNo == 0 { var maxSeqNo int err := o.Raw("SELECT COALESCE(MAX(序号), 0) FROM CourseEvaList WHERE 课程ID = ?", eva.CourseID).QueryRow(&maxSeqNo) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询序号失败: " + err.Error(), } c.ServeJSON() return } eva.SeqNo = maxSeqNo + 1 } else { // 如果指定了SeqNo,检查该SeqNo是否已存在 var count int64 count, err := o.QueryTable(new(models.CourseEvaList)). Filter("CourseID", eva.CourseID). Filter("SeqNo", eva.SeqNo). Count() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询序号失败: " + err.Error(), } c.ServeJSON() return } // 如果SeqNo已存在,则将该SeqNo及之后的所有序号都加1 if count > 0 { // 使用倒序更新,避免主键冲突 _, err := o.Raw("UPDATE CourseEvaList SET 序号 = 序号 + 1 WHERE 课程ID = ? AND 序号 >= ? ORDER BY 序号 DESC", eva.CourseID, eva.SeqNo).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "调整序号失败: " + err.Error(), } c.ServeJSON() return } } } // 设置评价来源为教员自定义 eva.EvaSource = 1 _, err := o.Insert(&eva) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "添加评价失败: " + err.Error(), } c.ServeJSON() return } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "添加评价成功", "seqNo": eva.SeqNo, } c.ServeJSON() } // /eva/delete 删除课程评价 func (c *EvaController) Delete() { type Request struct { CourseID int `json:"courseID"` SeqNo int `json:"seqNo"` } var req Request requestBody := c.Ctx.Input.RequestBody println("Request Body:", string(requestBody)) if err := json.Unmarshal(requestBody, &req); err != nil { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "请求参数格式错误: " + err.Error(), } c.ServeJSON() return } if req.CourseID == 0 || req.SeqNo == 0 { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "缺少必要参数", } c.ServeJSON() return } o := orm.NewOrm() // 先查询评价记录,判断是否来自流程图 var eva models.CourseEvaList err := o.Raw("SELECT * FROM CourseEvaList WHERE 课程ID = ? AND 序号 = ?", req.CourseID, req.SeqNo).QueryRow(&eva) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询评价记录失败: " + err.Error(), } c.ServeJSON() return } // 如果评价来自流程图(EvaSource=0),则不允许删除 if eva.EvaSource == 0 { c.Data["json"] = map[string]interface{}{ "code": 403, "msg": "来自流程图的评价不能删除", } c.ServeJSON() return } // 执行删除操作(仅对教员自定义的评价) result, err := o.Raw("DELETE FROM CourseEvaList WHERE 课程ID = ? AND 序号 = ?", req.CourseID, req.SeqNo).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "删除评价失败: " + err.Error(), } c.ServeJSON() return } n, _ := result.RowsAffected() if n == 0 { c.Data["json"] = map[string]interface{}{ "code": 404, "msg": "未找到对应的评价记录", } c.ServeJSON() return } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "删除评价成功", } c.ServeJSON() } // /eva/update 更新课程评价 func (c *EvaController) Update() { var eva models.CourseEvaList requestBody := c.Ctx.Input.RequestBody println("Request Body:", string(requestBody)) if err := json.Unmarshal(requestBody, &eva); err != nil { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "请求参数格式错误: " + err.Error(), } c.ServeJSON() return } if eva.CourseID == 0 || eva.SeqNo == 0 { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "缺少必要参数", } c.ServeJSON() return } o := orm.NewOrm() // 先尝试读取记录,判断是否存在 existingEva := models.CourseEvaList{CourseID: eva.CourseID, SeqNo: eva.SeqNo} err := o.Read(&existingEva, "CourseID", "SeqNo") if err != nil { if err == orm.ErrNoRows { c.Data["json"] = map[string]interface{}{ "code": 404, "msg": "未找到对应的评价记录", } c.ServeJSON() return } else { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询评价记录失败: " + err.Error(), } c.ServeJSON() return } } // 如果请求中没有提供相应字段,则使用现有记录中的值 if eva.EvaTargetRole == 0 { eva.EvaTargetRole = existingEva.EvaTargetRole } if eva.EvaName == "" { eva.EvaName = existingEva.EvaName } if eva.EvaMapID == 0 { eva.EvaMapID = existingEva.EvaMapID } // 评价来源始终使用现有记录中的值(保留原始来源) eva.EvaSource = existingEva.EvaSource // 使用原生SQL更新记录 _, err = o.Raw("UPDATE CourseEvaList SET 评价目标角色=?, 评价名称=?, 评价映射ID=?, 评价类型=?, 评价赋分=?, 评价失分=?, 评价来源=?, 失格项=? WHERE 课程ID=? AND 序号=?", eva.EvaTargetRole, eva.EvaName, eva.EvaMapID, eva.EvaType, eva.EvaScore, eva.EvaDeduction, eva.EvaSource, eva.DisqualificationItem, eva.CourseID, eva.SeqNo).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "更新评价失败: " + err.Error(), } c.ServeJSON() return } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "更新评价成功", "data": eva, } c.ServeJSON() } // /eva/orderupdate 评价排序更新 func (c *EvaController) Orderupdate() { type Request struct { CourseID int `json:"courseID"` SeqNo int `json:"seqNo"` SetOrder int `json:"setorder"` } var req Request requestBody := c.Ctx.Input.RequestBody println("Request Body:", string(requestBody)) if err := json.Unmarshal(requestBody, &req); err != nil { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "请求参数格式错误: " + err.Error(), } c.ServeJSON() return } if req.CourseID == 0 || req.SeqNo == 0 || req.SetOrder == 0 { c.Ctx.Output.SetStatus(400) c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "缺少必要参数", } c.ServeJSON() return } o := orm.NewOrm() // 先尝试读取记录,判断是否存在 existingEva := models.CourseEvaList{CourseID: req.CourseID, SeqNo: req.SeqNo} err := o.Read(&existingEva, "CourseID", "SeqNo") if err != nil { if err == orm.ErrNoRows { c.Data["json"] = map[string]interface{}{ "code": 404, "msg": "未找到对应的评价记录", } } else { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询评价记录失败: " + err.Error(), } } c.ServeJSON() return } // 获取该课程的所有评价记录,按序号排序 var evaList []models.CourseEvaList _, err = o.QueryTable(new(models.CourseEvaList)). Filter("CourseID", req.CourseID). OrderBy("SeqNo"). All(&evaList) if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "查询评价列表失败: " + err.Error(), } c.ServeJSON() return } // 检查边界条件 if req.SetOrder == 1 && req.SeqNo <= 1 { // 上移但已经在最顶部 c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "无法执行上移操作,已到达顶部", } c.ServeJSON() return } if req.SetOrder == 2 && req.SeqNo >= len(evaList) { // 下移但已经在最底部 c.Data["json"] = map[string]interface{}{ "code": 400, "msg": "无法执行下移操作,已到达底部", } c.ServeJSON() return } // 确定要交换的两个序号 var targetSeqNo int if req.SetOrder == 1 { // 上移:与前一个序号交换 targetSeqNo = req.SeqNo - 1 } else { // 下移:与后一个序号交换 targetSeqNo = req.SeqNo + 1 } // 使用三步更新避免主键冲突 // 第一步:将目标序号临时设为0 _, err = o.Raw("UPDATE CourseEvaList SET 序号 = 0 WHERE 课程ID = ? AND 序号 = ?", req.CourseID, targetSeqNo).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "更新序号失败: " + err.Error(), } c.ServeJSON() return } // 第二步:将当前序号更新为目标序号 _, err = o.Raw("UPDATE CourseEvaList SET 序号 = ? WHERE 课程ID = ? AND 序号 = ?", targetSeqNo, req.CourseID, req.SeqNo).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "更新序号失败: " + err.Error(), } c.ServeJSON() return } // 第三步:将临时序号0更新为当前序号 _, err = o.Raw("UPDATE CourseEvaList SET 序号 = ? WHERE 课程ID = ? AND 序号 = 0", req.SeqNo, req.CourseID).Exec() if err != nil { c.Data["json"] = map[string]interface{}{ "code": 500, "msg": "更新序号失败: " + err.Error(), } c.ServeJSON() return } c.Data["json"] = map[string]interface{}{ "code": 200, "msg": "顺序调整成功", } c.ServeJSON() }