题库增加题目数量展示
This commit is contained in:
parent
7664821d88
commit
aae2fe1e14
@ -22,6 +22,7 @@
|
|||||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||||
<el-table-column prop="bank_name" label="题库名称" min-width="200" show-overflow-tooltip />
|
<el-table-column prop="bank_name" label="题库名称" min-width="200" show-overflow-tooltip />
|
||||||
<el-table-column prop="bank_desc" label="描述" min-width="200" show-overflow-tooltip />
|
<el-table-column prop="bank_desc" label="描述" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="total_count" label="题目数量" min-width="60" align="center" />
|
||||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button link type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
<el-button link type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
|||||||
@ -2,9 +2,9 @@ package controllers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"server/models"
|
"server/models"
|
||||||
"server/services"
|
"server/services"
|
||||||
@ -18,27 +18,27 @@ type ExamQuestionController struct {
|
|||||||
|
|
||||||
// normalizeText removes HTML tags, converts to space, and collapses whitespace
|
// normalizeText removes HTML tags, converts to space, and collapses whitespace
|
||||||
func normalizeText(s string) string {
|
func normalizeText(s string) string {
|
||||||
str := strings.TrimSpace(s)
|
str := strings.TrimSpace(s)
|
||||||
if str == "" {
|
if str == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
// remove HTML tags
|
// remove HTML tags
|
||||||
re := regexp.MustCompile("<[^>]*>")
|
re := regexp.MustCompile("<[^>]*>")
|
||||||
str = re.ReplaceAllString(str, "")
|
str = re.ReplaceAllString(str, "")
|
||||||
// decode common entities
|
// decode common entities
|
||||||
str = strings.ReplaceAll(str, " ", " ")
|
str = strings.ReplaceAll(str, " ", " ")
|
||||||
str = strings.ReplaceAll(str, " ", " ")
|
str = strings.ReplaceAll(str, " ", " ")
|
||||||
// collapse whitespace
|
// collapse whitespace
|
||||||
reSpace := regexp.MustCompile(`\s+`)
|
reSpace := regexp.MustCompile(`\s+`)
|
||||||
str = reSpace.ReplaceAllString(str, " ")
|
str = reSpace.ReplaceAllString(str, " ")
|
||||||
return strings.TrimSpace(str)
|
return strings.TrimSpace(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeMatchRate returns a simple similarity percentage between two strings based on
|
// computeMatchRate returns a simple similarity percentage between two strings based on
|
||||||
// position-wise identical characters over the max length, rounded to integer 0-100.
|
// position-wise identical characters over the max length, rounded to integer 0-100.
|
||||||
func computeMatchRate(a, b string) int {
|
func computeMatchRate(a, b string) int {
|
||||||
s1 := normalizeText(a)
|
s1 := normalizeText(a)
|
||||||
s2 := normalizeText(b)
|
s2 := normalizeText(b)
|
||||||
if s1 == "" && s2 == "" {
|
if s1 == "" && s2 == "" {
|
||||||
return 100
|
return 100
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ type ExamQuestionBankController struct {
|
|||||||
// @router /exam-questions [get]
|
// @router /exam-questions [get]
|
||||||
func (c *ExamQuestionController) GetList() {
|
func (c *ExamQuestionController) GetList() {
|
||||||
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
||||||
keyword := c.GetString("keyword")
|
keyword := c.GetString("keyword")
|
||||||
typeStr := c.GetString("type")
|
typeStr := c.GetString("type")
|
||||||
bankId, _ := c.GetInt64("bank_id", 0)
|
bankId, _ := c.GetInt64("bank_id", 0)
|
||||||
minRate, _ := c.GetInt("min_rate", 0)
|
minRate, _ := c.GetInt("min_rate", 0)
|
||||||
@ -99,38 +99,38 @@ func (c *ExamQuestionController) GetList() {
|
|||||||
page, _ := c.GetInt("page", 1)
|
page, _ := c.GetInt("page", 1)
|
||||||
pageSize, _ := c.GetInt("pageSize", 10)
|
pageSize, _ := c.GetInt("pageSize", 10)
|
||||||
|
|
||||||
// use normalized keyword for DB searching to improve hit rate when editor HTML is posted
|
// use normalized keyword for DB searching to improve hit rate when editor HTML is posted
|
||||||
normKeyword := normalizeText(keyword)
|
normKeyword := normalizeText(keyword)
|
||||||
list, total, err := services.GetExamQuestions(services.QuestionListParams{
|
list, total, err := services.GetExamQuestions(services.QuestionListParams{
|
||||||
TenantId: tenantId,
|
TenantId: tenantId,
|
||||||
Keyword: normKeyword,
|
Keyword: normKeyword,
|
||||||
QuestionType: qtype,
|
QuestionType: qtype,
|
||||||
BankId: bankId,
|
BankId: bankId,
|
||||||
Page: page,
|
Page: page,
|
||||||
PageSize: pageSize,
|
PageSize: pageSize,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{"code": 1, "message": "获取试题列表失败: " + err.Error(), "data": nil}
|
c.Data["json"] = map[string]interface{}{"code": 1, "message": "获取试题列表失败: " + err.Error(), "data": nil}
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 当启用相似度筛选且按关键字无结果时,回退到不带关键字的最近记录中做相似度匹配
|
// 当启用相似度筛选且按关键字无结果时,回退到不带关键字的最近记录中做相似度匹配
|
||||||
if minRate > 0 && strings.TrimSpace(normKeyword) != "" && len(list) == 0 {
|
if minRate > 0 && strings.TrimSpace(normKeyword) != "" && len(list) == 0 {
|
||||||
fbPageSize := 50
|
fbPageSize := 50
|
||||||
fbList, _, fbErr := services.GetExamQuestions(services.QuestionListParams{
|
fbList, _, fbErr := services.GetExamQuestions(services.QuestionListParams{
|
||||||
TenantId: tenantId,
|
TenantId: tenantId,
|
||||||
Keyword: "",
|
Keyword: "",
|
||||||
BankId: bankId,
|
BankId: bankId,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
PageSize: fbPageSize,
|
PageSize: fbPageSize,
|
||||||
})
|
})
|
||||||
if fbErr == nil {
|
if fbErr == nil {
|
||||||
list = fbList
|
list = fbList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items := make([]map[string]interface{}, 0, len(list))
|
items := make([]map[string]interface{}, 0, len(list))
|
||||||
currentTitle := normalizeText(keyword)
|
currentTitle := normalizeText(keyword)
|
||||||
for _, q := range list {
|
for _, q := range list {
|
||||||
if q == nil {
|
if q == nil {
|
||||||
continue
|
continue
|
||||||
@ -421,7 +421,7 @@ func (c *ExamQuestionBankController) GetBankList() {
|
|||||||
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
|
||||||
keyword := c.GetString("keyword")
|
keyword := c.GetString("keyword")
|
||||||
page, _ := c.GetInt("page", 1)
|
page, _ := c.GetInt("page", 1)
|
||||||
pageSize, _ := c.GetInt("pageSize", 10)
|
pageSize, _ := c.GetInt("pageSize", 20)
|
||||||
list, total, err := services.GetExamQuestionBanks(services.BankListParams{
|
list, total, err := services.GetExamQuestionBanks(services.BankListParams{
|
||||||
TenantId: tenantId,
|
TenantId: tenantId,
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
@ -433,7 +433,22 @@ func (c *ExamQuestionBankController) GetBankList() {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Data["json"] = map[string]interface{}{"code": 0, "message": "ok", "data": map[string]interface{}{"list": list, "total": total}}
|
// enrich with total_count per bank
|
||||||
|
items := make([]map[string]interface{}, 0, len(list))
|
||||||
|
for _, b := range list {
|
||||||
|
if b == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cnt, _ := services.CountQuestionsInBank(tenantId, b.Id)
|
||||||
|
items = append(items, map[string]interface{}{
|
||||||
|
"id": b.Id,
|
||||||
|
"tenant_id": b.TenantId,
|
||||||
|
"bank_name": b.BankName,
|
||||||
|
"bank_desc": b.BankDesc,
|
||||||
|
"total_count": cnt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
c.Data["json"] = map[string]interface{}{"code": 0, "message": "ok", "data": map[string]interface{}{"list": items, "total": total}}
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,16 @@ type QuestionListParams struct {
|
|||||||
PageSize 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 {
|
type QuestionWithMeta struct {
|
||||||
Question *models.ExamQuestion
|
Question *models.ExamQuestion
|
||||||
Options []*models.ExamQuestionOption
|
Options []*models.ExamQuestionOption
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user