Browse Source

cowLog: 牛只事件日志

Yi 4 months ago
parent
commit
c0afe132f4

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20241223072631-d6d7cc8fef31
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20241224084901-9a0b78705dd6
 	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

+ 2 - 0
go.sum

@@ -78,6 +78,8 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20241223063242-cbd9ca4ef527 h1:bwLz4q7u
 gitee.com/xuyiping_admin/go_proto v0.0.0-20241223063242-cbd9ca4ef527/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20241223072631-d6d7cc8fef31 h1:KSfnFVKSlAyC7A6jCWAJkvAGxq/IVPsezl5ss3CqPMw=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20241223072631-d6d7cc8fef31/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241224084901-9a0b78705dd6 h1:dw2s50DrIIf7wOxOcIspSRFKNgvadWMgrEZZNpbO9Ho=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241224084901-9a0b78705dd6/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=

+ 18 - 22
model/calving_calf.go

@@ -26,27 +26,23 @@ func (e *CalvingCalf) TableName() string {
 	return "calving_calf"
 }
 
-func NewEventCalvingCalf(motherId, calvingId int64, req *pasturePb.EventCalving) []*CalvingCalf {
-	calvingCalfList := make([]*CalvingCalf, 0)
-	for _, v := range req.CalfItemList {
-		isAdoption := v.IsAdoption
-		if v.IsLive == pasturePb.IsShow_No {
-			isAdoption = pasturePb.IsShow_No
-		}
-		calvingCalfList = append(calvingCalfList, &CalvingCalf{
-			EarNumber:     v.EarNumber,
-			CalvingId:     calvingId,
-			CowId:         int64(v.CowId),
-			BirthAt:       int64(req.CalvingAt),
-			PenId:         v.PenId,
-			BirthWeight:   int64(v.Weight * 1000),
-			CurrentWeight: int64(v.Weight * 1000),
-			Sex:           v.Sex,
-			MotherId:      motherId,
-			Remarks:       v.Remarks,
-			IsAdoption:    isAdoption,
-			IsLive:        v.IsLive,
-		})
+func NewEventCalvingCalf(motherId, calvingId, calvingAt int64, req *pasturePb.CalfItem) *CalvingCalf {
+	isAdoption := req.IsAdoption
+	if req.IsLive == pasturePb.IsShow_No {
+		isAdoption = pasturePb.IsShow_No
+	}
+	return &CalvingCalf{
+		EarNumber:     req.EarNumber,
+		CalvingId:     calvingId,
+		CowId:         int64(req.CowId),
+		BirthAt:       calvingAt,
+		PenId:         req.PenId,
+		BirthWeight:   int64(req.Weight * 1000),
+		CurrentWeight: int64(req.Weight * 1000),
+		Sex:           req.Sex,
+		MotherId:      motherId,
+		Remarks:       req.Remarks,
+		IsAdoption:    isAdoption,
+		IsLive:        req.IsLive,
 	}
-	return calvingCalfList
 }

+ 41 - 22
model/event_calving.go

@@ -8,34 +8,53 @@ import (
 )
 
 type EventCalving struct {
-	Id             int64                         `json:"id"`
-	CowId          int64                         `json:"cowId"`
-	CowType        pasturePb.CowType_Kind        `json:"cowType"`
-	CowKind        pasturePb.CowKind_Kind        `json:"cowKind"`
-	EarNumber      string                        `json:"earNumber"`
-	Lact           int32                         `json:"lact"`
-	DayAge         int32                         `json:"dayAge"`
-	PlanDay        int64                         `json:"planDay"`
-	RealityDay     int64                         `json:"realityDay"`
-	EndDay         int64                         `json:"endDay"`
-	Status         pasturePb.IsShow_Kind         `json:"status"`
-	PenId          int32                         `json:"penId"`
-	ChildNumber    int8                          `json:"childNumber"`
-	BullNumber     string                        `json:"bullNumber"`
-	PregnancyAge   int64                         `json:"pregnancyAge"`
-	CalvingLevel   pasturePb.CalvingLevel_Kind   `json:"calvingLevel"`
-	OperationId    int64                         `json:"operationId"`
-	OperationName  string                        `json:"operationName"`
-	DystociaReason pasturePb.DystociaReason_Kind `json:"dystociaReason"`
-	Remarks        string                        `json:"remarks"`
-	CreatedAt      int64                         `json:"created_at"`
-	UpdatedAt      int64                         `json:"updated_at"`
+	Id                   int64                         `json:"id"`
+	CowId                int64                         `json:"cowId"`
+	CowType              pasturePb.CowType_Kind        `json:"cowType"`
+	CowKind              pasturePb.CowKind_Kind        `json:"cowKind"`
+	EarNumber            string                        `json:"earNumber"`
+	Lact                 int32                         `json:"lact"`
+	DayAge               int32                         `json:"dayAge"`
+	PlanDay              int64                         `json:"planDay"`
+	RealityDay           int64                         `json:"realityDay"`
+	EndDay               int64                         `json:"endDay"`
+	Status               pasturePb.IsShow_Kind         `json:"status"`
+	PenId                int32                         `json:"penId"`
+	ChildNumber          int32                         `json:"childNumber"`
+	BullNumber           string                        `json:"bullNumber"`
+	PregnancyAge         int32                         `json:"pregnancyAge"`
+	CalvingLevel         pasturePb.CalvingLevel_Kind   `json:"calvingLevel"`
+	OperationId          int64                         `json:"operationId"`
+	OperationName        string                        `json:"operationName"`
+	DystociaReason       pasturePb.DystociaReason_Kind `json:"dystociaReason"`
+	IsInducingChildbirth pasturePb.IsShow_Kind         `json:"isInducingChildbirth"`
+	Remarks              string                        `json:"remarks"`
+	CreatedAt            int64                         `json:"created_at"`
+	UpdatedAt            int64                         `json:"updated_at"`
 }
 
 func (e *EventCalving) TableName() string {
 	return "event_calving"
 }
 
+func (e *EventCalving) Update(operationUser *SystemUser, req *pasturePb.EventCalving, cow *Cow) {
+	if operationUser != nil {
+		e.OperationId = operationUser.Id
+		e.OperationName = operationUser.Name
+	}
+	e.RealityDay = int64(req.CalvingAt)
+	e.DayAge = cow.DayAge
+	e.PregnancyAge = cow.PregnancyAge
+	e.CalvingLevel = req.CalvingLevel
+	e.BullNumber = cow.LastBullNumber
+	e.ChildNumber = req.ChildNumber
+	e.Status = pasturePb.IsShow_Ok
+	e.PenId = cow.PenId
+	e.IsInducingChildbirth = req.IsInducingChildbirth
+	e.Remarks = req.Remarks
+	e.DystociaReason = req.DystociaReason
+}
+
 func NewEventCalving(cow *Cow) *EventCalving {
 	return &EventCalving{
 		CowId:      cow.Id,

+ 18 - 9
model/event_cow_log.go

@@ -2,7 +2,6 @@ package model
 
 import (
 	"fmt"
-	"time"
 
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 )
@@ -21,7 +20,7 @@ type EventCowLog struct {
 	EventType        pasturePb.EventType_Kind `json:"eventType"`
 	EventTypeName    string                   `json:"eventTypeName"`
 	EventDescription string                   `json:"eventDescription"`
-	OperationId      int64                    `json:"operationId"`
+	OperationId      int32                    `json:"operationId"`
 	OperationName    string                   `json:"operationName"`
 	EventAt          int64                    `json:"eventAt"`
 	Remarks          string                   `json:"remarks"`
@@ -38,14 +37,24 @@ func (e *EventCowLog) TableName() string {
 	return fmt.Sprintf("%s_%04d", e.UnShardTableName(), e.CowId%ShardTableNumber)
 }
 
-func NewCowEventLog(
+type EventCowLogModel struct {
+	Cow         *Cow
+	EventType   pasturePb.EventType_Kind
+	Operation   *SystemUser
+	Description string
+	EventAt     int64
+}
+
+func NewEventCowLog(
 	cow *Cow,
 	penMap map[int32]*Pen,
 	cowType map[pasturePb.CowType_Kind]string,
 	eventType pasturePb.EventType_Kind,
-	eventTypeMap map[pasturePb.EventType_Kind]string,
-	operation *SystemUser,
+	eventTypeName string,
+	operationId int32,
+	operationName string,
 	description string,
+	eventAt int64,
 ) *EventCowLog {
 	penName := ""
 	if pen, ok := penMap[cow.PenId]; ok {
@@ -60,10 +69,10 @@ func NewCowEventLog(
 		CowType:          cow.CowType,
 		CowTypeName:      cowType[cow.CowType],
 		EventType:        eventType,
-		EventTypeName:    eventTypeMap[eventType],
+		EventTypeName:    eventTypeName,
 		EventDescription: description,
-		OperationId:      operation.Id,
-		OperationName:    operation.Name,
-		EventAt:          time.Now().Unix(),
+		OperationId:      operationId,
+		OperationName:    operationName,
+		EventAt:          eventAt,
 	}
 }

+ 24 - 0
module/backend/config_data_other.go

@@ -476,6 +476,30 @@ func (s *StoreEntry) EventTypeEnumList(isAll string) []*pasturePb.ConfigOptionsL
 		Value:    int32(pasturePb.EventType_Mating),
 		Label:    "配种",
 		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Birth),
+		Label:    "出生",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Death),
+		Label:    "死亡",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Transfer_Out),
+		Label:    "转出",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Transfer_In),
+		Label:    "转入",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Out),
+		Label:    "淘汰",
+		Disabled: true,
+	}, &pasturePb.ConfigOptionsList{
+		Value:    int32(pasturePb.EventType_Immunication),
+		Label:    "免疫",
+		Disabled: true,
 	})
 	return configOptions
 }

