260 lines
7.9 KiB
Go
260 lines
7.9 KiB
Go
package services
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"server/models"
|
|
|
|
"github.com/beego/beego/v2/client/orm"
|
|
)
|
|
|
|
type QuestionListParams struct {
|
|
TenantId int
|
|
Keyword string
|
|
QuestionType *int8
|
|
BankId int64
|
|
Page int
|
|
PageSize int
|
|
}
|
|
|
|
// CountQuestionsInBank 统计指定题库下的题目数量(仅统计未删除且启用的题目)
|
|
func CountQuestionsInBank(tenantId int, bankId int64) (int64, error) {
|
|
o := orm.NewOrm()
|
|
qs := o.QueryTable(new(models.ExamQuestion)).Filter("delete_time__isnull", true).Filter("status", 1).Filter("bank_id", bankId)
|
|
if tenantId > 0 {
|
|
qs = qs.Filter("tenant_id", tenantId)
|
|
}
|
|
return qs.Count()
|
|
}
|
|
|
|
type QuestionWithMeta struct {
|
|
Question *models.ExamQuestion
|
|
Options []*models.ExamQuestionOption
|
|
Answer *models.ExamQuestionAnswer
|
|
}
|
|
|
|
type BankListParams struct {
|
|
TenantId int
|
|
Keyword string
|
|
Page int
|
|
PageSize int
|
|
}
|
|
|
|
func GetExamQuestions(params QuestionListParams) ([]*models.ExamQuestion, int64, error) {
|
|
o := orm.NewOrm()
|
|
qs := o.QueryTable(new(models.ExamQuestion)).Filter("delete_time__isnull", true).Filter("status", 1)
|
|
if params.TenantId > 0 {
|
|
qs = qs.Filter("tenant_id", params.TenantId)
|
|
}
|
|
if params.Keyword != "" {
|
|
qs = qs.Filter("question_title__icontains", params.Keyword)
|
|
}
|
|
if params.QuestionType != nil {
|
|
qs = qs.Filter("question_type", *params.QuestionType)
|
|
}
|
|
if params.BankId > 0 {
|
|
qs = qs.Filter("bank_id", params.BankId)
|
|
}
|
|
total, err := qs.Count()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if params.Page <= 0 {
|
|
params.Page = 1
|
|
}
|
|
if params.PageSize <= 0 {
|
|
params.PageSize = 10
|
|
}
|
|
offset := (params.Page - 1) * params.PageSize
|
|
var list []*models.ExamQuestion
|
|
_, err = qs.OrderBy("-id").Limit(params.PageSize, offset).All(&list, "Id", "TenantId", "QuestionType", "QuestionTitle", "Score")
|
|
return list, total, err
|
|
}
|
|
|
|
func GetExamQuestionDetail(tenantId int, id int64) (*QuestionWithMeta, error) {
|
|
o := orm.NewOrm()
|
|
q := new(models.ExamQuestion)
|
|
if err := o.QueryTable(q).Filter("id", id).Filter("delete_time__isnull", true).One(q); err != nil {
|
|
return nil, err
|
|
}
|
|
if tenantId > 0 && q.TenantId != tenantId {
|
|
return nil, errors.New("not found")
|
|
}
|
|
var opts []*models.ExamQuestionOption
|
|
_, _ = o.QueryTable(new(models.ExamQuestionOption)).Filter("question_id", q.Id).Filter("delete_time__isnull", true).All(&opts)
|
|
a := new(models.ExamQuestionAnswer)
|
|
_ = o.QueryTable(a).Filter("question_id", q.Id).Filter("delete_time__isnull", true).One(a)
|
|
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 {
|
|
q.TenantId = tenantId
|
|
}
|
|
q.Status = 1
|
|
if _, err := o.Insert(q); err != nil {
|
|
return 0, err
|
|
}
|
|
for i := range options {
|
|
options[i].TenantId = q.TenantId
|
|
options[i].QuestionId = q.Id
|
|
_, _ = o.Insert(&options[i])
|
|
}
|
|
ans := &models.ExamQuestionAnswer{TenantId: q.TenantId, QuestionId: q.Id, AnswerContent: answerContent}
|
|
_, _ = o.Insert(ans)
|
|
return q.Id, nil
|
|
}
|
|
|
|
func UpdateExamQuestion(tenantId int, id int64, q *models.ExamQuestion, options []models.ExamQuestionOption, answerContent string) error {
|
|
o := orm.NewOrm()
|
|
existing := models.ExamQuestion{Id: id}
|
|
if err := o.Read(&existing); err != nil {
|
|
return err
|
|
}
|
|
if tenantId > 0 && existing.TenantId != tenantId {
|
|
return errors.New("not found")
|
|
}
|
|
existing.QuestionType = q.QuestionType
|
|
existing.QuestionTitle = q.QuestionTitle
|
|
existing.QuestionAnalysis = q.QuestionAnalysis
|
|
existing.Score = q.Score
|
|
// 可选更新题库归属
|
|
fields := []string{"QuestionType", "QuestionTitle", "QuestionAnalysis", "Score"}
|
|
if q.BankId > 0 {
|
|
existing.BankId = q.BankId
|
|
fields = append(fields, "BankId")
|
|
}
|
|
if _, err := o.Update(&existing, fields...); err != nil {
|
|
return err
|
|
}
|
|
// soft delete old options and answer
|
|
now := time.Now()
|
|
o.QueryTable(new(models.ExamQuestionOption)).Filter("question_id", id).Filter("delete_time__isnull", true).Update(orm.Params{"delete_time": now})
|
|
o.QueryTable(new(models.ExamQuestionAnswer)).Filter("question_id", id).Filter("delete_time__isnull", true).Update(orm.Params{"delete_time": now})
|
|
for i := range options {
|
|
options[i].TenantId = existing.TenantId
|
|
options[i].QuestionId = id
|
|
_, _ = o.Insert(&options[i])
|
|
}
|
|
ans := &models.ExamQuestionAnswer{TenantId: existing.TenantId, QuestionId: id, AnswerContent: answerContent}
|
|
_, _ = o.Insert(ans)
|
|
return nil
|
|
}
|
|
|
|
func DeleteExamQuestion(tenantId int, id int64) error {
|
|
o := orm.NewOrm()
|
|
existing := models.ExamQuestion{Id: id}
|
|
if err := o.Read(&existing); err != nil {
|
|
return err
|
|
}
|
|
if tenantId > 0 && existing.TenantId != tenantId {
|
|
return errors.New("not found")
|
|
}
|
|
now := time.Now()
|
|
if _, err := o.QueryTable(new(models.ExamQuestion)).Filter("id", id).Update(orm.Params{"delete_time": now}); err != nil {
|
|
return err
|
|
}
|
|
o.QueryTable(new(models.ExamQuestionOption)).Filter("question_id", id).Filter("delete_time__isnull", true).Update(orm.Params{"delete_time": now})
|
|
o.QueryTable(new(models.ExamQuestionAnswer)).Filter("question_id", id).Filter("delete_time__isnull", true).Update(orm.Params{"delete_time": now})
|
|
return nil
|
|
}
|
|
|
|
func GetExamQuestionBanks(params BankListParams) ([]*models.ExamQuestionBank, int64, error) {
|
|
o := orm.NewOrm()
|
|
qs := o.QueryTable(new(models.ExamQuestionBank)).Filter("delete_time__isnull", true).Filter("status", 1)
|
|
if params.TenantId > 0 {
|
|
qs = qs.Filter("tenant_id", params.TenantId)
|
|
}
|
|
if params.Keyword != "" {
|
|
qs = qs.Filter("bank_name__icontains", params.Keyword)
|
|
}
|
|
total, err := qs.Count()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if params.Page <= 0 {
|
|
params.Page = 1
|
|
}
|
|
if params.PageSize <= 0 {
|
|
params.PageSize = 10
|
|
}
|
|
offset := (params.Page - 1) * params.PageSize
|
|
var list []*models.ExamQuestionBank
|
|
_, err = qs.OrderBy("-id").Limit(params.PageSize, offset).All(&list, "Id", "TenantId", "BankName", "BankDesc")
|
|
return list, total, err
|
|
}
|
|
|
|
func GetExamQuestionBankDetail(tenantId int, id int64) (*models.ExamQuestionBank, error) {
|
|
o := orm.NewOrm()
|
|
bank := new(models.ExamQuestionBank)
|
|
if err := o.QueryTable(bank).Filter("id", id).Filter("delete_time__isnull", true).One(bank); err != nil {
|
|
return nil, err
|
|
}
|
|
if tenantId > 0 && bank.TenantId != tenantId {
|
|
return nil, errors.New("not found")
|
|
}
|
|
return bank, nil
|
|
}
|
|
|
|
func CreateExamQuestionBank(tenantId int, bank *models.ExamQuestionBank) (int64, error) {
|
|
o := orm.NewOrm()
|
|
if tenantId > 0 {
|
|
bank.TenantId = tenantId
|
|
}
|
|
bank.Status = 1
|
|
if _, err := o.Insert(bank); err != nil {
|
|
return 0, err
|
|
}
|
|
return bank.Id, nil
|
|
}
|
|
|
|
func UpdateExamQuestionBank(tenantId int, id int64, bank *models.ExamQuestionBank) error {
|
|
o := orm.NewOrm()
|
|
existing := models.ExamQuestionBank{Id: id}
|
|
if err := o.Read(&existing); err != nil {
|
|
return err
|
|
}
|
|
if tenantId > 0 && existing.TenantId != tenantId {
|
|
return errors.New("not found")
|
|
}
|
|
existing.BankName = bank.BankName
|
|
existing.BankDesc = bank.BankDesc
|
|
if _, err := o.Update(&existing, "BankName", "BankDesc"); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func DeleteExamQuestionBank(tenantId int, id int64) error {
|
|
o := orm.NewOrm()
|
|
existing := models.ExamQuestionBank{Id: id}
|
|
if err := o.Read(&existing); err != nil {
|
|
return err
|
|
}
|
|
if tenantId > 0 && existing.TenantId != tenantId {
|
|
return errors.New("not found")
|
|
}
|
|
now := time.Now()
|
|
if _, err := o.QueryTable(new(models.ExamQuestionBank)).Filter("id", id).Update(orm.Params{"delete_time": now}); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|