瀏覽代碼

event: update

Yi 1 周之前
父節點
當前提交
2812e54057

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250319122035-8a8593d0cae9
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250320032539-3a62ca0c9a40
 	gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3

+ 4 - 0
go.sum

@@ -48,6 +48,10 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250319101753-c158097ddaa7 h1:Ex4WiajO
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250319101753-c158097ddaa7/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250319122035-8a8593d0cae9 h1:4HUr1cFR5aIFjiiSgyoL0s5zTWwUFC79Jf0JDEyUCgU=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250319122035-8a8593d0cae9/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250320024624-258ecc3b44f0 h1:Mrc0nMlNXGcMkCVzK8+aTXzoB/8t/9VDBuEYsiz8II8=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250320024624-258ecc3b44f0/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250320032539-3a62ca0c9a40 h1:B6D9VigfBV0MX0tB+8ga8GduOSC22ZBcGOomj2jAtaw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250320032539-3a62ca0c9a40/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b h1:w05MxH7yqveRlaRbxHhbif5YjPrJFodRPfOjYhXn7Zk=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

+ 1 - 1
http/handler/event/event_breed.go

@@ -185,7 +185,7 @@ func MatingBatch(c *gin.Context) {
 }
 
 func EstrusEventList(c *gin.Context) {
-	var req pasturePb.EstrusItemsRequest
+	var req pasturePb.SearchEventRequest
 	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return

+ 2 - 24
http/handler/work/item.go

@@ -111,7 +111,7 @@ func CalvingList(c *gin.Context) {
 }
 
 func NeckRingWarningEstrusItem(c *gin.Context) {
-	var req pasturePb.EstrusItemsRequest
+	var req pasturePb.WarningItemsRequest
 	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -123,29 +123,7 @@ func NeckRingWarningEstrusItem(c *gin.Context) {
 		PageOffset: int32(c.GetInt(middleware.PageOffset)),
 	}
 
-	res, err := middleware.BackendOperation(c).OpsService.EstrusCowList(c, &req, pagination)
-	if err != nil {
-		apierr.ClassifiedAbort(c, err)
-		return
-	}
-
-	ginutil.JSONResp(c, res)
-}
-
-func NeckRingWarningAbortionItem(c *gin.Context) {
-	var req pasturePb.EstrusItemsRequest
-	if err := ginutil.BindProto(c, &req); err != nil {
-		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
-		return
-	}
-
-	pagination := &pasturePb.PaginationModel{
-		Page:       int32(c.GetInt(middleware.Page)),
-		PageSize:   int32(c.GetInt(middleware.PageSize)),
-		PageOffset: int32(c.GetInt(middleware.PageOffset)),
-	}
-
-	res, err := middleware.BackendOperation(c).OpsService.EstrusCowList(c, &req, pagination)
+	res, err := middleware.BackendOperation(c).OpsService.EstrusOrAbortionCowList(c, &req, pagination)
 	if err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return

+ 4 - 2
http/route/work_api.go

@@ -30,8 +30,10 @@ func WorkOrderAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		workRoute.POST("/weaning/items", work.WeaningCowList)
 		workRoute.POST("/mating/items", work.MatingCowList)
 		workRoute.POST("/calving/items", work.CalvingList)
-		workRoute.POST("/estrus/items", work.NeckRingWarningEstrusItem)
-		workRoute.POST("/abortion/items", work.NeckRingWarningAbortionItem)
 		workRoute.POST("/disease/items", event.CowDiseaseList)
+
+		// 发情预警
+		workRoute.POST("/estrus/items", work.NeckRingWarningEstrusItem)
+		workRoute.POST("/abortion/items", work.NeckRingWarningEstrusItem)
 	}
 }

+ 28 - 24
model/cow.go