+ 24 - 0
module/backend/enum_map.go

@@ -230,3 +230,27 @@ func (s *StoreEntry) SameTimeTypeMap() map[pasturePb.SameTimeType_Kind]string {
 	}
 	return res
 }
+
+func (s *StoreEntry) EventTypeMap() map[pasturePb.EventType_Kind]string {
+	res := make(map[pasturePb.EventType_Kind]string)
+	for _, v := range s.EventTypeEnumList("") {
+		res[pasturePb.EventType_Kind(v.Value)] = v.Label
+	}
+	return res
+}
+
+func (s *StoreEntry) CalvingLevelMap() map[pasturePb.CalvingLevel_Kind]string {
+	res := make(map[pasturePb.CalvingLevel_Kind]string)
+	for _, v := range s.CalvingLevelEnumList("") {
+		res[pasturePb.CalvingLevel_Kind(v.Value)] = v.Label
+	}
+	return res
+}
+
+func (s *StoreEntry) DystociaReasonMap() map[pasturePb.DystociaReason_Kind]string {
+	res := make(map[pasturePb.DystociaReason_Kind]string)
+	for _, v := range s.DystociaReasonEnumList("") {
+		res[pasturePb.DystociaReason_Kind(v.Value)] = v.Label
+	}
+	return res
+}

