优化题目代码

This commit is contained in:
2025-11-19 16:07:43 +08:00
parent 5fddba8a30
commit 7664821d88
6 changed files with 263 additions and 104 deletions
+104 -12
View File
@@ -3,6 +3,8 @@ package controllers
import (
"encoding/json"
"strconv"
"strings"
"regexp"
"server/models"
"server/services"
@@ -14,6 +16,65 @@ type ExamQuestionController struct {
beego.Controller
}
// 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, "&nbsp;", " ")
str = strings.ReplaceAll(str, "&#160;", " ")
// 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)
if s1 == "" && s2 == "" {
return 100
}
maxLen := len([]rune(s1))
if l := len([]rune(s2)); l > maxLen {
maxLen = l
}
if maxLen == 0 {
return 0
}
r1 := []rune(s1)
r2 := []rune(s2)
same := 0
for i := 0; i < maxLen; i++ {
var c1, c2 rune
if i < len(r1) {
c1 = r1[i]
}
if i < len(r2) {
c2 = r2[i]
}
if c1 != 0 && c2 != 0 && c1 == c2 {
same++
}
}
// round to nearest int
rate := int(float64(same)/float64(maxLen)*100.0 + 0.5)
if rate < 0 {
return 0
}
if rate > 100 {
return 100
}
return rate
}
type ExamQuestionBankController struct {
beego.Controller
}
@@ -22,9 +83,10 @@ 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)
var qtype *int8
if typeStr != "" {
@@ -37,32 +99,62 @@ func (c *ExamQuestionController) GetList() {
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,
})
// 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
}
}
items := make([]map[string]interface{}, 0, len(list))
currentTitle := normalizeText(keyword)
for _, q := range list {
if q == nil {
continue
}
items = append(items, map[string]interface{}{
// 可选相似度计算与过滤
var rate *int
if currentTitle != "" {
v := computeMatchRate(currentTitle, q.QuestionTitle)
rate = &v
if minRate > 0 && v < minRate {
continue
}
}
item := map[string]interface{}{
"id": q.Id,
"tenant_id": q.TenantId,
"question_type": q.QuestionType,
"question_title": q.QuestionTitle,
"score": q.Score,
})
}
if rate != nil {
item["_match_rate"] = *rate
}
items = append(items, item)
}
c.Data["json"] = map[string]interface{}{
@@ -160,7 +252,7 @@ func (c *ExamQuestionController) BatchCreate() {
tenantId, _ := c.Ctx.Input.GetData("tenantId").(int)
var payload struct {
BankId int64 `json:"bank_id"`
Items []struct {
Items []struct {
QuestionTitle string `json:"question_title"`
QuestionType int8 `json:"question_type"`
Score float64 `json:"score"`
+1 -1
View File
@@ -298,7 +298,7 @@ func init() {
beego.Router("/api/knowledge/count", &controllers.KnowledgeController{}, "get:GetCount")
beego.Router("/api/knowledge/detail", &controllers.KnowledgeController{}, "get:Detail")
beego.Router("/api/knowledge/create", &controllers.KnowledgeController{}, "post:Create")
// ...
beego.Router("/api/knowledge/update", &controllers.KnowledgeController{}, "post:Update")
beego.Router("/api/knowledge/delete", &controllers.KnowledgeController{}, "post:Delete")
beego.Router("/api/knowledge/categories", &controllers.KnowledgeController{}, "get:GetCategories")
beego.Router("/api/knowledge/tags", &controllers.KnowledgeController{}, "get:GetTags")