|  | @@ -5,6 +5,7 @@ import (
 | 
											
												
													
														|  |  	"encoding/json"
 |  |  	"encoding/json"
 | 
											
												
													
														|  |  	"fmt"
 |  |  	"fmt"
 | 
											
												
													
														|  |  	"kpt-pasture/model"
 |  |  	"kpt-pasture/model"
 | 
											
												
													
														|  | 
 |  | +	"kpt-pasture/util"
 | 
											
												
													
														|  |  	"net/http"
 |  |  	"net/http"
 | 
											
												
													
														|  |  	"strings"
 |  |  	"strings"
 | 
											
												
													
														|  |  	"time"
 |  |  	"time"
 | 
											
										
											
												
													
														|  | @@ -337,40 +338,51 @@ func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMatin
 | 
											
												
													
														|  |  	// 所有牛只
 |  |  	// 所有牛只
 | 
											
												
													
														|  |  	cowIds := make([]int64, 0)
 |  |  	cowIds := make([]int64, 0)
 | 
											
												
													
														|  |  	// 需要更新配次的牛只
 |  |  	// 需要更新配次的牛只
 | 
											
												
													
														|  | -	matingTimes := make([]int64, 0)
 |  | 
 | 
											
												
													
														|  | 
 |  | +	matingTimes := make([]*model.MatingTimes, 0)
 | 
											
												
													
														|  | 
 |  | +	// 需要更新空怀的牛只
 | 
											
												
													
														|  | 
 |  | +	emptyCowIds := make([]int64, 0)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	for _, cow := range eventCheckModel.CowList {
 |  |  	for _, cow := range eventCheckModel.CowList {
 | 
											
												
													
														|  | -		// 牛号&& 胎次 && 已配 && 配种结果未知
 |  | 
 | 
											
												
													
														|  | -		count1, err := s.GetEventMatingIsExIstByCowId(ctx, cow, pasturePb.IsShow_Ok)
 |  | 
 | 
											
												
													
														|  | -		if err != nil {
 |  | 
 | 
											
												
													
														|  | -			return xerr.WithStack(err)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		// 1. 第一次配种,创建配种信息(自然发情牛只,未经过同期的牛只)
 | 
											
												
													
														|  | 
 |  | +		if cow.LastMatingAt <= 0 {
 | 
											
												
													
														|  | 
 |  | +			newMatingList = append(newMatingList, model.NewEventMating2(cow, req, eventCheckModel.CurrentUser))
 | 
											
												
													
														|  | 
 |  | +			continue
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		// 牛号&& 胎次 && 未配 && 配种结果未知
 |  | 
 | 
											
												
													
														|  | -		count2, err := s.GetEventMatingIsExIstByCowId(ctx, cow, pasturePb.IsShow_No)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		eventMatingHistory, err := s.GetEventMatingIsExIstByCowId(ctx, cow)
 | 
											
												
													
														|  |  		if err != nil {
 |  |  		if err != nil {
 | 
											
												
													
														|  |  			return xerr.WithStack(err)
 |  |  			return xerr.WithStack(err)
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		// 1. 第一次配种,创建配种信息(自然发情牛只,未经过同期的牛只)
 |  | 
 | 
											
												
													
														|  | -		if cow.LastMatingAt <= 0 {
 |  | 
 | 
											
												
													
														|  | -			newMatingList = append(newMatingList, model.NewEventMating2(cow, req, eventCheckModel.CurrentUser))
 |  | 
 | 
											
												
													
														|  | 
 |  | +		// 2. 同期更新配种信息 牛号&& 胎次 && 未配 && 配种结果未知   ==> 同期初配
 | 
											
												
													
														|  | 
 |  | +		if eventMatingHistory.Status == pasturePb.IsShow_No &&
 | 
											
												
													
														|  | 
 |  | +			eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown {
 | 
											
												
													
														|  | 
 |  | +			updateMatingList = append(updateMatingList, eventMatingHistory.Id)
 | 
											
												
													
														|  | 
 |  | +			continue
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		lastMatingAt := time.Unix(cow.LastMatingAt, 0).Format(model.LayoutDate2)
 |  | 
 | 
											
												
													
														|  | -		currentMatingAt := time.Unix(int64(req.MatingAt), 0).Format(model.LayoutDate2)
 |  | 
 | 
											
												
													
														|  | -		lastAddOneDayAt := time.Unix(cow.LastMatingAt, 0).AddDate(0, 0, 1).Format(model.LayoutDate2)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		lastMatingAt := time.Unix(cow.LastMatingAt, 0)
 | 
											
												
													
														|  | 
 |  | +		currentMatingAt := time.Unix(int64(req.MatingAt), 0)
 | 
											
												
													
														|  | 
 |  | +		daysBetween := util.DaysBetween(currentMatingAt.Unix(), lastMatingAt.Unix())
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		//  2. 如何两次配种时间为连续两天之内&&有过一次配种记录,则更新为复配状态
 |  | 
 | 
											
												
													
														|  | -		if (currentMatingAt == lastMatingAt || currentMatingAt == lastAddOneDayAt) && count1 == 1 {
 |  | 
 | 
											
												
													
														|  | -			matingReMatchIds = append(matingReMatchIds, cow.Id)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		//  3. 如何两次配种时间为连续两天之内&&有过一次配种记录,则更新为复配状态  牛号&& 胎次 && 已配 && 配种结果未知   ==> 复配
 | 
											
												
													
														|  | 
 |  | +		if (currentMatingAt.Format(model.LayoutDate2) == lastMatingAt.Format(model.LayoutDate2) || daysBetween == 1) &&
 | 
											
												
													
														|  | 
 |  | +			eventMatingHistory.Status == pasturePb.IsShow_Ok &&
 | 
											
												
													
														|  | 
 |  | +			eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown {
 | 
											
												
													
														|  | 
 |  | +			matingReMatchIds = append(matingReMatchIds, eventMatingHistory.Id)
 | 
											
												
													
														|  |  		} else {
 |  |  		} else {
 | 
											
												
													
														|  | -			matingTimes = append(matingTimes, cow.Id)
 |  | 
 | 
											
												
													
														|  | 
 |  | +			matingTimes = append(matingTimes, &model.MatingTimes{
 | 
											
												
													
														|  | 
 |  | +				Mt:            cow.MatingTimes + 1,
 | 
											
												
													
														|  | 
 |  | +				CowId:         cow.Id,
 | 
											
												
													
														|  | 
 |  | +				EventMatingId: eventMatingHistory.Id,
 | 
											
												
													
														|  | 
 |  | +			})
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		// 3. 同期更新配种信息
 |  | 
 | 
											
												
													
														|  | -		if count2 == 1 {
 |  | 
 | 
											
												
													
														|  | -			updateMatingList = append(updateMatingList, cow.Id)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		// 4. 提交的配种数据中,如何定位出空怀的牛只,
 | 
											
												
													
														|  | 
 |  | +		if (eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown || eventMatingHistory.MatingResult == pasturePb.MatingResult_ReMatch) &&
 | 
											
												
													
														|  | 
 |  | +			daysBetween >= 2 {
 | 
											
												
													
														|  | 
 |  | +			emptyCowIds = append(emptyCowIds, eventMatingHistory.Id)
 | 
											
												
													
														|  | 
 |  | +			newMatingList = append(newMatingList, model.NewEventMating2(cow, req, eventCheckModel.CurrentUser))
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  		cowIds = append(cowIds, cow.Id)
 |  |  		cowIds = append(cowIds, cow.Id)
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
										
											
												
													
														|  | @@ -392,7 +404,7 @@ func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMatin
 | 
											
												
													
														|  |  		// 更新配种事件数据(初配)
 |  |  		// 更新配种事件数据(初配)
 | 
											
												
													
														|  |  		if len(updateMatingList) > 0 {
 |  |  		if len(updateMatingList) > 0 {
 | 
											
												
													
														|  |  			if err = tx.Model(new(model.EventMating)).
 |  |  			if err = tx.Model(new(model.EventMating)).
 | 
											
												
													
														|  | -				Where("cow_id IN ?", updateMatingList).
 |  | 
 | 
											
												
													
														|  | 
 |  | +				Where("id IN ?", updateMatingList).
 | 
											
												
													
														|  |  				Where("status = ?", pasturePb.IsShow_No).
 |  |  				Where("status = ?", pasturePb.IsShow_No).
 | 
											
												
													
														|  |  				Updates(map[string]interface{}{
 |  |  				Updates(map[string]interface{}{
 | 
											
												
													
														|  |  					"mating_result":       pasturePb.MatingResult_Unknown,
 |  |  					"mating_result":       pasturePb.MatingResult_Unknown,
 | 
											
										
											
												
													
														|  | @@ -411,7 +423,7 @@ func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMatin
 | 
											
												
													
														|  |  		// 更新已配种的牛只为复配状态
 |  |  		// 更新已配种的牛只为复配状态
 | 
											
												
													
														|  |  		if len(matingReMatchIds) > 0 {
 |  |  		if len(matingReMatchIds) > 0 {
 | 
											
												
													
														|  |  			if err = tx.Model(new(model.EventMating)).
 |  |  			if err = tx.Model(new(model.EventMating)).
 | 
											
												
													
														|  | -				Where("cow_id IN ?", matingReMatchIds).
 |  | 
 | 
											
												
													
														|  | 
 |  | +				Where("id IN ?", matingReMatchIds).
 | 
											
												
													
														|  |  				Where("mating_result = ?", pasturePb.MatingResult_Unknown).
 |  |  				Where("mating_result = ?", pasturePb.MatingResult_Unknown).
 | 
											
												
													
														|  |  				Where("status = ?", pasturePb.IsShow_Ok).
 |  |  				Where("status = ?", pasturePb.IsShow_Ok).
 | 
											
												
													
														|  |  				Update("mating_result", pasturePb.MatingResult_ReMatch).
 |  |  				Update("mating_result", pasturePb.MatingResult_ReMatch).
 | 
											
										
											
												
													
														|  | @@ -420,6 +432,16 @@ func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMatin
 | 
											
												
													
														|  |  			}
 |  |  			}
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +		// 更新上次已配种的牛只为空怀
 | 
											
												
													
														|  | 
 |  | +		if len(emptyCowIds) > 0 {
 | 
											
												
													
														|  | 
 |  | +			if err = tx.Model(new(model.EventMating)).
 | 
											
												
													
														|  | 
 |  | +				Where("id IN ?", emptyCowIds).
 | 
											
												
													
														|  | 
 |  | +				Update("mating_result", pasturePb.BreedStatus_Empty).
 | 
											
												
													
														|  | 
 |  | +				Error; err != nil {
 | 
											
												
													
														|  | 
 |  | +				return xerr.WithStack(err)
 | 
											
												
													
														|  | 
 |  | +			}
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  		// 创建配种事件数据
 |  |  		// 创建配种事件数据
 | 
											
												
													
														|  |  		if len(newMatingList) > 0 {
 |  |  		if len(newMatingList) > 0 {
 | 
											
												
													
														|  |  			if err = tx.Create(newMatingList).Error; err != nil {
 |  |  			if err = tx.Create(newMatingList).Error; err != nil {
 | 
											
										
											
												
													
														|  | @@ -462,22 +484,22 @@ func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMatin
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		// 更新配次
 |  |  		// 更新配次
 | 
											
												
													
														|  | -		if err = tx.Model(new(model.EventMating)).
 |  | 
 | 
											
												
													
														|  | -			Where("cow_id IN ?", matingTimes).
 |  | 
 | 
											
												
													
														|  | -			Where("reality_day = ?", req.MatingAt).
 |  | 
 | 
											
												
													
														|  | -			Updates(map[string]interface{}{
 |  | 
 | 
											
												
													
														|  | -				"mating_times": gorm.Expr("mating_times + 1"),
 |  | 
 | 
											
												
													
														|  | -			}).Error; err != nil {
 |  | 
 | 
											
												
													
														|  | -			return xerr.WithStack(err)
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -		if err = tx.Model(new(model.Cow)).
 |  | 
 | 
											
												
													
														|  | -			Where("id IN ?", matingTimes).
 |  | 
 | 
											
												
													
														|  | -			Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
 |  | 
 | 
											
												
													
														|  | -			Updates(map[string]interface{}{
 |  | 
 | 
											
												
													
														|  | -				"mating_times": gorm.Expr("mating_times + 1"),
 |  | 
 | 
											
												
													
														|  | -			}).Error; err != nil {
 |  | 
 | 
											
												
													
														|  | -			return xerr.WithStack(err)
 |  | 
 | 
											
												
													
														|  | 
 |  | +		if len(matingTimes) > 0 {
 | 
											
												
													
														|  | 
 |  | +			for _, mt := range matingTimes {
 | 
											
												
													
														|  | 
 |  | +				if err = tx.Model(new(model.EventMating)).
 | 
											
												
													
														|  | 
 |  | +					Where("id = ?", mt.EventMatingId).
 | 
											
												
													
														|  | 
 |  | +					Update("mating_times", mt.Mt).Error; err != nil {
 | 
											
												
													
														|  | 
 |  | +					return xerr.WithStack(err)
 | 
											
												
													
														|  | 
 |  | +				}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +				if err = tx.Model(new(model.Cow)).
 | 
											
												
													
														|  | 
 |  | +					Where("id = ?", mt.CowId).
 | 
											
												
													
														|  | 
 |  | +					Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
 | 
											
												
													
														|  | 
 |  | +					Where("breed_status = ?", pasturePb.BreedStatus_Breeding).
 | 
											
												
													
														|  | 
 |  | +					Update("mating_times", mt.Mt).Error; err != nil {
 | 
											
												
													
														|  | 
 |  | +					return xerr.WithStack(err)
 | 
											
												
													
														|  | 
 |  | +				}
 | 
											
												
													
														|  | 
 |  | +			}
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		return nil
 |  |  		return nil
 | 
											
										
											
												
													
														|  | @@ -642,9 +664,12 @@ func (s *StoreEntry) AbortionCreate(ctx context.Context, req *pasturePb.EventAbo
 | 
											
												
													
														|  |  	newEventAbortion := model.NewEventAbortion(cow, req, abortionReasonsMap)
 |  |  	newEventAbortion := model.NewEventAbortion(cow, req, abortionReasonsMap)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	lastCowMating := &model.EventMating{}
 |  |  	lastCowMating := &model.EventMating{}
 | 
											
												
													
														|  | -	if err = s.DB.Where("cow_id = ?", cow.Id).Order("id desc").First(lastCowMating).Error; err != nil {
 |  | 
 | 
											
												
													
														|  | 
 |  | +	if err = s.DB.Model(new(model.EventMating)).Where("cow_id = ?", cow.Id).
 | 
											
												
													
														|  | 
 |  | +		Where("mating_result = ?", pasturePb.MatingResult_Pregnant).
 | 
											
												
													
														|  | 
 |  | +		Order("id desc").First(lastCowMating).Error; err != nil {
 | 
											
												
													
														|  |  		return xerr.WithStack(err)
 |  |  		return xerr.WithStack(err)
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	if err = s.DB.Transaction(func(tx *gorm.DB) error {
 |  |  	if err = s.DB.Transaction(func(tx *gorm.DB) error {
 | 
											
												
													
														|  |  		// 创建牛只流产事件数据
 |  |  		// 创建牛只流产事件数据
 | 
											
												
													
														|  |  		if err = tx.Create(newEventAbortion).Error; err != nil {
 |  |  		if err = tx.Create(newEventAbortion).Error; err != nil {
 | 
											
										
											
												
													
														|  | @@ -656,13 +681,13 @@ func (s *StoreEntry) AbortionCreate(ctx context.Context, req *pasturePb.EventAbo
 | 
											
												
													
														|  |  				"is_pregnant":      pasturePb.IsShow_No,
 |  |  				"is_pregnant":      pasturePb.IsShow_No,
 | 
											
												
													
														|  |  				"last_abortion_at": req.AbortionAt,
 |  |  				"last_abortion_at": req.AbortionAt,
 | 
											
												
													
														|  |  				"breed_status":     pasturePb.BreedStatus_Abort,
 |  |  				"breed_status":     pasturePb.BreedStatus_Abort,
 | 
											
												
													
														|  | -				"lact":             cow.Lact + 1,
 |  | 
 | 
											
												
													
														|  |  			}).Error; err != nil {
 |  |  			}).Error; err != nil {
 | 
											
												
													
														|  |  			return xerr.WithStack(err)
 |  |  			return xerr.WithStack(err)
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  		// 更新最近一次配种结果为流产
 |  |  		// 更新最近一次配种结果为流产
 | 
											
												
													
														|  | -		if err = tx.Model(new(model.EventMating)).Where("id = ?", lastCowMating.Id).
 |  | 
 | 
											
												
													
														|  | 
 |  | +		if err = tx.Model(new(model.EventMating)).
 | 
											
												
													
														|  | 
 |  | +			Where("id = ?", lastCowMating.Id).
 | 
											
												
													
														|  |  			Updates(map[string]interface{}{
 |  |  			Updates(map[string]interface{}{
 | 
											
												
													
														|  |  				"mating_result":    pasturePb.MatingResult_Abort,
 |  |  				"mating_result":    pasturePb.MatingResult_Abort,
 | 
											
												
													
														|  |  				"mating_result_at": req.AbortionAt,
 |  |  				"mating_result_at": req.AbortionAt,
 |