+ 1 - 0
module/backend/enum_options.go

@@ -194,6 +194,7 @@ func (s *StoreEntry) SystemBaseConfigOptions(ctx context.Context, optionsName, i
 		"auditStatus":                s.AuditStatusEnumList,
 		"pregnantCheckName":          s.PregnantCheckNameEnumList,
 		"unMatingReasons":            s.UnMatingReasonsEnumList,
+		"evenType":                   s.EventTypeEnumList,
 	}
 
 	getConfigFunc, ok := getConfigFuncMap[optionsName]

+ 0 - 8
module/backend/event_base.go

@@ -13,14 +13,6 @@ import (
 	"gorm.io/gorm"
 )
 
-func (s *StoreEntry) EventTemplate(ctx context.Context, req *pasturePb.SearchEventRequest) {
-
-}
-
-func (s *StoreEntry) CreateEventTemplate(ctx context.Context, req *pasturePb.SearchEventRequest) *pasturePb.EventData {
-	return nil
-}
-
 func (s *StoreEntry) ParseCowIds(ctx context.Context, cowIds string) ([]*model.Cow, error) {
 	if len(cowIds) == 0 {
 		return nil, xerr.Custom("cow id is required")

+ 32 - 29
module/backend/event_breed.go

@@ -60,21 +60,29 @@ func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEvent
 	}, nil
 }
 
