保持志愿明细接口
This commit is contained in:
parent
c1a0b60218
commit
26ce858f7a
|
|
@ -0,0 +1,14 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
// 验证表名格式的辅助函数
|
||||||
|
func IsValidTableName(tableName string) bool {
|
||||||
|
if tableName == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表名只能包含字母、数字、下划线和点号,且长度合理
|
||||||
|
matched, err := regexp.MatchString(`^[a-zA-Z_][a-zA-Z0-9_.]{0,100}$`, tableName)
|
||||||
|
return err == nil && matched
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,10 @@ import (
|
||||||
"server/common"
|
"server/common"
|
||||||
user_service "server/modules/user/service"
|
user_service "server/modules/user/service"
|
||||||
yxDto "server/modules/yx/dto"
|
yxDto "server/modules/yx/dto"
|
||||||
|
"server/modules/yx/entity"
|
||||||
yx_service "server/modules/yx/service"
|
yx_service "server/modules/yx/service"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
@ -14,6 +16,8 @@ type UserMajorController struct {
|
||||||
userScoreService *user_service.UserScoreService
|
userScoreService *user_service.UserScoreService
|
||||||
yxUserScoreService *yx_service.YxUserScoreService
|
yxUserScoreService *yx_service.YxUserScoreService
|
||||||
yxCalculationMajorService *yx_service.YxCalculationMajorService
|
yxCalculationMajorService *yx_service.YxCalculationMajorService
|
||||||
|
yxVolunteerService *yx_service.YxVolunteerService
|
||||||
|
yxVolunteerRecordService *yx_service.YxVolunteerRecordService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserMajorController() *UserMajorController {
|
func NewUserMajorController() *UserMajorController {
|
||||||
|
|
@ -21,6 +25,8 @@ func NewUserMajorController() *UserMajorController {
|
||||||
yxUserScoreService: yx_service.NewYxUserScoreService(),
|
yxUserScoreService: yx_service.NewYxUserScoreService(),
|
||||||
userScoreService: user_service.NewUserScoreService(),
|
userScoreService: user_service.NewUserScoreService(),
|
||||||
yxCalculationMajorService: yx_service.NewYxCalculationMajorService(),
|
yxCalculationMajorService: yx_service.NewYxCalculationMajorService(),
|
||||||
|
yxVolunteerService: yx_service.NewYxVolunteerService(),
|
||||||
|
yxVolunteerRecordService: yx_service.NewYxVolunteerRecordService(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,6 +38,7 @@ func (ctrl *UserMajorController) RegisterRoutes(rg *gin.RouterGroup) {
|
||||||
// group.GET("/:id", ctrl.GetByID)
|
// group.GET("/:id", ctrl.GetByID)
|
||||||
group.GET("/list", ctrl.List)
|
group.GET("/list", ctrl.List)
|
||||||
group.GET("/list_by_school", ctrl.ListBySchool)
|
group.GET("/list_by_school", ctrl.ListBySchool)
|
||||||
|
group.POST("/save_volunteer", ctrl.SaveVolunteer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,3 +119,101 @@ func (ctrl *UserMajorController) List(c *gin.Context) {
|
||||||
}
|
}
|
||||||
common.SuccessPage(c, newMap, total, page, size)
|
common.SuccessPage(c, newMap, total, page, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SaveVolunteer 保存志愿明细
|
||||||
|
// @Summary 保存志愿明细
|
||||||
|
// @Tags 用户专业
|
||||||
|
// @Param keys body []string true "Keys: schoolCode_majorCode_enrollmentCode"
|
||||||
|
// @Success 200 {object} common.Response
|
||||||
|
// @Router /user/major/save_volunteer [post]
|
||||||
|
func (ctrl *UserMajorController) 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, "保存成功")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ func NewUserScoreService() *UserScoreService {
|
||||||
return &UserScoreService{
|
return &UserScoreService{
|
||||||
yxUserScoreService: service.NewYxUserScoreService(),
|
yxUserScoreService: service.NewYxUserScoreService(),
|
||||||
yxCalculationMajorService: service.NewYxCalculationMajorService(),
|
yxCalculationMajorService: service.NewYxCalculationMajorService(),
|
||||||
|
yxVolunteerService: service.NewYxVolunteerService(),
|
||||||
mapper: mapper.NewYxUserScoreMapper(),
|
mapper: mapper.NewYxUserScoreMapper(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +179,13 @@ func (s *UserScoreService) SaveUserScore(req *dto.SaveScoreRequest) (vo.UserScor
|
||||||
return vo.UserScoreVO{}, fmt.Errorf("保存专业信息失败: %w", err)
|
return vo.UserScoreVO{}, fmt.Errorf("保存专业信息失败: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建志愿表
|
||||||
|
err = s.yxVolunteerService.CreateByScoreId(entityItem.ID, req.CreateBy)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return vo.UserScoreVO{}, fmt.Errorf("创建志愿表失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 提交事务
|
// 提交事务
|
||||||
if err := tx.Commit().Error; err != nil {
|
if err := tx.Commit().Error; err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
|
@ -193,9 +201,6 @@ func (s *UserScoreService) SaveUserScore(req *dto.SaveScoreRequest) (vo.UserScor
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vo.UserScoreVO{}, fmt.Errorf("缓存成绩记录失败: %w", err)
|
return vo.UserScoreVO{}, fmt.Errorf("缓存成绩记录失败: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建志愿表
|
|
||||||
s.yxVolunteerService.CreateByScoreId(entityItem.ID, req.CreateBy)
|
|
||||||
return userScoreVO, nil
|
return userScoreVO, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package mapper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"server/common"
|
||||||
"server/config"
|
"server/config"
|
||||||
"server/modules/yx/dto"
|
"server/modules/yx/dto"
|
||||||
"server/modules/yx/entity"
|
"server/modules/yx/entity"
|
||||||
|
|
@ -401,6 +402,50 @@ func (m *YxCalculationMajorMapper) FindByScoreID(scoreID string) ([]entity.YxCal
|
||||||
return items, err
|
return items, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *YxCalculationMajorMapper) FindListByCompositeKeys(tableName string, keys []string, scoreId string) ([]entity.YxCalculationMajor, error) {
|
||||||
|
if len(keys) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证表名格式(防止表名注入)
|
||||||
|
if !common.IsValidTableName(tableName) {
|
||||||
|
return nil, fmt.Errorf("无效的表名: %s", tableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证和转义 score_id
|
||||||
|
if scoreId == "" {
|
||||||
|
return nil, fmt.Errorf("score_id 不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []entity.YxCalculationMajor
|
||||||
|
db := config.DB
|
||||||
|
if tableName != "" {
|
||||||
|
db = db.Table(tableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql := "SELECT * FROM " + tableName + " WHERE score_id = ? AND (school_code, major_code, enrollment_code) IN ("
|
||||||
|
var params []interface{}
|
||||||
|
|
||||||
|
// 将 score_id 作为第一个参数
|
||||||
|
params = append(params, scoreId)
|
||||||
|
|
||||||
|
for i, key := range keys {
|
||||||
|
parts := strings.Split(key, "_")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
sql += ","
|
||||||
|
}
|
||||||
|
sql += "(?, ?, ?)"
|
||||||
|
params = append(params, parts[0], parts[1], parts[2])
|
||||||
|
}
|
||||||
|
sql += ")"
|
||||||
|
|
||||||
|
err := db.Raw(sql, params...).Scan(&items).Error
|
||||||
|
return items, err
|
||||||
|
}
|
||||||
|
|
||||||
func (m *YxCalculationMajorMapper) BatchCreate(tableName string, items []entity.YxCalculationMajor, batchSize int) error {
|
func (m *YxCalculationMajorMapper) BatchCreate(tableName string, items []entity.YxCalculationMajor, batchSize int) error {
|
||||||
if tableName != "" {
|
if tableName != "" {
|
||||||
return config.DB.Table(tableName).CreateInBatches(items, batchSize).Error
|
return config.DB.Table(tableName).CreateInBatches(items, batchSize).Error
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,15 @@ import (
|
||||||
|
|
||||||
type YxVolunteerMapper struct{}
|
type YxVolunteerMapper struct{}
|
||||||
|
|
||||||
func (m *YxVolunteerMapper) CloseOtherVolunteer(userId string) {
|
func (m *YxVolunteerMapper) CloseOtherVolunteer(userId string) error {
|
||||||
config.DB.Model(&entity.YxVolunteer{}).Where("create_by = ? ", userId).Updates(map[string]interface{}{"state": "0"})
|
result := config.DB.Model(&entity.YxVolunteer{}).
|
||||||
|
Where("create_by = ?", userId).
|
||||||
|
Updates(map[string]interface{}{"state": "0"})
|
||||||
|
|
||||||
|
if result.Error != nil {
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYxVolunteerMapper() *YxVolunteerMapper {
|
func NewYxVolunteerMapper() *YxVolunteerMapper {
|
||||||
|
|
@ -32,6 +39,12 @@ func (m *YxVolunteerMapper) FindByID(id string) (*entity.YxVolunteer, error) {
|
||||||
return &item, err
|
return &item, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *YxVolunteerMapper) FindActiveByScoreId(scoreId string) (*entity.YxVolunteer, error) {
|
||||||
|
var item entity.YxVolunteer
|
||||||
|
err := config.DB.Where("score_id = ? AND state = ?", scoreId, "1").First(&item).Error
|
||||||
|
return &item, err
|
||||||
|
}
|
||||||
|
|
||||||
func (m *YxVolunteerMapper) Create(item *entity.YxVolunteer) error {
|
func (m *YxVolunteerMapper) Create(item *entity.YxVolunteer) error {
|
||||||
return config.DB.Create(item).Error
|
return config.DB.Create(item).Error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ func (m *YxVolunteerRecordMapper) Delete(id string) error {
|
||||||
return config.DB.Delete(&entity.YxVolunteerRecord{}, "id = ?", id).Error
|
return config.DB.Delete(&entity.YxVolunteerRecord{}, "id = ?", id).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *YxVolunteerRecordMapper) DeleteByVolunteerID(volunteerID string) error {
|
||||||
|
return config.DB.Delete(&entity.YxVolunteerRecord{}, "volunteer_id = ?", volunteerID).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (m *YxVolunteerRecordMapper) BatchCreate(items []entity.YxVolunteerRecord, batchSize int) error {
|
func (m *YxVolunteerRecordMapper) BatchCreate(items []entity.YxVolunteerRecord, batchSize int) error {
|
||||||
return config.DB.CreateInBatches(items, batchSize).Error
|
return config.DB.CreateInBatches(items, batchSize).Error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,10 @@ func (s *YxCalculationMajorService) GetByScoreID(scoreID string) ([]entity.YxCal
|
||||||
return s.mapper.FindByScoreID(scoreID)
|
return s.mapper.FindByScoreID(scoreID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *YxCalculationMajorService) FindListByCompositeKeys(tableName string, keys []string, scoreId string) ([]entity.YxCalculationMajor, error) {
|
||||||
|
return s.mapper.FindListByCompositeKeys(tableName, keys, scoreId)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *YxCalculationMajorService) BatchCreate(tableName string, items []entity.YxCalculationMajor) error {
|
func (s *YxCalculationMajorService) BatchCreate(tableName string, items []entity.YxCalculationMajor) error {
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].ID = uuid.New().String()
|
items[i].ID = uuid.New().String()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ func (s *YxVolunteerRecordService) Delete(id string) error {
|
||||||
return s.mapper.Delete(id)
|
return s.mapper.Delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *YxVolunteerRecordService) DeleteByVolunteerID(volunteerID string) error {
|
||||||
|
return s.mapper.DeleteByVolunteerID(volunteerID)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *YxVolunteerRecordService) BatchCreate(items []entity.YxVolunteerRecord) error {
|
func (s *YxVolunteerRecordService) BatchCreate(items []entity.YxVolunteerRecord) error {
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].ID = uuid.New().String()
|
items[i].ID = uuid.New().String()
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"server/common"
|
||||||
"server/modules/yx/entity"
|
"server/modules/yx/entity"
|
||||||
"server/modules/yx/mapper"
|
"server/modules/yx/mapper"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type YxVolunteerService struct {
|
type YxVolunteerService struct {
|
||||||
|
|
@ -26,10 +26,14 @@ func (s *YxVolunteerService) GetByID(id string) (*entity.YxVolunteer, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *YxVolunteerService) Create(item *entity.YxVolunteer) error {
|
func (s *YxVolunteerService) Create(item *entity.YxVolunteer) error {
|
||||||
item.ID = uuid.New().String()
|
item.ID = common.GenerateStringID()
|
||||||
return s.mapper.Create(item)
|
return s.mapper.Create(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *YxVolunteerService) FindActiveByScoreId(scoreId string) (*entity.YxVolunteer, error) {
|
||||||
|
return s.mapper.FindActiveByScoreId(scoreId)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *YxVolunteerService) Update(item *entity.YxVolunteer) error {
|
func (s *YxVolunteerService) Update(item *entity.YxVolunteer) error {
|
||||||
return s.mapper.Update(item)
|
return s.mapper.Update(item)
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +48,7 @@ func (s *YxVolunteerService) Delete(id string) error {
|
||||||
|
|
||||||
func (s *YxVolunteerService) BatchCreate(items []entity.YxVolunteer) error {
|
func (s *YxVolunteerService) BatchCreate(items []entity.YxVolunteer) error {
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].ID = uuid.New().String()
|
items[i].ID = common.GenerateStringID()
|
||||||
}
|
}
|
||||||
return s.mapper.BatchCreate(items, 100)
|
return s.mapper.BatchCreate(items, 100)
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +60,7 @@ func (s *YxVolunteerService) BatchUpdate(items []entity.YxVolunteer) error {
|
||||||
func (s *YxVolunteerService) BatchUpsert(items []entity.YxVolunteer, updateColumns []string) error {
|
func (s *YxVolunteerService) BatchUpsert(items []entity.YxVolunteer, updateColumns []string) error {
|
||||||
for i := range items {
|
for i := range items {
|
||||||
if items[i].ID == "" {
|
if items[i].ID == "" {
|
||||||
items[i].ID = uuid.New().String()
|
items[i].ID = common.GenerateStringID()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s.mapper.BatchUpsert(items, updateColumns)
|
return s.mapper.BatchUpsert(items, updateColumns)
|
||||||
|
|
@ -69,8 +73,7 @@ func (s *YxVolunteerService) BatchDelete(ids []string) error {
|
||||||
// 根据ScoreId创建新志愿表
|
// 根据ScoreId创建新志愿表
|
||||||
func (s *YxVolunteerService) CreateByScoreId(scoreId string, userId string) error {
|
func (s *YxVolunteerService) CreateByScoreId(scoreId string, userId string) error {
|
||||||
volunteer := entity.YxVolunteer{}
|
volunteer := entity.YxVolunteer{}
|
||||||
volunteer.ID = uuid.New().String()
|
volunteer.ID = common.GenerateStringID()
|
||||||
|
|
||||||
// 志愿表名称格式 时间戳 20260101134501志愿表
|
// 志愿表名称格式 时间戳 20260101134501志愿表
|
||||||
volunteer.VolunteerName = time.Now().Format("20060102150405") + "志愿表"
|
volunteer.VolunteerName = time.Now().Format("20060102150405") + "志愿表"
|
||||||
|
|
||||||
|
|
@ -81,8 +84,10 @@ func (s *YxVolunteerService) CreateByScoreId(scoreId string, userId string) erro
|
||||||
volunteer.CreateTime = time.Now()
|
volunteer.CreateTime = time.Now()
|
||||||
volunteer.UpdateTime = time.Now()
|
volunteer.UpdateTime = time.Now()
|
||||||
|
|
||||||
// 先关闭当前用户其他志愿单
|
// 先关闭当前用户其他志愿单 - ✅ 检查错误
|
||||||
s.mapper.CloseOtherVolunteer(userId)
|
if err := s.mapper.CloseOtherVolunteer(userId); err != nil {
|
||||||
|
return fmt.Errorf("关闭其他志愿表失败: %w", err)
|
||||||
|
}
|
||||||
// 创建志愿表
|
// 创建志愿表
|
||||||
return s.mapper.Create(&volunteer)
|
return s.mapper.Create(&volunteer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue