257 lines
8.2 KiB
Go
257 lines
8.2 KiB
Go
package controller
|
|
|
|
import (
|
|
"server/common"
|
|
"server/modules/user/service"
|
|
yxDto "server/modules/yx/dto"
|
|
"server/modules/yx/entity"
|
|
yx_service "server/modules/yx/service"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type UserVolunteerController struct {
|
|
userScoreService *service.UserScoreService
|
|
yxVolunteerService *yx_service.YxVolunteerService
|
|
yxVolunteerRecordService *yx_service.YxVolunteerRecordService
|
|
yxCalculationMajorService *yx_service.YxCalculationMajorService
|
|
}
|
|
|
|
func NewUserVolunteerController() *UserVolunteerController {
|
|
return &UserVolunteerController{
|
|
userScoreService: service.NewUserScoreService(),
|
|
yxVolunteerService: yx_service.NewYxVolunteerService(),
|
|
yxVolunteerRecordService: yx_service.NewYxVolunteerRecordService(),
|
|
yxCalculationMajorService: yx_service.NewYxCalculationMajorService(),
|
|
}
|
|
}
|
|
|
|
func (ctrl *UserVolunteerController) RegisterRoutes(rg *gin.RouterGroup) {
|
|
group := rg.Group("/user/volunteer")
|
|
{
|
|
group.POST("/save", ctrl.SaveVolunteer)
|
|
group.GET("/detail", ctrl.GetVolunteerDetail)
|
|
}
|
|
}
|
|
|
|
// SaveVolunteer 保存志愿明细
|
|
// @Summary 保存志愿明细
|
|
// @Tags 用户志愿
|
|
// @Param keys body []string true "Keys: schoolCode_majorCode_enrollmentCode"
|
|
// @Success 200 {object} common.Response
|
|
// @Router /user/volunteer/save [post]
|
|
func (ctrl *UserVolunteerController) SaveVolunteer(c *gin.Context) {
|
|
var keys []string
|
|
if err := c.ShouldBindJSON(&keys); err != nil {
|
|
common.Error(c, 500, err.Error())
|
|
return
|
|
}
|
|
|
|
// data deduplication
|
|
seen := make(map[string]bool)
|
|
var uniqueKeys []string
|
|
for _, key := range keys {
|
|
if !seen[key] {
|
|
seen[key] = true
|
|
uniqueKeys = append(uniqueKeys, key)
|
|
}
|
|
}
|
|
keys = uniqueKeys
|
|
|
|
loginUserId := common.GetLoginUser(c).ID
|
|
userScoreVO, err := ctrl.userScoreService.GetActiveByID(loginUserId)
|
|
if err != nil {
|
|
common.Error(c, 500, err.Error())
|
|
return
|
|
}
|
|
|
|
if userScoreVO.CalculationTableName == "" {
|
|
common.Error(c, 500, "未找到计算表名")
|
|
return
|
|
}
|
|
|
|
// 查找当前激活的志愿表
|
|
volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
|
|
if err != nil {
|
|
common.Error(c, 500, "查找志愿表失败: "+err.Error())
|
|
return
|
|
}
|
|
if volunteer == nil || volunteer.ID == "" {
|
|
common.Error(c, 500, "请先创建志愿表")
|
|
return
|
|
}
|
|
|
|
// 查找专业信息
|
|
majors, err := ctrl.yxCalculationMajorService.FindListByCompositeKeys(userScoreVO.CalculationTableName, keys, userScoreVO.ID)
|
|
if err != nil {
|
|
common.Error(c, 500, "查找专业信息失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// 构建 Map 用于保持顺序
|
|
majorMap := make(map[string]entity.YxCalculationMajor)
|
|
for _, major := range majors {
|
|
k := major.SchoolCode + "_" + major.MajorCode + "_" + major.EnrollmentCode
|
|
majorMap[k] = major
|
|
}
|
|
|
|
var records []entity.YxVolunteerRecord
|
|
for i, key := range keys {
|
|
if major, ok := majorMap[key]; ok {
|
|
record := entity.YxVolunteerRecord{
|
|
VolunteerID: volunteer.ID,
|
|
SchoolCode: major.SchoolCode,
|
|
MajorCode: major.MajorCode,
|
|
EnrollmentCode: major.EnrollmentCode,
|
|
Indexs: i + 1,
|
|
CreateBy: loginUserId,
|
|
CreateTime: time.Now(),
|
|
Batch: major.Batch,
|
|
EnrollProbability: major.EnrollProbability,
|
|
StudentConvertedScore: major.StudentConvertedScore,
|
|
CalculationMajorID: major.ID,
|
|
}
|
|
records = append(records, record)
|
|
}
|
|
}
|
|
|
|
// 先删除旧数据
|
|
if err := ctrl.yxVolunteerRecordService.DeleteByVolunteerID(volunteer.ID); err != nil {
|
|
common.Error(c, 500, "删除旧数据失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// 批量插入新数据
|
|
if len(records) > 0 {
|
|
if err := ctrl.yxVolunteerRecordService.BatchCreate(records); err != nil {
|
|
common.Error(c, 500, "保存失败: "+err.Error())
|
|
return
|
|
}
|
|
}
|
|
|
|
common.Success(c, "保存成功")
|
|
}
|
|
|
|
// GetVolunteerDetail 获取当前志愿单详情
|
|
// @Summary 获取当前志愿单详情
|
|
// @Tags 用户志愿
|
|
// @Success 200 {object} common.Response
|
|
// @Router /user/volunteer/detail [get]
|
|
func (ctrl *UserVolunteerController) GetVolunteerDetail(c *gin.Context) {
|
|
loginUserId := common.GetLoginUser(c).ID
|
|
userScoreVO, err := ctrl.userScoreService.GetActiveByID(loginUserId)
|
|
if err != nil {
|
|
common.Error(c, 500, err.Error())
|
|
return
|
|
}
|
|
|
|
// 查找当前激活的志愿表
|
|
volunteer, err := ctrl.yxVolunteerService.FindActiveByScoreId(userScoreVO.ID)
|
|
if err != nil {
|
|
common.Error(c, 500, "查找志愿表失败: "+err.Error())
|
|
return
|
|
}
|
|
if volunteer == nil || volunteer.ID == "" {
|
|
common.Success(c, nil) // No volunteer record found
|
|
return
|
|
}
|
|
|
|
records, err := ctrl.yxVolunteerRecordService.FindByVolunteerID(volunteer.ID)
|
|
if err != nil {
|
|
common.Error(c, 500, "查找志愿明细失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Fetch enriched details
|
|
var enrichedMajors map[string]yxDto.SchoolMajorDTO
|
|
if len(records) > 0 && userScoreVO.CalculationTableName != "" {
|
|
keys := make([]string, 0, len(records))
|
|
for _, r := range records {
|
|
keys = append(keys, r.SchoolCode+"_"+r.MajorCode+"_"+r.EnrollmentCode)
|
|
}
|
|
majors, err := ctrl.yxCalculationMajorService.FindDtoListByCompositeKeys(userScoreVO.CalculationTableName, keys, userScoreVO.ID)
|
|
if err == nil {
|
|
enrichedMajors = make(map[string]yxDto.SchoolMajorDTO)
|
|
for _, m := range majors {
|
|
// Key by composite key as ID matches record's logic (or use ID if record stores correct ID)
|
|
// Record has CalculationMajorID, but DTO also has ID. Let's use ID if reliable, else composite.
|
|
// FindDtoListByCompositeKeys returns items where ID should match.
|
|
enrichedMajors[m.SchoolCode+"_"+m.MajorCode+"_"+m.EnrollmentCode] = m
|
|
}
|
|
}
|
|
}
|
|
|
|
// Grouping
|
|
// Response structure: volunteer info + grouped items
|
|
type VolunteerDetailItem struct {
|
|
entity.YxVolunteerRecord
|
|
SchoolName string `json:"schoolName"`
|
|
MajorName string `json:"majorName"`
|
|
PlanNum int `json:"planNum"`
|
|
Tuition string `json:"tuition"`
|
|
SchoolIcon string `json:"schoolIcon"`
|
|
Province string `json:"province"`
|
|
SchoolNature string `json:"schoolNature"`
|
|
InstitutionType string `json:"institutionType"`
|
|
MajorDetail string `json:"majorDetail"` // from detail
|
|
}
|
|
|
|
groupedItems := map[string][]VolunteerDetailItem{
|
|
"提前批": {},
|
|
"本科批": {},
|
|
"专科批": {},
|
|
}
|
|
|
|
for _, r := range records {
|
|
item := VolunteerDetailItem{
|
|
YxVolunteerRecord: r,
|
|
}
|
|
key := r.SchoolCode + "_" + r.MajorCode + "_" + r.EnrollmentCode
|
|
if m, ok := enrichedMajors[key]; ok {
|
|
item.SchoolName = m.SchoolName
|
|
item.MajorName = m.MajorName
|
|
item.PlanNum = m.PlanNum
|
|
item.Tuition = m.Tuition
|
|
// DTO doesn't have icon? Check DTO definition.
|
|
// SchoolMajorDTO in step 150 sql selects school_icon. But DTO struct (step 6) might not have it.
|
|
// Checking DTO definition in step 6... It does NOT have SchoolIcon.
|
|
// I need to update DTO definition if I want SchoolIcon.
|
|
// For now, let's omit if not in DTO or update DTO.
|
|
// Wait, simple fix: update DTO struct later. For now map what matches.
|
|
item.Province = m.Province
|
|
item.SchoolNature = m.SchoolNature
|
|
item.InstitutionType = m.InstitutionType
|
|
item.MajorDetail = m.Detail
|
|
}
|
|
|
|
// Map batch
|
|
// Batch might be "本科提前批", "本科A段" etc. Need to normalize to 3 buckets?
|
|
// Or just use the batch string from record/major?
|
|
// User said "志愿明细(专科批,本科批,提前批)".
|
|
// If data has "本科A段", where does it go? "本科批"?
|
|
// I'll assume exact match or simple containment.
|
|
|
|
// If specific batches exist in data like "本科A段", "本科B段", they go to "本科批"?
|
|
// Let's use simple logic:
|
|
groupKey := ""
|
|
if r.Batch == "提前批" || r.Batch == "本科提前批" {
|
|
groupKey = "提前批"
|
|
} else if r.Batch == "高职高专" || r.Batch == "专科批" {
|
|
groupKey = "专科批"
|
|
} else {
|
|
groupKey = "本科批"
|
|
}
|
|
|
|
groupedItems[groupKey] = append(groupedItems[groupKey], item)
|
|
}
|
|
|
|
// Sort items by Indexs in each group? Records are already ordered by Indexs globally.
|
|
// Within group, they should follow Indexs order naturally if iterated in order.
|
|
|
|
common.Success(c, map[string]interface{}{
|
|
"volunteer": volunteer,
|
|
"items": groupedItems,
|
|
})
|
|
}
|