// Package mapper 数据访问层 package mapper import ( "fmt" "server/config" "server/modules/yx/dto" "server/modules/yx/entity" "strings" "sync" "gorm.io/gorm/clause" ) type YxCalculationMajorMapper struct{} func NewYxCalculationMajorMapper() *YxCalculationMajorMapper { return &YxCalculationMajorMapper{} } func (m *YxCalculationMajorMapper) FindAll(page, size int) ([]entity.YxCalculationMajor, int64, error) { var items []entity.YxCalculationMajor var total int64 config.DB.Model(&entity.YxCalculationMajor{}).Count(&total) err := config.DB.Offset((page - 1) * size).Limit(size).Find(&items).Error return items, total, err } func (m *YxCalculationMajorMapper) FindRecommendList(query dto.SchoolMajorQuery) ([]dto.UserMajorDTO, int64, error) { var items []dto.UserMajorDTO var total int64 countSQL := ` SELECT COUNT(cm.id) FROM ? cm LEFT JOIN yx_school_child sc ON sc.school_code = cm.school_code LEFT JOIN yx_school_research_teaching srt ON srt.school_id = sc.school_id LEFT JOIN yx_school s ON s.id = sc.school_id WHERE 1=1 AND cm.state > 0 ` sql := ` SELECT cm.id, s.school_name, s.school_icon, cm.state, cm.school_code, cm.major_code, cm.major_name, cm.enrollment_code, cm.tuition, cm.detail as majorDetail, cm.category, cm.batch, cm.private_student_converted_score as privateStudentScore, cm.student_old_converted_score as studentScore, cm.student_converted_score, cm.enroll_probability, cm.rules_enroll_probability_sx, cm.rules_enroll_probability, cm.probability_operator, cm.major_type, cm.major_type_child, cm.plan_num, cm.main_subjects, cm.limitation, cm.other_score_limitation, s.province as province, s.school_nature as schoolNature, s.institution_type as institutionType FROM ? cm LEFT JOIN yx_school_child sc ON sc.school_code = cm.school_code LEFT JOIN yx_school_research_teaching srt ON srt.school_id = sc.school_id LEFT JOIN yx_school s ON s.id = sc.school_id WHERE 1=1 AND cm.state > 0 ` params := []interface{}{} params = append(params, query.UserScoreVO.CalculationTableName) if query.UserScoreVO.ID != "" { countSQL += " AND cm.score_id = ?" sql += " AND cm.score_id = ?" params = append(params, query.UserScoreVO.ID) } if query.MajorType != "" { countSQL += " AND cm.major_type = ?" sql += " AND cm.major_type = ?" params = append(params, query.MajorType) } if query.Category != "" { countSQL += " AND cm.category = ?" sql += " AND cm.category = ?" params = append(params, query.Category) } if len(query.MajorTypeChildren) > 0 { placeholders := strings.Repeat("?,", len(query.MajorTypeChildren)-1) + "?" countSQL += " AND cm.major_type_child IN (" + placeholders + ")" sql += " AND cm.major_type_child IN (" + placeholders + ")" for _, v := range query.MajorTypeChildren { params = append(params, v) } } if query.MainSubjects != "" { countSQL += " AND cm.main_subjects = ?" sql += " AND cm.main_subjects = ?" params = append(params, query.MainSubjects) } // 录取概率 switch query.Probability { case "难录取": countSQL += " AND cm.enroll_probability < 60" sql += " AND cm.enroll_probability < 60" case "可冲击": countSQL += " AND (cm.enroll_probability >= 60 and cm.enroll_probability < 73)" sql += " AND (cm.enroll_probability >= 60 and cm.enroll_probability < 73)" case "较稳妥": countSQL += " AND (cm.enroll_probability >= 73 and cm.enroll_probability < 93)" sql += " AND (cm.enroll_probability >= 73 and cm.enroll_probability < 93)" case "可保底": countSQL += " AND (cm.enroll_probability >= 93)" sql += " AND (cm.enroll_probability >= 93)" } countSQL = strings.Replace(countSQL, "yx_calculation_major", "yx_calculation_major_2025_2", -1) sql = strings.Replace(sql, "yx_calculation_major", "yx_calculation_major_2025_2", -1) var wg sync.WaitGroup var countErr, queryErr error wg.Add(2) // 协程1:COUNT 查询 go func() { defer wg.Done() countErr = config.DB.Raw(countSQL, params...).Count(&total).Error }() // 协程2:主查询 go func() { defer wg.Done() sql += fmt.Sprintf(" LIMIT %d OFFSET %d", query.Size, (query.Page-1)*query.Size) queryErr = config.DB.Raw(sql, params...).Scan(&items).Error }() wg.Wait() if countErr != nil || queryErr != nil { return nil, 0, fmt.Errorf("countErr: %v, queryErr: %v", countErr, queryErr) } return items, total, queryErr } func (m *YxCalculationMajorMapper) FindByID(id string) (*entity.YxCalculationMajor, error) { var item entity.YxCalculationMajor err := config.DB.First(&item, "id = ?", id).Error return &item, err } func (m *YxCalculationMajorMapper) Create(item *entity.YxCalculationMajor) error { return config.DB.Create(item).Error } func (m *YxCalculationMajorMapper) Update(item *entity.YxCalculationMajor) error { return config.DB.Save(item).Error } func (m *YxCalculationMajorMapper) UpdateFields(id string, fields map[string]interface{}) error { return config.DB.Model(&entity.YxCalculationMajor{}).Where("id = ?", id).Updates(fields).Error } func (m *YxCalculationMajorMapper) Delete(id string) error { return config.DB.Delete(&entity.YxCalculationMajor{}, "id = ?", id).Error } func (m *YxCalculationMajorMapper) FindByScoreID(scoreID string) ([]entity.YxCalculationMajor, error) { var items []entity.YxCalculationMajor err := config.DB.Where("score_id = ?", scoreID).Find(&items).Error return items, err } func (m *YxCalculationMajorMapper) BatchCreate(items []entity.YxCalculationMajor, batchSize int) error { return config.DB.CreateInBatches(items, batchSize).Error } func (m *YxCalculationMajorMapper) BatchUpdate(items []entity.YxCalculationMajor) error { return config.DB.Save(items).Error } func (m *YxCalculationMajorMapper) BatchUpsert(items []entity.YxCalculationMajor, updateColumns []string) error { return config.DB.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns(updateColumns), }).CreateInBatches(items, 100).Error } func (m *YxCalculationMajorMapper) BatchDelete(ids []string) error { return config.DB.Delete(&entity.YxCalculationMajor{}, "id IN ?", ids).Error } func (m *YxCalculationMajorMapper) DeleteByScoreID(scoreID string) error { return config.DB.Delete(&entity.YxCalculationMajor{}, "score_id = ?", scoreID).Error }