新增智能新建题目功能

This commit is contained in:
2025-11-17 22:55:28 +08:00
parent 0fff276e59
commit e3366af9ec
9 changed files with 834 additions and 57 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ runmode = dev
# MySQL - 远程连接配置
mysqluser = gotest
mysqlpass = 2nZhRdMPCNZrdzsd
mysqlurls = 212.64.112.158:3388
mysqlurls = 192.168.31.10:3306
mysqldb = gotest
# ORM配置
+90
View File
@@ -144,6 +144,96 @@ func (c *ExamQuestionController) Create() {
c.ServeJSON()
}
// BatchCreate
// @router /exam-questions/batch [post]
func (c *ExamQuestionController) BatchCreate() {
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
var payload struct {
Items []struct {
QuestionTitle string `json:"question_title"`
QuestionType int8 `json:"question_type"`
Score float64 `json:"score"`
QuestionAnalysis string `json:"question_analysis"`
Options []map[string]string `json:"options"`
Answer interface{} `json:"answer"`
} `json:"items"`
}
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &payload); err != nil {
c.Data["json"] = map[string]interface{}{"code": 1, "message": "请求参数错误: " + err.Error(), "data": nil}
c.ServeJSON()
return
}
if len(payload.Items) == 0 {
c.Data["json"] = map[string]interface{}{"code": 1, "message": "导入数据为空", "data": nil}
c.ServeJSON()
return
}
success := 0
fails := 0
createdIds := make([]int64, 0, len(payload.Items))
updatedIds := make([]int64, 0, len(payload.Items))
for _, item := range payload.Items {
q := &models.ExamQuestion{
TenantId: tenantId,
QuestionType: item.QuestionType,
QuestionTitle: item.QuestionTitle,
QuestionAnalysis: item.QuestionAnalysis,
Score: item.Score,
Status: 1,
}
var opts []models.ExamQuestionOption
for _, o := range item.Options {
opts = append(opts, models.ExamQuestionOption{OptionLabel: o["label"], OptionContent: o["content"]})
}
answerContent := ""
switch v := item.Answer.(type) {
case string:
answerContent = v
case []interface{}:
for i, it := range v {
if s, ok := it.(string); ok {
if i == 0 {
answerContent = s
} else {
answerContent += "," + s
}
}
}
}
// 如果存在完全匹配的题目标题,则覆盖更新;否则新增
if existing, err := services.FindExamQuestionByTitle(tenantId, item.QuestionTitle); err == nil && existing != nil {
if err := services.UpdateExamQuestion(tenantId, existing.Id, q, opts, answerContent); err != nil {
fails++
continue
}
updatedIds = append(updatedIds, existing.Id)
success++
} else {
id, err := services.CreateExamQuestion(tenantId, q, opts, answerContent)
if err != nil {
fails++
continue
}
createdIds = append(createdIds, id)
success++
}
}
c.Data["json"] = map[string]interface{}{
"code": 0,
"message": "批量导入完成",
"data": map[string]interface{}{
"success": success,
"failed": fails,
"created_ids": createdIds,
"updated_ids": updatedIds,
},
}
c.ServeJSON()
}
// Update
// @router /exam-questions/:id [put]
func (c *ExamQuestionController) Update() {
+2
View File
@@ -286,6 +286,8 @@ func init() {
// 考试题目路由
beego.Router("/api/exam-questions", &controllers.ExamQuestionController{}, "get:GetList;post:Create")
beego.Router("/api/exam-questions/:id", &controllers.ExamQuestionController{}, "get:GetDetail;put:Update;delete:Delete")
// 题目批量导入路由
beego.Router("/api/exam-questions/batch", &controllers.ExamQuestionController{}, "post:BatchCreate")
// 考试题库路由
beego.Router("/api/exam-question-banks", &controllers.ExamQuestionBankController{}, "get:GetBankList;post:CreateBank")
+15
View File
@@ -74,6 +74,21 @@ func GetExamQuestionDetail(tenantId int, id int64) (*QuestionWithMeta, error) {
return &QuestionWithMeta{Question: q, Options: opts, Answer: a}, nil
}
// FindExamQuestionByTitle 在指定租户下根据题目标题精确查找试题
// 用于批量导入时判断是否存在完全相同题目,以便执行覆盖更新
func FindExamQuestionByTitle(tenantId int, title string) (*models.ExamQuestion, error) {
o := orm.NewOrm()
q := new(models.ExamQuestion)
qs := o.QueryTable(q).Filter("delete_time__isnull", true).Filter("question_title", title)
if tenantId > 0 {
qs = qs.Filter("tenant_id", tenantId)
}
if err := qs.One(q); err != nil {
return nil, err
}
return q, nil
}
func CreateExamQuestion(tenantId int, q *models.ExamQuestion, options []models.ExamQuestionOption, answerContent string) (int64, error) {
o := orm.NewOrm()
if tenantId > 0 {