From aae2fe1e145b0da5221bf55c44dc6ac5873f7c50 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E5=BC=BA?= <357099073@qq.com>
Date: Wed, 19 Nov 2025 17:14:31 +0800
Subject: [PATCH] =?UTF-8?q?=E9=A2=98=E5=BA=93=E5=A2=9E=E5=8A=A0=E9=A2=98?=
=?UTF-8?q?=E7=9B=AE=E6=95=B0=E9=87=8F=E5=B1=95=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../apps/exams/examinationQuestions/index.vue | 1 +
server/controllers/exam.go | 105 ++++++++++--------
server/services/exam.go | 10 ++
3 files changed, 71 insertions(+), 45 deletions(-)
diff --git a/pc/src/views/apps/exams/examinationQuestions/index.vue b/pc/src/views/apps/exams/examinationQuestions/index.vue
index f9cf59e..618091c 100644
--- a/pc/src/views/apps/exams/examinationQuestions/index.vue
+++ b/pc/src/views/apps/exams/examinationQuestions/index.vue
@@ -22,6 +22,7 @@
+
编辑
diff --git a/server/controllers/exam.go b/server/controllers/exam.go
index b3e59ab..223366d 100644
--- a/server/controllers/exam.go
+++ b/server/controllers/exam.go
@@ -2,9 +2,9 @@ package controllers
import (
"encoding/json"
+ "regexp"
"strconv"
"strings"
- "regexp"
"server/models"
"server/services"
@@ -18,27 +18,27 @@ type ExamQuestionController struct {
// normalizeText removes HTML tags, converts to space, and collapses whitespace
func normalizeText(s string) string {
- str := strings.TrimSpace(s)
- if str == "" {
- return ""
- }
- // remove HTML tags
- re := regexp.MustCompile("<[^>]*>")
- str = re.ReplaceAllString(str, "")
- // decode common entities
- str = strings.ReplaceAll(str, " ", " ")
- str = strings.ReplaceAll(str, " ", " ")
- // collapse whitespace
- reSpace := regexp.MustCompile(`\s+`)
- str = reSpace.ReplaceAllString(str, " ")
- return strings.TrimSpace(str)
+ str := strings.TrimSpace(s)
+ if str == "" {
+ return ""
+ }
+ // remove HTML tags
+ re := regexp.MustCompile("<[^>]*>")
+ str = re.ReplaceAllString(str, "")
+ // decode common entities
+ str = strings.ReplaceAll(str, " ", " ")
+ str = strings.ReplaceAll(str, " ", " ")
+ // collapse whitespace
+ reSpace := regexp.MustCompile(`\s+`)
+ str = reSpace.ReplaceAllString(str, " ")
+ return strings.TrimSpace(str)
}
// computeMatchRate returns a simple similarity percentage between two strings based on
// position-wise identical characters over the max length, rounded to integer 0-100.
func computeMatchRate(a, b string) int {
- s1 := normalizeText(a)
- s2 := normalizeText(b)
+ s1 := normalizeText(a)
+ s2 := normalizeText(b)
if s1 == "" && s2 == "" {
return 100
}
@@ -83,7 +83,7 @@ type ExamQuestionBankController struct {
// @router /exam-questions [get]
func (c *ExamQuestionController) GetList() {
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
- keyword := c.GetString("keyword")
+ keyword := c.GetString("keyword")
typeStr := c.GetString("type")
bankId, _ := c.GetInt64("bank_id", 0)
minRate, _ := c.GetInt("min_rate", 0)
@@ -99,38 +99,38 @@ func (c *ExamQuestionController) GetList() {
page, _ := c.GetInt("page", 1)
pageSize, _ := c.GetInt("pageSize", 10)
- // use normalized keyword for DB searching to improve hit rate when editor HTML is posted
- normKeyword := normalizeText(keyword)
- list, total, err := services.GetExamQuestions(services.QuestionListParams{
- TenantId: tenantId,
- Keyword: normKeyword,
- QuestionType: qtype,
- BankId: bankId,
- Page: page,
- PageSize: pageSize,
- })
+ // use normalized keyword for DB searching to improve hit rate when editor HTML is posted
+ normKeyword := normalizeText(keyword)
+ list, total, err := services.GetExamQuestions(services.QuestionListParams{
+ TenantId: tenantId,
+ Keyword: normKeyword,
+ 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
}
- // 当启用相似度筛选且按关键字无结果时,回退到不带关键字的最近记录中做相似度匹配
- if minRate > 0 && strings.TrimSpace(normKeyword) != "" && len(list) == 0 {
- fbPageSize := 50
- fbList, _, fbErr := services.GetExamQuestions(services.QuestionListParams{
- TenantId: tenantId,
- Keyword: "",
- BankId: bankId,
- Page: 1,
- PageSize: fbPageSize,
- })
- if fbErr == nil {
- list = fbList
- }
- }
+ // 当启用相似度筛选且按关键字无结果时,回退到不带关键字的最近记录中做相似度匹配
+ if minRate > 0 && strings.TrimSpace(normKeyword) != "" && len(list) == 0 {
+ fbPageSize := 50
+ fbList, _, fbErr := services.GetExamQuestions(services.QuestionListParams{
+ TenantId: tenantId,
+ Keyword: "",
+ BankId: bankId,
+ Page: 1,
+ PageSize: fbPageSize,
+ })
+ if fbErr == nil {
+ list = fbList
+ }
+ }
items := make([]map[string]interface{}, 0, len(list))
- currentTitle := normalizeText(keyword)
+ currentTitle := normalizeText(keyword)
for _, q := range list {
if q == nil {
continue
@@ -421,7 +421,7 @@ 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)
+ pageSize, _ := c.GetInt("pageSize", 20)
list, total, err := services.GetExamQuestionBanks(services.BankListParams{
TenantId: tenantId,
Keyword: keyword,
@@ -433,7 +433,22 @@ func (c *ExamQuestionBankController) GetBankList() {
c.ServeJSON()
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()
}
diff --git a/server/services/exam.go b/server/services/exam.go
index d60f764..f82f4c2 100644
--- a/server/services/exam.go
+++ b/server/services/exam.go
@@ -18,6 +18,16 @@ type QuestionListParams struct {
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