This commit is contained in:
zhouwentao 2026-01-31 13:30:03 +08:00
parent 9167b6a661
commit aac82d8a52
9 changed files with 54 additions and 76 deletions

View File

@ -1,16 +1,15 @@
package service package common
import ( import (
"math" "math"
"regexp" "regexp"
"server/common"
"server/modules/user/vo" "server/modules/user/vo"
"server/modules/yx/dto" "server/modules/yx/dto"
"strconv" "strconv"
"strings" "strings"
) )
// ScoreUtil 分数计算工具函数集合 // ScoreCalculator 分数计算工具函数集合
// 移植自 Java 版本的 ScoreUtil.java // 移植自 Java 版本的 ScoreUtil.java
var ( var (
@ -66,9 +65,9 @@ func ComputeHistoryMajorEnrollScoreLineDifferenceWithRulesEnrollProbability(majo
// boolean isSportsMajor = "体育类".equals(enrollData.getMajorType()); // boolean isSportsMajor = "体育类".equals(enrollData.getMajorType());
if "体育类" == majorType { if "体育类" == majorType {
if "2024" == enrollData.Year && "专过文排" != enrollData.EnrollmentCode && "文过专排" != enrollData.EnrollmentCode { if "2024" == enrollData.Year && "专过文排" != enrollData.EnrollmentCode && "文过专排" != enrollData.EnrollmentCode {
currentDiff = currentDiff * common.Number7p5 currentDiff = currentDiff * Number7p5
} else if "2024" == enrollData.Year && "文过专排" == enrollData.EnrollmentCode { // Placeholder } else if "2024" == enrollData.Year && "文过专排" == enrollData.EnrollmentCode { // Placeholder
currentDiff = currentDiff * common.Number5 currentDiff = currentDiff * Number5
} else if "2023" == enrollData.Year { } else if "2023" == enrollData.Year {
continue continue
} else if rulesEnrollProbability == enrollData.RulesEnrollProbability { // Need field } else if rulesEnrollProbability == enrollData.RulesEnrollProbability { // Need field
@ -119,11 +118,11 @@ func ConvertIntoScore(rulesEnrollProbability string, culturalScore, professional
// CrossingControlLine 判断是否过省控线 // CrossingControlLine 判断是否过省控线
func CrossingControlLine(rulesEnrollProbability string, culturalScore, professionalScore, culturalControlLine, specialControlLine float64) bool { func CrossingControlLine(rulesEnrollProbability string, culturalScore, professionalScore, culturalControlLine, specialControlLine float64) bool {
if rulesEnrollProbability == common.CulturalControlLineGuo { if rulesEnrollProbability == CulturalControlLineGuo {
return culturalScore >= culturalControlLine return culturalScore >= culturalControlLine
} else if rulesEnrollProbability == common.SpecialControlLineGuo { } else if rulesEnrollProbability == SpecialControlLineGuo {
return professionalScore >= specialControlLine return professionalScore >= specialControlLine
} else if rulesEnrollProbability == common.CulturalControlLineGuoMain { } else if rulesEnrollProbability == CulturalControlLineGuoMain {
return culturalScore >= specialControlLine return culturalScore >= specialControlLine
} }
return culturalScore >= culturalControlLine && professionalScore >= specialControlLine return culturalScore >= culturalControlLine && professionalScore >= specialControlLine

View File

@ -3,17 +3,12 @@ package controller
import ( import (
"server/common" "server/common"
"server/modules/system/dto"
"server/modules/system/service" "server/modules/system/service"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// AuthController 认证控制器 // AuthController 认证控制器
type AuthController struct { type AuthController struct {
userService *service.SysUserService userService *service.SysUserService
@ -38,7 +33,7 @@ func (ctrl *AuthController) RegisterRoutes(r *gin.RouterGroup) {
// @Success 200 {object} common.Response // @Success 200 {object} common.Response
// @Router /sys/auth/login [post] // @Router /sys/auth/login [post]
func (ctrl *AuthController) SysLogin(c *gin.Context) { func (ctrl *AuthController) SysLogin(c *gin.Context) {
var req LoginRequest var req dto.LoginRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
common.Error(c, 400, "用户名和密码不能为空") common.Error(c, 400, "用户名和密码不能为空")
return return

View File

@ -0,0 +1,7 @@
package dto
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}

View File

@ -3,7 +3,6 @@ package controller
import ( import (
"server/common" "server/common"
"server/modules/user/service" "server/modules/user/service"
"server/modules/user/vo"
yxDto "server/modules/yx/dto" yxDto "server/modules/yx/dto"
"server/modules/yx/entity" "server/modules/yx/entity"
yx_service "server/modules/yx/service" yx_service "server/modules/yx/service"
@ -65,16 +64,11 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
keys = uniqueKeys keys = uniqueKeys
loginUserId := common.GetLoginUser(c).ID loginUserId := common.GetLoginUser(c).ID
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId) userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserId)
if err != nil { if err != nil {
common.Error(c, 500, err.Error()) // 获取用户成绩信息失败 common.Error(c, 500, err.Error()) // 获取用户成绩信息失败
return return
} }
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
if userScoreVO.CalculationTableName == "" { if userScoreVO.CalculationTableName == "" {
common.Error(c, 500, "未找到计算表名") common.Error(c, 500, "未找到计算表名")
@ -150,16 +144,11 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
// @Router /user/volunteer/detail [get] // @Router /user/volunteer/detail [get]
func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) { func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) {
loginUserId := common.GetLoginUser(c).ID loginUserId := common.GetLoginUser(c).ID
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId) userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserId)
if err != nil { if err != nil {
common.Error(c, 500, err.Error()) common.Error(c, 500, err.Error())
return return
} }
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
// 查找当前激活的志愿表 // 查找当前激活的志愿表
volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID) volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
@ -353,16 +342,11 @@ func (ctrl *UserVolunteerController) SwitchVolunteer(c *gin.Context) {
loginUserID := common.GetLoginUser(c).ID loginUserID := common.GetLoginUser(c).ID
// 1. 先判断是否已是该志愿单 (从 cache 或 db 中查找激活的) // 1. 先判断是否已是该志愿单 (从 cache 或 db 中查找激活的)
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserID) userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserID)
if err != nil { if err != nil {
common.Error(c, 500, "获取用户成绩信息失败: "+err.Error()) common.Error(c, 500, "获取用户成绩信息失败: "+err.Error())
return return
} }
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
if userScoreVO.ID != "" { if userScoreVO.ID != "" {
activeVolunteer, _ := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID) activeVolunteer, _ := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)

View File

@ -26,13 +26,21 @@ type UserScoreService struct {
mapper *mapper.YxUserScoreMapper mapper *mapper.YxUserScoreMapper
} }
// GetActiveScoreID 获取用户的激活成绩信息 // GetActiveScoreID 获取用户的激活成绩ID
func (s *UserScoreService) GetActiveScoreID(userID string) (interface{}, error) { func (s *UserScoreService) GetActiveScoreID(userID string) (string, error) {
vo, err := s.GetActiveScoreByUserID(userID) var score entity.YxUserScore
// 明确指定字段,提高可读性
err := config.DB.Model(&entity.YxUserScore{}).
Where("create_by = ? AND state = ?", userID, "1").
Select("id").
First(&score).Error
if err != nil { if err != nil {
return nil, err if errors.Is(err, gorm.ErrRecordNotFound) {
return "", nil // 未找到激活成绩返回空字符串
}
return "", fmt.Errorf("查询激活成绩ID失败: %w", err)
} }
return vo, nil return score.ID, nil
} }
// GetActiveScoreByID 获取用户的激活成绩实体(实现 IScoreService 接口) // GetActiveScoreByID 获取用户的激活成绩实体(实现 IScoreService 接口)

View File

@ -3,8 +3,8 @@ package mapper
import ( import (
"server/config" "server/config"
"server/modules/yx/dto"
"server/modules/yx/entity" "server/modules/yx/entity"
"server/modules/yx/vo"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
@ -81,8 +81,8 @@ func (m *YxVolunteerMapper) BatchDelete(ids []string) error {
return config.DB.Delete(&entity.YxVolunteer{}, "id IN ?", ids).Error return config.DB.Delete(&entity.YxVolunteer{}, "id IN ?", ids).Error
} }
func (m *YxVolunteerMapper) ListByUser(userID string, page, size int) ([]dto.UserVolunteerVO, int64, error) { func (m *YxVolunteerMapper) ListByUser(userID string, page, size int) ([]vo.UserVolunteerVO, int64, error) {
var items []dto.UserVolunteerVO var items []vo.UserVolunteerVO
var total int64 var total int64
db := config.DB.Table("yx_volunteer v"). db := config.DB.Table("yx_volunteer v").

View File

@ -4,6 +4,7 @@ package service
import ( import (
"fmt" "fmt"
"server/common" "server/common"
calc "server/common"
"server/modules/user/vo" "server/modules/user/vo"
"server/modules/yx/dto" "server/modules/yx/dto"
yxDto "server/modules/yx/dto" yxDto "server/modules/yx/dto"
@ -45,11 +46,6 @@ func (s *YxCalculationMajorService) RecommendMajorList(schoolMajorQuery yxDto.Sc
schoolMajorQuery.Batch = "高职高专" schoolMajorQuery.Batch = "高职高专"
} }
// if len(schoolMajorQuery.MajorTypeChildren) > 0 && "高职高专" != schoolMajorQuery.Batch {
// if "表演类" == schoolMajorQuery.MajorType {
// }
// }
calculationMajors, total, probCount, err := s.mapper.FindRecommendList(schoolMajorQuery) calculationMajors, total, probCount, err := s.mapper.FindRecommendList(schoolMajorQuery)
if err != nil { if err != nil {
return nil, 0, dto.ProbabilityCountDTO{}, err return nil, 0, dto.ProbabilityCountDTO{}, err
@ -444,7 +440,7 @@ func (s *YxCalculationMajorService) betaRecommendMajorListSetEnrollProbability(r
} }
// 判断其他录取要求 // 判断其他录取要求
if !OtherScoreJudge(professionalScore, userScoreVO, *item) { if !calc.OtherScoreJudge(professionalScore, userScoreVO, *item) {
item.EnrollProbability = common.Number0 item.EnrollProbability = common.Number0
continue continue
} }
@ -466,18 +462,18 @@ func (s *YxCalculationMajorService) betaRecommendMajorListSetEnrollProbability(r
} }
// 判断是否过省控线 // 判断是否过省控线
if !CrossingControlLine(rulesEnrollProbability, culturalScore, professionalScore, culturalControlLine, specialControlLine) { if !calc.CrossingControlLine(rulesEnrollProbability, culturalScore, professionalScore, culturalControlLine, specialControlLine) {
item.EnrollProbability = common.Number0 item.EnrollProbability = common.Number0
continue continue
} }
// 计算学生折合分 // 计算学生折合分
studentScore := ConvertIntoScore(rulesEnrollProbability, culturalScore, professionalScore, probabilityOperator) studentScore := calc.ConvertIntoScore(rulesEnrollProbability, culturalScore, professionalScore, probabilityOperator)
item.PrivateStudentScore = studentScore item.PrivateStudentScore = studentScore
item.StudentScore = studentScore // 展示用 item.StudentScore = studentScore // 展示用
// 权限检查 // 权限检查
if !HasComputeEnrollProbabilityPermissions(nowBatch, item.Batch) { if !calc.HasComputeEnrollProbabilityPermissions(nowBatch, item.Batch) {
item.EnrollProbability = common.Number0 item.EnrollProbability = common.Number0
continue continue
} }
@ -495,14 +491,14 @@ func (s *YxCalculationMajorService) betaRecommendMajorListSetEnrollProbability(r
continue continue
} else { } else {
// 当前年省控线 折合后 // 当前年省控线 折合后
nowYearProvincialControlLine := ConvertIntoScore(rulesEnrollProbability, culturalControlLine, specialControlLine, probabilityOperator) nowYearProvincialControlLine := calc.ConvertIntoScore(rulesEnrollProbability, culturalControlLine, specialControlLine, probabilityOperator)
if nowYearProvincialControlLine <= 0 { if nowYearProvincialControlLine <= 0 {
item.EnrollProbability = common.Number0 item.EnrollProbability = common.Number0
continue continue
} }
// 历年分差 // 历年分差
diffMap := ComputeHistoryMajorEnrollScoreLineDifferenceWithRulesEnrollProbability(item.MajorType, rulesEnrollProbability, probabilityOperator, item.HistoryMajorEnrollMap) diffMap := calc.ComputeHistoryMajorEnrollScoreLineDifferenceWithRulesEnrollProbability(item.MajorType, rulesEnrollProbability, probabilityOperator, item.HistoryMajorEnrollMap)
historyThreeYearDiff := diffMap["scoreDifference"].(float64) historyThreeYearDiff := diffMap["scoreDifference"].(float64)
if historyThreeYearDiff == 0 { if historyThreeYearDiff == 0 {
@ -514,8 +510,8 @@ func (s *YxCalculationMajorService) betaRecommendMajorListSetEnrollProbability(r
nowYearDiff := studentScore - nowYearProvincialControlLine nowYearDiff := studentScore - nowYearProvincialControlLine
// 计算录取率 // 计算录取率
enrollProbability := CommonCheckEnrollProbability(nowYearDiff, historyThreeYearDiff) enrollProbability := calc.CommonCheckEnrollProbability(nowYearDiff, historyThreeYearDiff)
item.EnrollProbability = CommonCheckEnrollProbabilityBeilv(enrollProbability) item.EnrollProbability = calc.CommonCheckEnrollProbabilityBeilv(enrollProbability)
} }
} }

View File

@ -4,17 +4,17 @@ package service
import ( import (
"fmt" "fmt"
"server/common" "server/common"
"server/modules/yx/dto"
"server/modules/yx/entity" "server/modules/yx/entity"
"server/modules/yx/mapper" "server/modules/yx/mapper"
"server/modules/yx/vo"
"time" "time"
) )
// IScoreService 定义成绩服务的接口,用于解耦 // ScoreService 定义成绩服务的接口,用于解耦
type IScoreService interface { type ScoreService interface {
GetByID(id string) (interface{}, error) GetByID(id string) (interface{}, error)
GetActiveScoreByID(userID string) (entity.YxUserScore, error) GetActiveScoreByID(userID string) (entity.YxUserScore, error)
GetActiveScoreID(userID string) (interface{}, error) GetActiveScoreID(userID string) (string, error)
UpdateFields(id string, fields map[string]interface{}) error UpdateFields(id string, fields map[string]interface{}) error
Delete(id string) error Delete(id string) error
} }
@ -113,7 +113,7 @@ func (s *YxVolunteerService) UpdateName(id, name, userID string) error {
return s.mapper.UpdateFields(id, map[string]interface{}{"volunteer_name": name, "update_by": userID, "update_time": time.Now()}) return s.mapper.UpdateFields(id, map[string]interface{}{"volunteer_name": name, "update_by": userID, "update_time": time.Now()})
} }
func (s *YxVolunteerService) ListByUser(userID string, page, size int) ([]dto.UserVolunteerVO, int64, error) { func (s *YxVolunteerService) ListByUser(userID string, page, size int) ([]vo.UserVolunteerVO, int64, error) {
return s.mapper.ListByUser(userID, page, size) return s.mapper.ListByUser(userID, page, size)
} }
@ -146,7 +146,7 @@ func (s *YxVolunteerService) DeleteVolunteer(id, userID string) error {
return nil // 暂时回退复杂逻辑 return nil // 暂时回退复杂逻辑
} }
func (s *YxVolunteerService) SwitchVolunteer(id, userID string, scoreService IScoreService) error { func (s *YxVolunteerService) SwitchVolunteer(id, userID string, scoreService ScoreService) error {
if err := s.mapper.CloseOtherVolunteer(userID); err != nil { if err := s.mapper.CloseOtherVolunteer(userID); err != nil {
return err return err
} }
@ -160,21 +160,10 @@ func (s *YxVolunteerService) SwitchVolunteer(id, userID string, scoreService ISc
} }
// 获取之前的激活成绩并关闭 // 获取之前的激活成绩并关闭
scoreObj, err := scoreService.GetActiveScoreID(userID) activeScoreID, err := scoreService.GetActiveScoreID(userID)
if err != nil { if err != nil {
return fmt.Errorf("获取激活成绩失败: %w", err) return fmt.Errorf("获取激活成绩失败: %w", err)
} }
var activeScoreID string
if scoreObj != nil {
// 尝试从 VO 对象中提取 ID
if vo, ok := scoreObj.(map[string]interface{}); ok {
if id, ok := vo["id"].(string); ok {
activeScoreID = id
}
} else if vo, ok := scoreObj.(struct{ ID string }); ok {
activeScoreID = vo.ID
}
}
if activeScoreID != "" && activeScoreID != volunteer.ScoreId { if activeScoreID != "" && activeScoreID != volunteer.ScoreId {
scoreService.UpdateFields(activeScoreID, map[string]interface{}{"state": "0"}) scoreService.UpdateFields(activeScoreID, map[string]interface{}{"state": "0"})
} }

View File

@ -1,4 +1,4 @@
package dto package vo
import ( import (
"server/modules/yx/entity" "server/modules/yx/entity"