@@ -10,26 +10,28 @@ import (
 
 type Cow struct {
 	Id                  int64                          `json:"id"`
-	PastureId           int64                          `json:"pastureId"`           // 牧场id
-	Sex                 pasturePb.Genders_Kind         `json:"sex"`                 // 性别
-	NeckRingNumber      string                         `json:"neckRingNumber"`      // 脖环号
-	EarNumber           string                         `json:"earNumber"`           // 耳标号
-	EarOldNumber        string                         `json:"earOldNumber"`        // 旧耳标号
-	PenId               int32                          `json:"penId"`               // 栏舍id
-	PenName             string                         `json:"penName"`             // 栏舍名称
-	Lact                int32                          `json:"lact"`                // 胎次
-	DayAge              int32                          `json:"dayAge"`              // 日龄
-	CalvingAge          int32                          `json:"calvingAge"`          // 产后天使
-	PregnancyAge        int32                          `json:"pregnancyAge"`        // 怀孕天数 孕检结果有阳性更新,产犊后至0
-	AdmissionAge        int32                          `json:"admissionAge"`        // 入场日龄
-	AbortionAge         int32                          `json:"abortionAge"`         // 流产天数
-	CowType             pasturePb.CowType_Kind         `json:"cowType"`             // 牛只类型
-	BreedStatus         pasturePb.BreedStatus_Kind     `json:"breedStatus"`         // 繁殖状态
-	CowKind             pasturePb.CowKind_Kind         `json:"cowKind"`             // 牛只品种
-	BirthWeight         int64                          `json:"birthWeight"`         // 出生体重
-	CurrentWeight       int64                          `json:"currentWeight"`       // 当前体重
-	AdmissionWeight     int64                          `json:"admissionWeight"`     // 入场体重
-	SourceId            pasturePb.CowSource_Kind       `json:"sourceId"`            // 来源哪里
+	PastureId           int64                          `json:"pastureId"`       // 牧场id
+	Sex                 pasturePb.Genders_Kind         `json:"sex"`             // 性别
+	NeckRingNumber      string                         `json:"neckRingNumber"`  // 脖环号
+	EarNumber           string                         `json:"earNumber"`       // 耳标号
+	EleEarNumber        string                         `json:"eleEarNumber"`    // 电子耳标号
+	EarOldNumber        string                         `json:"earOldNumber"`    // 旧耳标号
+	PenId               int32                          `json:"penId"`           // 栏舍id
+	PenName             string                         `json:"penName"`         // 栏舍名称
+	Lact                int32                          `json:"lact"`            // 胎次
+	DayAge              int32                          `json:"dayAge"`          // 日龄
+	CalvingAge          int32                          `json:"calvingAge"`      // 产后天使
+	PregnancyAge        int32                          `json:"pregnancyAge"`    // 怀孕天数 孕检结果有阳性更新,产犊后至0
+	AdmissionAge        int32                          `json:"admissionAge"`    // 入场日龄
+	AbortionAge         int32                          `json:"abortionAge"`     // 流产天数
+	CowType             pasturePb.CowType_Kind         `json:"cowType"`         // 牛只类型
+	BreedStatus         pasturePb.BreedStatus_Kind     `json:"breedStatus"`     // 繁殖状态
+	CowKind             pasturePb.CowKind_Kind         `json:"cowKind"`         // 牛只品种
+	BirthWeight         int64                          `json:"birthWeight"`     // 出生体重
+	CurrentWeight       int64                          `json:"currentWeight"`   // 当前体重
+	AdmissionWeight     int64                          `json:"admissionWeight"` // 入场体重
+	SourceKind          pasturePb.CowSource_Kind       `json:"sourceKind"`      // 来源哪里
+	PurposeKind         pasturePb.Purpose_Kind         `json:"purposeKind"`
 	FatherNumber        string                         `json:"fatherNumber"`        // 父号
 	MotherNumber        string                         `json:"motherNumber"`        // 母号
 	AdmissionStatus     pasturePb.AdmissionStatus_Kind `json:"admissionStatus"`     // 在场状态
@@ -265,7 +267,7 @@ func (c CowSlice) ToPB(
 			BirthWeight:               float32(v.BirthWeight) / 1000,
 			CurrentWeight:             float32(v.CurrentWeight) / 1000,
 			DayAge:                    v.DayAge,
-			SourceName:                cowSourceMap[v.SourceId],
+			SourceName:                cowSourceMap[v.SourceKind],
 			MotherNumber:              v.MotherNumber,
 			FatherNumber:              v.FatherNumber,
 			AdmissionStatusName:       admissionStatusMap[v.AdmissionStatus],
@@ -349,11 +351,13 @@ func NewEnterCow(pastureId int64, req *pasturePb.EventEnterRequest, penMap map[i
 		CowType:             req.CowType,
 		BreedStatus:         req.BreedStatus,
 		CowKind:             req.CowKind,
-		SourceId:            req.CowSource,
+		SourceKind:          req.CowSource,
 		FatherNumber:        req.FatherNumber,
 		MotherNumber:        req.MotherNumber,
 		AdmissionStatus:     pasturePb.AdmissionStatus_Admission,
 		HealthStatus:        pasturePb.HealthStatus_Health,
+		PurposeKind:         req.PurposeKind,
+		EleEarNumber:        req.EleEarNumber,
 		IsPregnant:          isPregnant,
 		WeaningAt:           int64(req.WeaningAt),
 		BirthAt:             int64(req.BirthAt),
@@ -381,7 +385,7 @@ func NewCalfCow(matherInfo *Cow, calf *CalvingCalf) *Cow {
 		CowKind:         matherInfo.CowKind,               // 牛只品种
 		BirthWeight:     calf.BirthWeight,
 		BirthAt:         calf.BirthAt,
-		SourceId:        pasturePb.CowSource_Calving, // 产犊方式
+		SourceKind:      pasturePb.CowSource_Calving, // 产犊方式
 		FatherNumber:    matherInfo.EarNumber,
 		MotherNumber:    matherInfo.LastBullNumber,
 		AdmissionStatus: pasturePb.AdmissionStatus_Admission,
@@ -455,7 +459,7 @@ func (c *Cow) GetAverageDailyWeight() float64 {
 		return 0
 	}
 	firstWeight := c.BirthWeight
-	if c.SourceId == pasturePb.CowSource_Buy {
+	if c.SourceKind == pasturePb.CowSource_Buy {
 		firstWeight = c.AdmissionWeight
 
 	}

+ 22 - 0
module/backend/config_data_base.go

@@ -243,3 +243,25 @@ func (s *StoreEntry) IndicatorsDetailsList(isAll string) []*pasturePb.ConfigOpti
 
 	return configOptions
 }
+
+func (s *StoreEntry) CowPurposeList(isAll string) []*pasturePb.ConfigOptionsList {
+	configOptions := make([]*pasturePb.ConfigOptionsList, 0)
+	if isAll == model.IsAllYes {
+		configOptions = append(configOptions,
+			&pasturePb.ConfigOptionsList{
+				Value:    int32(0),
+				Label:    "全部",
+				Disabled: true,
+			})
+	}
+	configOptions = append(configOptions, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.Purpose_Breeding),
+		Label:    "繁殖",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.Purpose_Fatten),
+		Label:    "育肥",
+		Disabled: true,
+	})
+	return configOptions
+}

+ 1 - 0
module/backend/enum_options.go

@@ -217,6 +217,7 @@ func (s *StoreEntry) SystemBaseConfigOptions(ctx context.Context, optionsName, i
 		"deadReason":                 s.DeadReasonEnumList,
 		"categoryKind":               s.EventCategoryEnumList,
 		"indicatorsDetails":          s.IndicatorsDetailsList,
+		"purposeKind":                s.CowPurposeList,
 	}
 
 	getConfigFunc, ok := getConfigFuncMap[optionsName]

+ 3 - 17
module/backend/event_breed.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"fmt"
 	"kpt-pasture/model"
-	"kpt-pasture/util"
 	"net/http"
 	"strings"
 	"time"
@@ -323,7 +322,7 @@ func (s *StoreEntry) SameTimeList(
 	}, nil
 }
 
-func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventEstrusResponse, error) {
+func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventEstrusResponse, error) {
 	userModel, err := s.GetUserModel(ctx)
 	if err != nil {
 		return nil, xerr.WithStack(err)
@@ -335,26 +334,13 @@ func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.EstrusItemsR
 		Where("is_show = ?", pasturePb.IsShow_Ok).
 		Where("pasture_id = ?", userModel.AppPasture.Id).
 		Where("expose_estrus_type = ?", pasturePb.ExposeEstrusType_Natural_Estrus)
-	if len(req.EarNumbers) > 0 {
-		earNumberString := ""
-		for _, e := range req.EarNumbers {
-			earNumberString += fmt.Sprintf("%s,", e)
-		}
-
-		pref.Where("ear_number IN (?)", strings.TrimRight(earNumberString, ","))
-	}
 
 	if req.EarNumber != "" {
 		pref.Where("ear_number = ?", req.EarNumber)
 	}
 
-	if req.Level > 0 {
-		pref.Where("level = ?", req.Level)
-	}
-
-	if len(req.PenIds) > 0 {
-		penIds := strings.Split(util.ArrayInt32ToStrings(req.PenIds, ","), ",")
-		pref.Where("pen_id IN ?", penIds)
+	if req.StartDayAt > 0 && req.EndDayAt > 0 && req.StartDayAt <= req.EndDayAt {
+		pref.Where("reality_day BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt)
 	}
 
 	if err = pref.Order("id desc").

+ 1 - 1
module/backend/event_cow_log.go

@@ -36,7 +36,7 @@ func (s *StoreEntry) SubmitEventLog(ctx context.Context, pastureId int64, cow *m
 		}
 		desc = fmt.Sprintf("性别: %s; 栏舍: %s; 体重: %s kg; 价格: %s; 来源: %s;", sex, penMap[cow.PenId].Name,
 			strconv.FormatFloat(float64(data.Weight), 'f', 2, 64),
-			strconv.FormatFloat(float64(data.Price), 'f', 2, 64), sourceMap[cow.SourceId])
+			strconv.FormatFloat(float64(data.Price), 'f', 2, 64), sourceMap[cow.SourceKind])
 	case pasturePb.EventType_Transfer_Ben:
 		data := req.(*model.EventTransferGroup)
 		transferAt, _ := util.TimeParseLocal(model.LayoutTime, data.TransferDate)

+ 2 - 2
module/backend/interface.go

@@ -177,7 +177,7 @@ type EventService interface {
 	MatingBatch(ctx context.Context, req *pasturePb.EventMatingBatch) error
 	// EstrusBatchMating 发情批量处理配种
 	EstrusBatchMating(ctx context.Context, req *pasturePb.EventNaturalEstrusBatch) error
-	EstrusList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventEstrusResponse, error)
+	EstrusList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchEventEstrusResponse, error)
 
 	// AbortionList 流产
 	AbortionList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventAbortionResponse, error)
@@ -298,7 +298,7 @@ type WorkService interface {
 	MatingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingItemsResponse, error)
 	CalvingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CalvingItemsResponse, error)
 	CowDiseaseList(ctx context.Context, req *pasturePb.SearchEventCowTreatmentRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowDiseaseResponse, error)
-	EstrusCowList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusResponse, error)
+	EstrusOrAbortionCowList(ctx context.Context, req *pasturePb.WarningItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusResponse, error)
 }
 
 type TestService interface {

+ 37 - 22
module/backend/neck_ring_warning.go

@@ -9,39 +9,54 @@ import (
 	"strings"
 	"time"
 
+	"gorm.io/gorm"
+
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 	"gitee.com/xuyiping_admin/pkg/xerr"
 )
 
-func (s *StoreEntry) EstrusCowList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusResponse, error) {
+func (s *StoreEntry) EstrusOrAbortionCowList(ctx context.Context, req *pasturePb.WarningItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusResponse, error) {
 	userModel, err := s.GetUserModel(ctx)
 	if err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	systemBasic, err := s.FindSystemBasic(ctx, userModel.AppPasture.Id, model.EstrusWaringDays)
-	if err != nil {
-		return nil, xerr.WithStack(err)
-	}
-
-	nowTime := time.Now()
-	startTime := time.Unix(util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
-	entTime := time.Unix(util.TimeParseLocalEndUnix(nowTime.AddDate(0, 0, 1).Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
 	var count int64
 	neckRingEstrusList := make([]*model.NeckRingEstrusWarning, 0)
-	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrusWarning).TableName())).
-		Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
-		Where("b.last_mating_at < UNIX_TIMESTAMP(a.date_time)").
-		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
-		Where("b.is_not_mating = ?", pasturePb.IsShow_No).
-		Where("a.level >= ?", pasturePb.EstrusLevel_Low).
-		Where("a.pasture_id = ?", userModel.AppPasture.Id).
-		Where("a.date_time BETWEEN ? AND ?", startTime, entTime).
-		Where(s.DB.Where("b.last_mating_at < UNIX_TIMESTAMP(a.first_time)").
-			Or(s.DB.Where("b.last_mating_at = ?", 0).
-				Where("b.calving_age > ?", systemBasic.MinValue).
-				Or("b.lact = ?", 0))).
-		Where("a.is_show = ?", pasturePb.IsShow_Ok)
+	var pref *gorm.DB
+	switch req.Kind {
+	case "estrus":
+		nowTime := time.Now()
+		startTime := time.Unix(util.TimeParseLocalUnix(nowTime.Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
+		entTime := time.Unix(util.TimeParseLocalEndUnix(nowTime.AddDate(0, 0, 1).Format(model.LayoutDate2)), 0).Format(model.LayoutTime)
+		systemBasic, err := s.FindSystemBasic(ctx, userModel.AppPasture.Id, model.EstrusWaringDays)
+		if err != nil {
+			return nil, xerr.WithStack(err)
+		}
+
+		pref = s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrusWarning).TableName())).
+			Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
+			Where("b.last_mating_at < UNIX_TIMESTAMP(a.date_time)").
+			Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
+			Where("b.is_not_mating = ?", pasturePb.IsShow_No).
+			Where("a.level >= ?", pasturePb.EstrusLevel_Low).
+			Where("a.pasture_id = ?", userModel.AppPasture.Id).
+			Where("a.date_time BETWEEN ? AND ?", startTime, entTime).
+			Where(s.DB.Where("b.last_mating_at < UNIX_TIMESTAMP(a.first_time)").
+				Or(s.DB.Where("b.last_mating_at = ?", 0).
+					Where("b.calving_age > ?", systemBasic.MinValue).
+					Or("b.lact = ?", 0))).
+			Where("a.is_show = ?", pasturePb.IsShow_Ok)
+	case "abortion":
+		pref = s.DB.Table(fmt.Sprintf("%s as a", new(model.NeckRingEstrusWarning).TableName())).
+			Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
+			Where("b.pregnancy_age BETWEEN ? AND ?", 1, 260).
+			Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
+			Where("b.is_pregnant = ?", pasturePb.IsShow_Ok).
+			Where("a.level >= ?", pasturePb.EstrusLevel_Middle).
+			Where("a.pasture_id = ?", userModel.AppPasture.Id).
+			Where("a.is_show = ?", pasturePb.IsShow_Ok)
+	}
 
 	if len(req.EarNumber) > 0 {
 		pref.Where("a.ear_number = ?", req.EarNumber)