-func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) error {
-	if len(req.CowId) <= 0 {
+func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) (err error) {
+	cow, err := s.GetCowInfoByCowId(ctx, int64(req.CowId))
+	if err != nil {
+		zaplog.Error("CalvingCreate", zap.Any("cow_id", req.CowId), zap.Any("err", err))
 		return xerr.Custom("请选择相关牛只")
 	}
 
-	cowList, err := s.ParseCowIds(ctx, req.CowId)
+	operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
 	if err != nil {
-		return xerr.WithStack(err)
+		return xerr.Customf("获取操作人员信息失败: %s", err.Error())
 	}
+	req.OperationName = operationUser.Name
 
-	if len(cowList) <= 0 {
-		return xerr.Custom("请选择相关牛只")
-	}
+	// 记录牛只事件日志
+	defer func() {
+		if err == nil {
+			// 母牛事件日志
+			cowLogs := s.SubmitEventLog(ctx, cow, pasturePb.EventType_Calving, req)
+			s.DB.Table(cowLogs.TableName()).Create(cowLogs)
+			// todo 犊牛的
+		}
+	}()
 
-	cow := cowList[0]
 	newEventCalving := &model.EventCalving{}
 	if err = s.DB.Model(new(model.EventCalving)).
 		Where("cow_id = ?", cow.Id).
@@ -82,44 +90,39 @@ func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalv
 		First(newEventCalving).Error; err != nil {
 		return xerr.Custom("该母牛信息不存在")
 	}
-
 	if err = s.DB.Transaction(func(tx *gorm.DB) error {
-		// 母牛信息
+		// 更新产犊事件表
+		newEventCalving.Update(operationUser, req, cow)
 		if err = tx.Model(new(model.EventCalving)).
 			Where("id = ?", newEventCalving.Id).
-			Updates(map[string]interface{}{
-				"reality_day":   int64(req.CalvingAt),
-				"day_age":       cow.DayAge,
-				"lact":          cow.Lact + 1,
-				"pregnancy_age": cow.PregnancyAge,
-				"calving_level": req.CalvingLevel,
-				"bull_number":   cow.LastBullNumber,
-				"child_number":  len(req.CalfItemList),
-			}).
-			Error; err != nil {
+			Updates(newEventCalving).Error; err != nil {
 			return xerr.WithStack(err)
 		}
-		// 犊牛信息
-		newCalvingCalfList := model.NewEventCalvingCalf(cow.Id, newEventCalving.Id, req)
-		for _, v := range newCalvingCalfList {
+
+		for _, v := range req.CalfItemList {
 			if v.IsLive == pasturePb.IsShow_No || v.IsAdoption == pasturePb.IsShow_No {
 				continue
 			}
+			// 犊牛信息
+			newCalvingCalf := model.NewEventCalvingCalf(int64(req.CowId), newEventCalving.Id, int64(req.CalvingAt), v)
 			// 留养犊牛
-			newCow := model.NewCalfCow(cow.Id, cow.LastBullNumber, v)
+			newCow := model.NewCalfCow(cow.Id, cow.LastBullNumber, newCalvingCalf)
 			if err = tx.Create(newCow).Error; err != nil {
 				return xerr.WithStack(err)
 			}
-			v.CowId = newCow.Id
-		}
-		if err = tx.Create(newCalvingCalfList).Error; err != nil {
-			return xerr.WithStack(err)
+
+			v.CowId = int32(newCow.Id)
+			if err = tx.Create(newCalvingCalf).Error; err != nil {
+				return xerr.WithStack(err)
+			}
 		}
 
+		// 更新母牛信息
 		if err = tx.Model(new(model.Cow)).Where("id = ?", cow.Id).
 			Updates(map[string]interface{}{
-				"calving_age":     0,
+				"calving_age":     int32(time.Now().Sub(time.Unix(int64(req.CalvingAt), 0)).Hours() / 24),
 				"mating_times":    0,
+				"pregnancy_age":   0,
 				"lact":            cow.Lact + 1,
 				"breed_status":    pasturePb.BreedStatus_Calving,
 				"is_pregnant":     pasturePb.IsShow_No,

+ 45 - 0
module/backend/event_breed_more.go

@@ -252,3 +252,48 @@ func (s *StoreEntry) AbortionList(
 		},
 	}, nil
 }
+
+func (s *StoreEntry) SubmitEventLog(ctx context.Context, cow *model.Cow, eventType pasturePb.EventType_Kind, req interface{}) *model.EventCowLog {
+	var (
+		desc          = ""
+		eventTypeName = s.EventTypeMap()[eventType]
+		eventAt       = int64(0)
+		penMap        = s.PenMap(ctx)
+		cowTypeMap    = s.CowTypeMap()
+	)
+
+	switch eventType {
+	case pasturePb.EventType_Enter:
+	case pasturePb.EventType_Transfer_Ben:
+	case pasturePb.EventType_Body_Score:
+	case pasturePb.EventType_Pregnancy_Check:
+	case pasturePb.EventType_Estrus:
+	case pasturePb.EventType_Calving:
+		data := req.(*pasturePb.EventCalving)
+		eventAt = int64(data.CalvingAt)
+		desc = fmt.Sprintf("怀孕天数:%d;难产等级: %s;产子数量: %d", cow.PregnancyAge, s.CalvingLevelMap()[data.CalvingLevel], data.ChildNumber)
+		for _, v := range data.CalfItemList {
+			if v.CowId > 0 {
+				desc += fmt.Sprintf(";犊牛ID: %d; 出生体重: %f", v.CowId, v.Weight)
+			}
+		}
+		if data.IsInducingChildbirth == pasturePb.IsShow_Ok {
+			desc += fmt.Sprintf("; 难产原因: %s", s.DystociaReasonMap()[data.DystociaReason])
+		}
+		newEventCowLog := model.NewEventCowLog(cow, penMap, cowTypeMap, eventType, eventTypeName, data.OperationId, data.OperationName, desc, eventAt)
+		return newEventCowLog
+	case pasturePb.EventType_Seme_Time:
+	case pasturePb.EventType_Mating:
+	case pasturePb.EventType_Birth:
+		data := req.(*pasturePb.EventCalving)
+		eventAt = int64(data.CalvingAt)
+		desc = fmt.Sprintf("出生体重: %dKG;", data.CalvingAt, data.ChildNumber)
+
+	case pasturePb.EventType_Death:
+	case pasturePb.EventType_Transfer_Out:
+	case pasturePb.EventType_Transfer_In:
+	case pasturePb.EventType_Out:
+	case pasturePb.EventType_Immunication:
+	}
+	return nil
+}

+ 3 - 0
module/backend/interface.go

@@ -195,6 +195,9 @@ type EventService interface {
 	CowDiseaseTreatmentDetail(ctx context.Context, req *pasturePb.EventCowTreatmentDetailRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowTreatmentDetailResponse, error)
 	// CowDiseaseCurable 治愈
 	CowDiseaseCurable(ctx context.Context, req *pasturePb.EventCowCurableRequest) error
+
+	// SubmitEventLog 记录提交事件结果日志
+	SubmitEventLog(ctx context.Context, cow *model.Cow, eventType pasturePb.EventType_Kind, req interface{}) []*model.EventCowLog
 }
 
 //go:generate mockgen -destination mock/CowService.go -package kptservicemock kpt-pasture/module/backend CowService

+ 0 - 11
module/backend/sql.go

@@ -100,17 +100,6 @@ func (s *StoreEntry) PenMap(ctx context.Context) map[int32]*model.Pen {
 	return penMap
 }
 
-func (s *StoreEntry) GetCowList(ctx context.Context, cowIds []int64) ([]*model.Cow, error) {
-	cowList := make([]*model.Cow, 0)
-	if err := s.DB.Model(new(model.Cow)).
-		Where("id IN ?", cowIds).
-		Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
-		Find(&cowList).Error; err != nil {
-		return nil, xerr.WithStack(err)
-	}
-	return cowList, nil
-}
-
 func (s *StoreEntry) GetCowInfoByCowId(ctx context.Context, cowId int64) (*model.Cow, error) {
 	cowData := &model.Cow{Id: cowId}
 	if err := s.DB.Model(new(model.Cow)).