449 lines
13 KiB
Go
449 lines
13 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
|
|
"server/models"
|
|
"server/services"
|
|
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
type ExamQuestionController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type ExamQuestionBankController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
// Get list
|
|
// @router /exam-questions [get]
|
|
func (c *ExamQuestionController) GetList() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
keyword := c.GetString("keyword")
|
|
typeStr := c.GetString("type")
|
|
bankId, _ := c.GetInt64("bank_id", 0)
|
|
|
|
var qtype *int8
|
|
if typeStr != "" {
|
|
if iv, err := strconv.Atoi(typeStr); err == nil {
|
|
v := int8(iv)
|
|
qtype = &v
|
|
}
|
|
}
|
|
|
|
page, _ := c.GetInt("page", 1)
|
|
pageSize, _ := c.GetInt("pageSize", 10)
|
|
|
|
list, total, err := services.GetExamQuestions(services.QuestionListParams{
|
|
TenantId: tenantId,
|
|
Keyword: keyword,
|
|
QuestionType: qtype,
|
|
BankId: bankId,
|
|
Page: page,
|
|
PageSize: pageSize,
|
|
})
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "获取试题列表失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
|
|
items := make([]map[string]interface{}, 0, len(list))
|
|
for _, q := range list {
|
|
if q == nil {
|
|
continue
|
|
}
|
|
items = append(items, map[string]interface{}{
|
|
"id": q.Id,
|
|
"tenant_id": q.TenantId,
|
|
"question_type": q.QuestionType,
|
|
"question_title": q.QuestionTitle,
|
|
"score": q.Score,
|
|
})
|
|
}
|
|
|
|
c.Data["json"] = map[string]interface{}{
|
|
"code": 0,
|
|
"message": "ok",
|
|
"data": map[string]interface{}{
|
|
"list": items,
|
|
"total": total,
|
|
},
|
|
}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// Get detail
|
|
// @router /exam-questions/:id [get]
|
|
func (c *ExamQuestionController) GetDetail() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
detail, err := services.GetExamQuestionDetail(tenantId, id)
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "试题不存在", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "ok", "data": detail}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// Create
|
|
// @router /exam-questions [post]
|
|
func (c *ExamQuestionController) Create() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
var payload 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"`
|
|
BankId int64 `json:"bank_id"`
|
|
}
|
|
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
|
|
}
|
|
q := &models.ExamQuestion{
|
|
TenantId: tenantId,
|
|
QuestionType: payload.QuestionType,
|
|
QuestionTitle: payload.QuestionTitle,
|
|
QuestionAnalysis: payload.QuestionAnalysis,
|
|
Score: payload.Score,
|
|
Status: 1,
|
|
}
|
|
if payload.BankId > 0 {
|
|
q.BankId = payload.BankId
|
|
}
|
|
var opts []models.ExamQuestionOption
|
|
for _, o := range payload.Options {
|
|
opts = append(opts, models.ExamQuestionOption{OptionLabel: o["label"], OptionContent: o["content"]})
|
|
}
|
|
answerContent := ""
|
|
switch v := payload.Answer.(type) {
|
|
case string:
|
|
answerContent = v
|
|
case []interface{}:
|
|
for i, item := range v {
|
|
if s, ok := item.(string); ok {
|
|
if i == 0 {
|
|
answerContent = s
|
|
} else {
|
|
answerContent += "," + s
|
|
}
|
|
}
|
|
}
|
|
}
|
|
id, err := services.CreateExamQuestion(tenantId, q, opts, answerContent)
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "创建失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "创建成功", "data": map[string]interface{}{"id": id}}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// BatchCreate
|
|
// @router /exam-questions/batch [post]
|
|
func (c *ExamQuestionController) BatchCreate() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
var payload struct {
|
|
BankId int64 `json:"bank_id"`
|
|
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,
|
|
}
|
|
if payload.BankId > 0 {
|
|
q.BankId = payload.BankId
|
|
}
|
|
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() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
var payload 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"`
|
|
BankId int64 `json:"bank_id"`
|
|
}
|
|
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
|
|
}
|
|
q := &models.ExamQuestion{QuestionType: payload.QuestionType, QuestionTitle: payload.QuestionTitle, QuestionAnalysis: payload.QuestionAnalysis, Score: payload.Score}
|
|
if payload.BankId > 0 {
|
|
q.BankId = payload.BankId
|
|
}
|
|
var opts []models.ExamQuestionOption
|
|
for _, o := range payload.Options {
|
|
opts = append(opts, models.ExamQuestionOption{OptionLabel: o["label"], OptionContent: o["content"]})
|
|
}
|
|
answerContent := ""
|
|
switch v := payload.Answer.(type) {
|
|
case string:
|
|
answerContent = v
|
|
case []interface{}:
|
|
for i, item := range v {
|
|
if s, ok := item.(string); ok {
|
|
if i == 0 {
|
|
answerContent = s
|
|
} else {
|
|
answerContent += "," + s
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if err := services.UpdateExamQuestion(tenantId, id, q, opts, answerContent); err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "更新失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "更新成功", "data": nil}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// Delete
|
|
// @router /exam-questions/:id [delete]
|
|
func (c *ExamQuestionController) Delete() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
if err := services.DeleteExamQuestion(tenantId, id); err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "删除失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "删除成功", "data": nil}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// GetBankList
|
|
// @router /exam-question-banks [get]
|
|
func (c *ExamQuestionBankController) GetBankList() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
keyword := c.GetString("keyword")
|
|
page, _ := c.GetInt("page", 1)
|
|
pageSize, _ := c.GetInt("pageSize", 10)
|
|
list, total, err := services.GetExamQuestionBanks(services.BankListParams{
|
|
TenantId: tenantId,
|
|
Keyword: keyword,
|
|
Page: page,
|
|
PageSize: pageSize,
|
|
})
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "获取试题库列表失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "ok", "data": map[string]interface{}{"list": list, "total": total}}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// GetBankDetail
|
|
// @router /exam-question-banks/:id [get]
|
|
func (c *ExamQuestionBankController) GetBankDetail() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
bank, err := services.GetExamQuestionBankDetail(tenantId, id)
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "试题库不存在", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "ok", "data": bank}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// CreateBank
|
|
// @router /exam-question-banks [post]
|
|
func (c *ExamQuestionBankController) CreateBank() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
var payload struct {
|
|
BankName string `json:"bank_name"`
|
|
BankDesc string `json:"bank_desc"`
|
|
}
|
|
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
|
|
}
|
|
bank := &models.ExamQuestionBank{
|
|
TenantId: tenantId,
|
|
BankName: payload.BankName,
|
|
BankDesc: payload.BankDesc,
|
|
Status: 1,
|
|
}
|
|
id, err := services.CreateExamQuestionBank(tenantId, bank)
|
|
if err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "创建失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "创建成功", "data": map[string]interface{}{"id": id}}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// UpdateBank
|
|
// @router /exam-question-banks/:id [put]
|
|
func (c *ExamQuestionBankController) UpdateBank() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
var payload struct {
|
|
BankName string `json:"bank_name"`
|
|
BankDesc string `json:"bank_desc"`
|
|
}
|
|
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
|
|
}
|
|
bank := &models.ExamQuestionBank{
|
|
Id: id,
|
|
TenantId: tenantId,
|
|
BankName: payload.BankName,
|
|
BankDesc: payload.BankDesc,
|
|
}
|
|
if err := services.UpdateExamQuestionBank(tenantId, id, bank); err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "更新失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "更新成功", "data": nil}
|
|
c.ServeJSON()
|
|
}
|
|
|
|
// DeleteBank
|
|
// @router /exam-question-banks/:id [delete]
|
|
func (c *ExamQuestionBankController) DeleteBank() {
|
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
|
id, err := c.GetInt64(":id")
|
|
if err != nil || id <= 0 {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "ID无效", "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
if err := services.DeleteExamQuestionBank(tenantId, id); err != nil {
|
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "删除失败: " + err.Error(), "data": nil}
|
|
c.ServeJSON()
|
|
return
|
|
}
|
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "删除成功", "data": nil}
|
|
c.ServeJSON()
|
|
}
|