123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- package backend
- import (
- "context"
- "fmt"
- "kpt-pasture/model"
- "kpt-pasture/util"
- "math"
- "net/http"
- "time"
- pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
- "gitee.com/xuyiping_admin/pkg/xerr"
- )
- func (s *StoreEntry) TwentyOnePregnantRate(ctx context.Context, req *pasturePb.TwentyOnePregnantRateRequest) (*pasturePb.TwentyOnePregnantRateResponse, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- startUnix := util.TimeParseLocalUnix(req.StartDate)
- endUnix := util.TimeParseLocalUnix(req.EndDate)
- if startUnix > endUnix {
- return nil, xerr.Customf("开始时间不能大于结束时间: %s ~ %d", req.StartDate, req.EndDate)
- }
- nowDateTime := time.Now().Local()
- if endUnix > nowDateTime.Unix() {
- return nil, xerr.Customf("结束时间不能大于当前时间: %s ~ %s", req.EndDate, nowDateTime.Format(model.LayoutDate2))
- }
- dataRange, err := util.Get21DayPeriods(req.StartDate, req.EndDate)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- chart := &pasturePb.TwentyOnePregnantRateChart{
- Header: make([]string, 0),
- PregnantRate: make([]float32, 0),
- MatingRate: make([]float32, 0),
- }
- // 牛只主动停配期
- systemBasicName := ""
- switch req.CowType {
- case pasturePb.CowType_Breeding_Calf:
- systemBasicName = model.ProactivelyStopBreedingForAdult
- case pasturePb.CowType_Reserve_Calf:
- systemBasicName = model.ProactivelyStopBreedingForBackup
- default:
- return nil, xerr.Customf("不支持的牛只类型: %d", req.CowType)
- }
- systemBasic, err := s.GetSystemBasicByName(ctx, userModel.AppPasture.Id, systemBasicName)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- stopBreedingDay := systemBasic.MinValue
- twentyOnePregnantRateList := make([]*pasturePb.TwentyOnePregnantRateList, 0)
- for _, v := range dataRange {
- middleDay, err := util.GetRangeDayMiddleDay(v, 11)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- _, shouldBreedCount := s.TwentyOnePregnantShouldBreedList(userModel.AppPasture.Id, req.CowType, stopBreedingDay, middleDay)
- realityBreedCowList, realityBreedCount := s.TwentyOnePregnantRealityBreedList(userModel.AppPasture.Id, req.CowType, v[0], v[1])
- breedRate, abortionRate, realityPregnantRate := float32(0), float32(0), float32(0)
- if realityBreedCount > 0 && shouldBreedCount > 0 {
- breedRate = float32(math.Round(float64(realityBreedCount)/float64(shouldBreedCount)*100) / 100)
- }
- realityPregnantCount, shouldPregnantCount, realityAbortionCount := int32(0), int32(0), int32(0)
- for _, eventMating := range realityBreedCowList {
- if eventMating.MatingResult == pasturePb.MatingResult_Pregnant {
- realityPregnantCount++
- }
- if eventMating.MatingResult == pasturePb.MatingResult_Abort {
- realityAbortionCount++
- }
- if s.IsDeparture(ctx, userModel.AppPasture.Id, eventMating.CowId, 35) {
- shouldPregnantCount++
- }
- }
- if realityPregnantCount > 0 && shouldPregnantCount > 0 {
- realityPregnantRate = float32(math.Round(float64(realityPregnantCount)/float64(shouldPregnantCount)*100) / 100)
- }
- if realityAbortionCount > 0 && realityPregnantCount > 0 {
- abortionRate = float32(math.Round(float64(realityAbortionCount)/float64(realityPregnantCount)*100) / 100)
- }
- chart.Header = append(chart.Header, fmt.Sprintf("%s ~ %s", v[0][5:], v[1][5:]))
- chart.PregnantRate = append(chart.PregnantRate, realityPregnantRate)
- chart.MatingRate = append(chart.MatingRate, breedRate)
- twentyOnePregnantRateList = append(twentyOnePregnantRateList, &pasturePb.TwentyOnePregnantRateList{
- StartDay: v[0],
- EndDay: v[1],
- ShouldBreedCount: shouldBreedCount, // 应配种
- RealityBreedCount: realityBreedCount, // 实际配种
- BreedRate: breedRate, // 配种率
- ShouldPregnantCount: shouldPregnantCount, // 应怀孕
- RealityPregnantCount: realityPregnantCount, // 实际怀孕
- PregnantRate: realityPregnantRate, // 怀孕率
- RealityAbortionCount: realityAbortionCount, // 实际流产
- AbortionRate: abortionRate, // 流产率
- })
- }
- return &pasturePb.TwentyOnePregnantRateResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.TwentyOnePregnantRateData{
- Chart: chart,
- Table: &pasturePb.TwentyOnePregnantRateTable{
- List: twentyOnePregnantRateList,
- Total: int32(len(dataRange)),
- },
- },
- }, nil
- }
- // TwentyOnePregnantShouldBreedList 21天牛应配牛只列表
- func (s *StoreEntry) TwentyOnePregnantShouldBreedList(pastureId int64, cowType pasturePb.CowType_Kind, stopBreedingDay int32, middleDay string) ([]*model.CowCalving, int32) {
- everyDayCalvingList := make([]*model.CowCalving, 0)
- if err := s.DB.Model(new(model.CowCalving)).
- Where("pasture_id = ?", pastureId).
- Where("cow_type = ?", cowType).
- Where("date_time = ?", middleDay).
- Where("calving_age >= ?", stopBreedingDay).
- Where("is_abortion = ?", pasturePb.IsShow_No).
- Where("is_departure = ?", pasturePb.IsShow_No).
- Where("is_forbidden = ?", pasturePb.IsShow_No).
- Find(&everyDayCalvingList).Error; err != nil {
- return everyDayCalvingList, 0
- }
- return everyDayCalvingList, int32(len(everyDayCalvingList))
- }
- func (s *StoreEntry) TwentyOnePregnantRealityBreedList(pastureId int64, cowType pasturePb.CowType_Kind, startDate, endDate string) ([]*model.EventMating, int32) {
- eventMatingList := make([]*model.EventMating, 0)
- if err := s.DB.Model(new(model.EventMating)).
- Where("pasture_id = ?", pastureId).
- Where("cow_type = ?", cowType).
- Where("reality_day BETWEEN ? AND ?", util.TimeParseLocalUnix(startDate), util.TimeParseLocalEndUnix(endDate)).
- Where("status = ?", pasturePb.IsShow_Ok).
- Find(&eventMatingList).Error; err != nil {
- return eventMatingList, 0
- }
- return eventMatingList, int32(len(eventMatingList))
- }
- // IsDeparture 是否离场并且在配种后35天
- func (s *StoreEntry) IsDeparture(ctx context.Context, pastureId, cowId int64, days int32) bool {
- cowInfo := &model.Cow{}
- if err := s.DB.Model(new(model.Cow)).
- Where("pasture_id = ?", pastureId).
- Where("sex = ?", pasturePb.Genders_Female).
- Where("id = ?", cowId).First(cowInfo).Error; err != nil {
- return false
- }
- matingUnix := time.Unix(cowInfo.LastMatingAt, 0).Local().AddDate(0, 0, int(days)).Unix()
- departureAt := cowInfo.DepartureAt
- if departureAt > 0 && matingUnix >= matingUnix {
- return true
- }
- return false
- }
- func (s *StoreEntry) TwentyOnePregnantDetail(ctx context.Context, req *pasturePb.TwentyOnePregnantDetailsRequest) (*pasturePb.TwentyOnePregnantDetailsResponse, error) {
- userModel, err := s.GetUserModel(ctx)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- pastureId := userModel.AppPasture.Id
- list := make([]*pasturePb.TwentyOnePregnantItems, 0)
- // 牛只主动停配期
- systemBasicName := ""
- switch req.CowType {
- case pasturePb.CowType_Breeding_Calf:
- systemBasicName = model.ProactivelyStopBreedingForAdult
- case pasturePb.CowType_Reserve_Calf:
- systemBasicName = model.ProactivelyStopBreedingForBackup
- default:
- return nil, xerr.Customf("不支持的牛只类型: %d", req.CowType)
- }
- systemBasic, err := s.GetSystemBasicByName(ctx, userModel.AppPasture.Id, systemBasicName)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- stopBreedingDay := systemBasic.MinValue
- middleDay, err := util.GetRangeDayMiddleDay([]string{req.StartDate, req.EndDate}, 11)
- if err != nil {
- return nil, xerr.WithStack(err)
- }
- cowTypeMap := s.CowTypeMap()
- switch req.Type {
- case pasturePb.TwentyOnePregnantType_ShouldBreed:
- shouldBreedCowList, _ := s.TwentyOnePregnantShouldBreedList(pastureId, req.CowType, stopBreedingDay, middleDay)
- list = model.CowCalvingSlice(shouldBreedCowList).ToPB()
- case pasturePb.TwentyOnePregnantType_RealityBreed:
- realityBreedCowList, _ := s.TwentyOnePregnantRealityBreedList(pastureId, req.CowType, req.StartDate, req.EndDate)
- list = model.EventMatingSlice(realityBreedCowList).ToPB3(false, cowTypeMap)
- case pasturePb.TwentyOnePregnantType_ShouldPregnant:
- realityBreedCowList, _ := s.TwentyOnePregnantRealityBreedList(pastureId, req.CowType, req.StartDate, req.EndDate)
- newShouldBreedCowList := make([]*model.EventMating, 0)
- for _, v := range realityBreedCowList {
- if s.IsDeparture(ctx, v.PastureId, v.CowId, stopBreedingDay) {
- newShouldBreedCowList = append(newShouldBreedCowList, v)
- }
- }
- list = model.EventMatingSlice(newShouldBreedCowList).ToPB3(false, cowTypeMap)
- case pasturePb.TwentyOnePregnantType_RealityPregnant:
- realityBreedCowList, _ := s.TwentyOnePregnantRealityBreedList(userModel.AppPasture.Id, req.CowType, req.StartDate, req.EndDate)
- list = model.EventMatingSlice(realityBreedCowList).ToPB3(true, cowTypeMap)
- case pasturePb.TwentyOnePregnantType_RealityAbortion:
- realityBreedCowList, _ := s.TwentyOnePregnantRealityBreedList(userModel.AppPasture.Id, req.CowType, req.StartDate, req.EndDate)
- list = model.EventMatingSlice(realityBreedCowList).ToPB4(cowTypeMap)
- }
- return &pasturePb.TwentyOnePregnantDetailsResponse{
- Code: http.StatusOK,
- Msg: "ok",
- Data: &pasturePb.TwentyOnePregnantData{
- List: list,
- Header: map[string]string{
- "earNumber": "牛号",
- "lact": "胎次",
- "matingDateFormat": "配种日期",
- "matingTimes": "配次",
- "pregnantCheckDateFormat": "孕检日期",
- "isMating": "是否有胎",
- "abortionDateFormat": "流产日期",
- "departureDateFormat": "离场日期",
- "expectedProductionDateFormat": "预产日期",
- },
- HeaderSort: []string{"earNumber", "lact", "matingDateFormat", "matingTimes", "pregnantCheckDateFormat",
- "isMating", "abortionDateFormat", "departureDateFormat", "expectedProductionDateFormat"},
- },
- }, nil
- }
|