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

View File

@ -3,17 +3,12 @@ package controller
import (
"server/common"
"server/modules/system/dto"
"server/modules/system/service"
"github.com/gin-gonic/gin"
)
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// AuthController 认证控制器
type AuthController struct {
userService *service.SysUserService
@ -38,7 +33,7 @@ func (ctrl *AuthController) RegisterRoutes(r *gin.RouterGroup) {
// @Success 200 {object} common.Response
// @Router /sys/auth/login [post]
func (ctrl *AuthController) SysLogin(c *gin.Context) {
var req LoginRequest
var req dto.LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
common.Error(c, 400, "用户名和密码不能为空")
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 (
"server/common"
"server/modules/user/service"
"server/modules/user/vo"
yxDto "server/modules/yx/dto"
"server/modules/yx/entity"
yx_service "server/modules/yx/service"
@ -65,16 +64,11 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
keys = uniqueKeys
loginUserId := common.GetLoginUser(c).ID
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId)
userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserId)
if err != nil {
common.Error(c, 500, err.Error()) // 获取用户成绩信息失败
return
}
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
if userScoreVO.CalculationTableName == "" {
common.Error(c, 500, "未找到计算表名")
@ -150,16 +144,11 @@ func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
// @Router /user/volunteer/detail [get]
func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) {
loginUserId := common.GetLoginUser(c).ID
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserId)
userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserId)
if err != nil {
common.Error(c, 500, err.Error())
return
}
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
// 查找当前激活的志愿表
volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
@ -353,16 +342,11 @@ func (ctrl *UserVolunteerController) SwitchVolunteer(c *gin.Context) {
loginUserID := common.GetLoginUser(c).ID
// 1. 先判断是否已是该志愿单 (从 cache 或 db 中查找激活的)
scoreObj, err := ctrl.userScoreService.GetActiveScoreID(loginUserID)
userScoreVO, err := ctrl.userScoreService.GetActiveScoreByUserID(loginUserID)
if err != nil {
common.Error(c, 500, "获取用户成绩信息失败: "+err.Error())
return
}
userScoreVO, ok := scoreObj.(vo.UserScoreVO)
if !ok {
common.Error(c, 500, "成绩信息格式错误")
return
}
if userScoreVO.ID != "" {
activeVolunteer, _ := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)

View File

@ -26,13 +26,21 @@ type UserScoreService struct {
mapper *mapper.YxUserScoreMapper
}
// GetActiveScoreID 获取用户的激活成绩信息
func (s *UserScoreService) GetActiveScoreID(userID string) (interface{}, error) {
vo, err := s.GetActiveScoreByUserID(userID)
// GetActiveScoreID 获取用户的激活成绩ID
func (s *UserScoreService) GetActiveScoreID(userID string) (string, error) {
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 {
return nil, err
if errors.Is(err, gorm.ErrRecordNotFound) {
return "", nil // 未找到激活成绩返回空字符串
}
return vo, nil
return "", fmt.Errorf("查询激活成绩ID失败: %w", err)
}
return score.ID, nil
}
// GetActiveScoreByID 获取用户的激活成绩实体(实现 IScoreService 接口)

View File

@ -3,8 +3,8 @@ package mapper
import (
"server/config"
"server/modules/yx/dto"
"server/modules/yx/entity"
"server/modules/yx/vo"
"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
}
func (m *YxVolunteerMapper) ListByUser(userID string, page, size int) ([]dto.UserVolunteerVO, int64, error) {
var items []dto.UserVolunteerVO
func (m *YxVolunteerMapper) ListByUser(userID string, page, size int) ([]vo.UserVolunteerVO, int64, error) {
var items []vo.UserVolunteerVO
var total int64
db := config.DB.Table("yx_volunteer v").

View File

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

View File

@ -4,17 +4,17 @@ package service
import (
"fmt"
"server/common"
"server/modules/yx/dto"
"server/modules/yx/entity"
"server/modules/yx/mapper"
"server/modules/yx/vo"
"time"
)
// IScoreService 定义成绩服务的接口,用于解耦
type IScoreService interface {
// ScoreService 定义成绩服务的接口,用于解耦
type ScoreService interface {
GetByID(id string) (interface{}, 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
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()})
}
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)
}
@ -146,7 +146,7 @@ func (s *YxVolunteerService) DeleteVolunteer(id, userID string) error {
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 {
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 {
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 {
scoreService.UpdateFields(activeScoreID, map[string]interface{}{"state": "0"})
}

View File

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