Browse Source

items: 清单业务调整

Yi 4 months ago
parent
commit
a76530c090

+ 2 - 4
go.mod

@@ -3,8 +3,8 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20241106025935-173da25922b3
-	gitee.com/xuyiping_admin/pkg v0.0.0-20241029095841-aa1fe89b557a
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20241108091551-7dc4ce1f1dd1
+	gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eko/gocache v1.1.0
 	github.com/getsentry/sentry-go v0.23.0
@@ -30,8 +30,6 @@ require (
 	gorm.io/gorm v1.25.2
 )
 
-require gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
-
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect

+ 8 - 22
go.sum

@@ -36,26 +36,14 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241030093930-85784b846ab4 h1:7GYTs67byos3e1BIdGMjJM8qlWNpho5LQovOCcrNVxo=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241030093930-85784b846ab4/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241101012151-bbf157c372ed h1:w4R1HdbIkcHhRunjPTPT8PPk4TybANIBy4OuC89Na4c=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241101012151-bbf157c372ed/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241104023746-2df64dda0323 h1:lA3XTnnhg52VFLDM/typUJCypirbD7TmnMyIlWk5B70=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241104023746-2df64dda0323/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241104025928-e62a2d8db6d6 h1:NqH5P8Sgm38m9RFb3cQnKIsX0qZqXefJrC7JjJUTB2g=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241104025928-e62a2d8db6d6/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241105012623-f1bbf6690530 h1:XYf4/IuGdKl5h006Du829JTTO9YP8admhxnB20SogZM=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241105012623-f1bbf6690530/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241105074912-bc99391ff5e0 h1:YDGgqXp0ehW+aNEmf/vL2b6MWLp1hGbLvsVXe2Q7j2s=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241105074912-bc99391ff5e0/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106022913-38a1080b12ee h1:rIiYzv6+miuBQErl20p9i1h0XcHFxLJLFWXEZAmJr6o=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106022913-38a1080b12ee/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106023724-b2d5b980b9ea h1:4Q2ydO/Q4ydh9CDNiP7pUQoLiaOagrxkGOtMIhQAa7k=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106023724-b2d5b980b9ea/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106025935-173da25922b3 h1:BfF/ElvARXoyn7hykF1tjzu9kCkW8SvMcZNPMj31qpQ=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20241106025935-173da25922b3/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
-gitee.com/xuyiping_admin/pkg v0.0.0-20241029095841-aa1fe89b557a h1:z6Pp4HmdcxEZ43avmbFoE3vwEYcWnIefqEEZZWCHfek=
-gitee.com/xuyiping_admin/pkg v0.0.0-20241029095841-aa1fe89b557a/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108021844-f28903a01f3a h1:bL18y2fYHv3Ml+7aika3uIDrCVD8BkwiKWy1+I+jLn4=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108021844-f28903a01f3a/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108073749-0d4badc06e82 h1:p0dlGbsRggDKk1kuWHW915CZpV3AbJFH/tPJNSF/nS0=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108073749-0d4badc06e82/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108091551-7dc4ce1f1dd1 h1:3RbPPejz79D12OMSuUgm1z5Ci15hGRfXigUE5lZkGz8=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20241108091551-7dc4ce1f1dd1/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=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
@@ -1038,8 +1026,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
 gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
-gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=

+ 2 - 1
http/handler/analysis/analysis.go

@@ -274,5 +274,6 @@ func MultiFactorInfantSurvivalRate(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	ginutil.JSONResp(c, res)
+
+	c.JSON(http.StatusOK, res)
 }

+ 100 - 0
http/handler/work/calendar.go

@@ -82,3 +82,103 @@ func CalendarToDoList(c *gin.Context) {
 	}
 	c.JSON(http.StatusOK, res)
 }
+
+func ImmunizationItems(c *gin.Context) {
+	var req pasturePb.ItemsRequest
+	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.Dependency(c).StoreEventHub.OpsService.ImmunisationCowList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}
+
+func SameTimeCowList(c *gin.Context) {
+	var req pasturePb.ItemsRequest
+	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.Dependency(c).StoreEventHub.OpsService.SameTimeCowList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}
+
+func PregnancyCheckCowList(c *gin.Context) {
+	var req pasturePb.ItemsRequest
+	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.Dependency(c).StoreEventHub.OpsService.PregnancyCheckCowList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}
+
+func WeaningCowList(c *gin.Context) {
+	var req pasturePb.ItemsRequest
+	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.Dependency(c).StoreEventHub.OpsService.WeaningCowList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}
+
+func MatingCowList(c *gin.Context) {
+	var req pasturePb.ItemsRequest
+	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.Dependency(c).StoreEventHub.OpsService.MatingCowList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}

+ 18 - 6
http/middleware/cors.go

@@ -1,10 +1,12 @@
 package middleware
 
 import (
+	"bytes"
+	"io"
 	"io/ioutil"
 	"net/http"
-	"path/filepath"
 	"runtime"
+	"strings"
 
 	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
 
@@ -48,13 +50,22 @@ func CORS(configs ...cors.Config) gin.HandlerFunc {
 				body, _ := ioutil.ReadAll(c.Request.Body)
 
 				// 获取 panic 发生的位置
-				pc, file, line, ok := runtime.Caller(1)
+				pc, file, line, ok := runtime.Caller(2)
 				funcName := ""
 				if ok {
-					funcName := runtime.FuncForPC(pc).Name()
+					fn := runtime.FuncForPC(pc).Name()
 					// 去除包路径,只保留函数名
-					funcName = filepath.Base(funcName)
-					file = filepath.Base(file)
+					/*funcName = filepath.Base(fn)
+					file = filepath.Base(file)*/
+					parts := strings.Split(fn, "/")
+					if len(parts) > 0 {
+						lastPart := parts[len(parts)-1]
+						parts = strings.Split(lastPart, ".")
+						if len(parts) > 0 {
+							funcName = parts[len(parts)-1]
+						}
+					}
+					file = strings.TrimPrefix(file, c.Request.Context().Value(gin.ContextKey).(string)+"/") // 尝试去除项目路径前缀(可选)
 				}
 				zaplog.Error("cors",
 					zap.Any("recover", err),
@@ -65,9 +76,10 @@ func CORS(configs ...cors.Config) gin.HandlerFunc {
 					zap.Any("func", funcName),
 					zap.Any("request", string(body)),
 				)
+				c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
+				c.JSON(http.StatusInternalServerError, gin.H{"err": "Internal Server Error"})
 			}
 		}()
-
 		c.Next()
 	}
 }

+ 6 - 0
http/route/work_order.go

@@ -22,5 +22,11 @@ func WorkOrderAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		workRoute.POST("/calendar/detail", work.CalendarTableDetail)
 		workRoute.POST("/calendar/todo/list", work.CalendarToDoList)
 
+		// 清单相关接口
+		workRoute.POST("/same/time/items", work.SameTimeCowList)
+		workRoute.POST("/immunization/items", work.ImmunizationItems)
+		workRoute.POST("/pregnancy/check/items", work.PregnancyCheckCowList)
+		workRoute.POST("/weaning/items", work.WeaningCowList)
+		workRoute.POST("/mating/items", work.MatingCowList)
 	}
 }

+ 0 - 14
model/calendar.go

@@ -62,17 +62,3 @@ func (c CalendarSlice) ToPB() []*pasturePb.Calendar {
 	}
 	return res
 }
-
-type CalendarResponse struct {
-	Code    int32         `json:"code"`
-	Message string        `json:"message"`
-	Data    *CalendarData `json:"data"`
-}
-
-type CalendarData struct {
-	Total    int32       `json:"total"`
-	Page     int32       `json:"page"`
-	PageSize int32       `json:"pageSize"`
-	Header   interface{} `json:"header"`
-	List     interface{} `json:"list"`
-}

+ 0 - 66
model/cow_immunization_plan.go

@@ -1,66 +0,0 @@
-package model
-
-import (
-	"time"
-
-	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
-)
-
-type CowImmunizationPlan struct {
-	Id                   int64                 `json:"id"`
-	CowId                int64                 `json:"cowId"`
-	ImmunizationPlanId   int64                 `json:"immunizationPlanId"`
-	ImmunizationPlanName string                `json:"immunizationPlanName"`
-	PlanDay              string                `json:"planDay"`
-	RealityDay           string                `json:"realityDay"`
-	Status               pasturePb.IsShow_Kind `json:"status"`
-	OperationId          int64                 `json:"operationId"`
-	OperationName        string                `json:"operationName"`
-	DrugsId              int64                 `json:"drugsId"`
-	Unit                 pasturePb.Unit_Kind   `json:"unit"`
-	Usage                string                `json:"usage"`
-	Remarks              string                `json:"remarks"`
-	CreateAt             int64                 `json:"createAt"`
-	UpdateAt             int64                 `json:"updateAt"`
-}
-
-func (c *CowImmunizationPlan) TableName() string {
-	return "cow_immunization_plan"
-}
-
-func NewCowImmunizationPlan(cowId int64, immunizationPlan *ImmunizationPlan) *CowImmunizationPlan {
-	return &CowImmunizationPlan{
-		CowId:                cowId,
-		ImmunizationPlanId:   immunizationPlan.Id,
-		ImmunizationPlanName: immunizationPlan.Name,
-		PlanDay:              time.Now().Format(LayoutDate2),
-		Status:               pasturePb.IsShow_No,
-	}
-}
-
-func NewCowImmunizationPlanList(cowList []*Cow, immunizationPlan *ImmunizationPlan) []*CowImmunizationPlan {
-	cowImmunizationPlanList := make([]*CowImmunizationPlan, len(cowList))
-	for i, v := range cowList {
-		cowImmunizationPlanList[i] = NewCowImmunizationPlan(v.Id, immunizationPlan)
-	}
-	return cowImmunizationPlanList
-}
-
-type ImmunizationPlanCowSlice []*CowImmunizationPlan
-
-type ImmunizationCalendarHeader struct {
-	Id                   string `json:"id"`
-	CowId                string `json:"cowId"`
-	PlanStartTime        string `json:"planStartTime"`
-	ImmunizationPlanId   string `json:"immunizationPlanId"`
-	ImmunizationPlanName string `json:"immunizationPlanName"`
-	Status               string `json:"status"`
-}
-
-func (I ImmunizationPlanCowSlice) ToPB() []*CowImmunizationPlan {
-	res := make([]*CowImmunizationPlan, len(I))
-	for i, v := range I {
-		res[i] = v
-	}
-	return res
-}

+ 28 - 37
model/event_cow_same_time.go

@@ -1,14 +1,13 @@
 package model
 
 import (
-	"fmt"
-
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 )
 
 type EventCowSameTime struct {
 	Id            int64                       `json:"id"`
 	CowId         int64                       `json:"cowId"`
+	CowType       pasturePb.CowType_Kind      `json:"cowType"`
 	PenId         int32                       `json:"penId"`
 	PenName       string                      `json:"penName"`
 	Lact          int32                       `json:"lact"`
@@ -31,37 +30,28 @@ func (s *EventCowSameTime) TableName() string {
 	return "event_cow_same_time"
 }
 
-func NewCowSameTimeDetailList(cowList []*Cow, sameTimeId int64, planTime int64, sameTimeType pasturePb.SameTimeType_Kind) []*EventCowSameTime {
+func NewEventCowSameTime(cow *Cow, planTime int64, sameTimeId int64, sameTimeType pasturePb.SameTimeType_Kind) *EventCowSameTime {
+	return &EventCowSameTime{
+		CowId:        cow.Id,
+		Lact:         cow.Lact,
+		CowType:      cow.CowType,
+		PenId:        cow.PenId,
+		SameTimeId:   sameTimeId,
+		SameTimeType: sameTimeType,
+		Status:       pasturePb.IsShow_No,
+		PlanDay:      planTime,
+		EndDay:       planTime,
+	}
+}
+
+func NewEventCowSameTimeList(cowList []*Cow, sameTimeId int64, planTime int64, sameTimeType pasturePb.SameTimeType_Kind) []*EventCowSameTime {
 	res := make([]*EventCowSameTime, len(cowList))
 	for i, cow := range cowList {
-		res[i] = &EventCowSameTime{
-			CowId:        cow.Id,
-			Lact:         cow.Lact,
-			PenId:        cow.PenId,
-			SameTimeId:   sameTimeId,
-			SameTimeType: sameTimeType,
-			Status:       pasturePb.IsShow_No,
-			PlanDay:      planTime,
-			EndDay:       planTime,
-		}
+		res[i] = NewEventCowSameTime(cow, planTime, sameTimeId, sameTimeType)
 	}
-
 	return res
 }
 
-type SameTimeHeader struct {
-	Id              string `json:"id"`
-	CowId           string `json:"cowId"`
-	CowTypeName     string `json:"cowTypeName"`
-	BreedStatusName string `json:"breedStatusName"`
-	PenName         string `json:"penName"`
-	Lact            string `json:"lact"`
-	CalvingAge      string `json:"calvingAge"`
-	AbortionAge     string `json:"abortionAge"`
-	DayAge          string `json:"dayAge"`
-	Status          string `json:"status"`
-}
-
 type SameTimeBody struct {
 	Id              int64                      `json:"id"`
 	CowId           int64                      `json:"cowId"`
@@ -81,20 +71,21 @@ type SameTimeBody struct {
 type SameTimeBodySlice []*SameTimeBody
 
 func (s SameTimeBodySlice) ToPB(
-	cowTypeMap map[pasturePb.CowType_Kind]string,
 	breedStatusMap map[pasturePb.BreedStatus_Kind]string,
 	penMap map[int32]*Pen,
-) []*SameTimeBody {
-	res := make([]*SameTimeBody, len(s))
+) []*pasturePb.SameTimeItems {
+	res := make([]*pasturePb.SameTimeItems, len(s))
 	for i, v := range s {
-		res[i] = &SameTimeBody{
-			Id:              v.Id,
-			CowId:           v.CowId,
-			CowType:         v.CowType,
-			CowTypeName:     cowTypeMap[v.CowType],
+		penName := ""
+		if pen, ok := penMap[v.PenId]; ok {
+			penName = pen.Name
+		}
+		res[i] = &pasturePb.SameTimeItems{
+			Id:              int32(v.Id),
+			CowId:           int32(v.CowId),
 			BreedStatus:     v.BreedStatus,
 			BreedStatusName: breedStatusMap[v.BreedStatus],
-			PenName:         penMap[v.PenId].Name,
+			PenName:         penName,
 			PenId:           v.PenId,
 			Lact:            v.Lact,
 			CalvingAge:      v.CalvingAge,
@@ -112,7 +103,7 @@ func (s EventCowSameTimeSlice) ToPB() []*pasturePb.EventSameTime {
 	res := make([]*pasturePb.EventSameTime, len(s))
 	for i, v := range s {
 		res[i] = &pasturePb.EventSameTime{
-			CowId:            fmt.Sprintf("%d", v.CowId),
+			CowId:            int32(v.CowId),
 			PenId:            v.PenId,
 			DrugsId:          int32(v.DrugsId),
 			Usage:            v.Usage,

+ 99 - 0
model/event_immunization_plan.go

@@ -0,0 +1,99 @@
+package model
+
+import (
+	"kpt-pasture/util"
+	"time"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+)
+
+type EventImmunizationPlan struct {
+	Id            int64                  `json:"id"`
+	CowId         int64                  `json:"cowId"`
+	Lact          int32                  `json:"lact"`
+	DayAge        int32                  `json:"dayAge"`
+	CowType       pasturePb.CowType_Kind `json:"cowType"`
+	CowKind       pasturePb.CowKind_Kind `json:"cowKind"`
+	PenId         int32                  `json:"penId"`
+	PenName       string                 `json:"penName"`
+	PlanId        int64                  `json:"planId"`
+	PlanName      string                 `json:"planName"`
+	PlanDay       int64                  `json:"planDay"`
+	RealityDay    int64                  `json:"realityDay"`
+	EndDay        int64                  `json:"endDay"`
+	Status        pasturePb.IsShow_Kind  `json:"status"`
+	OperationId   int64                  `json:"operationId"`
+	OperationName string                 `json:"operationName"`
+	DrugsId       int64                  `json:"drugsId"`
+	DrugsName     string                 `json:"drugsName"`
+	Unit          pasturePb.Unit_Kind    `json:"unit"`
+	UnitName      string                 `json:"unitName"`
+	Usage         int32                  `json:"usage"`
+	Remarks       string                 `json:"remarks"`
+	CreateAt      int64                  `json:"createAt"`
+	UpdateAt      int64                  `json:"updateAt"`
+}
+
+func (c *EventImmunizationPlan) TableName() string {
+	return "event_immunization_plan"
+}
+
+func NewCowImmunizationPlan(cow *Cow, pen *Pen, immunizationPlan *ImmunizationPlan) *EventImmunizationPlan {
+	todayTime := time.Now().Format(LayoutDate2)
+	todayStartTime := util.TimeParseLocalUnix(todayTime)
+	todayEndTime := util.TimeParseLocalEndUnix(todayTime)
+	return &EventImmunizationPlan{
+		CowId:    cow.Id,
+		Lact:     cow.Lact,
+		DayAge:   cow.DayAge,
+		CowKind:  cow.CowKind,
+		CowType:  cow.CowType,
+		PenId:    cow.PenId,
+		PenName:  pen.Name,
+		PlanId:   immunizationPlan.Id,
+		PlanName: immunizationPlan.Name,
+		PlanDay:  todayStartTime,
+		EndDay:   todayEndTime,
+		Status:   pasturePb.IsShow_No,
+	}
+}
+
+func NewCowImmunizationPlanList(cowList []*Cow, penMap map[int32]*Pen, immunizationPlan *ImmunizationPlan) []*EventImmunizationPlan {
+	cowImmunizationPlanList := make([]*EventImmunizationPlan, len(cowList))
+	for i, cow := range cowList {
+		pen := penMap[cow.PenId]
+		cowImmunizationPlanList[i] = NewCowImmunizationPlan(cow, pen, immunizationPlan)
+	}
+	return cowImmunizationPlanList
+}
+
+type EventImmunizationPlanSlice []*EventImmunizationPlan
+
+func (I EventImmunizationPlanSlice) ToPB() []*pasturePb.ImmunizationItems {
+	res := make([]*pasturePb.ImmunizationItems, len(I))
+	for i, v := range I {
+		res[i] = &pasturePb.ImmunizationItems{
+			Id:               int32(v.Id),
+			CowId:            int32(v.CowId),
+			PenId:            v.PenId,
+			Lact:             v.Lact,
+			PenName:          v.PenName,
+			DayAge:           v.DayAge,
+			PlanDay:          time.Unix(v.PlanDay, 0).Format(LayoutDate2),
+			Status:           v.Status,
+			ImmunizationName: v.PlanName,
+			ImmunizationId:   int32(v.PlanId),
+			Remarks:          v.Remarks,
+			OperatorId:       int32(v.OperationId),
+			OperatorName:     v.OperationName,
+			DrugId:           int32(v.DrugsId),
+			DrugName:         v.DrugsName,
+			Unit:             v.Unit,
+			UnitName:         v.UnitName,
+			Usage:            v.Usage,
+			CreatedAt:        int32(v.CreateAt),
+			UpdatedAt:        int32(v.UpdateAt),
+		}
+	}
+	return res
+}

+ 41 - 15
model/event_mating.go

@@ -111,21 +111,6 @@ func (e EventMatingSlice) ToPB(exposeEstrusTypeMap map[pasturePb.ExposeEstrusTyp
 	return res
 }
 
-type CowMatingHeader struct {
-	Id              string `json:"id"`
-	CowId           string `json:"cowId"`
-	PlanDay         string `json:"planDay"`
-	Lact            string `json:"lact"`
-	Status          string `json:"status"`
-	BreedStatusName string `json:"breedStatusName"`
-	BreedStatus     string `json:"breedStatus"`
-	CowTypeName     string `json:"cowTypeName"`
-	PenName         string `json:"penName"`
-	DayAge          string `json:"dayAge"`
-	CalvingAge      string `json:"calvingAge"`
-	AbortionAge     string `json:"abortionAge"`
-}
-
 type CowMatingBody struct {
 	Id              int64                      `json:"id"`
 	CowId           int64                      `json:"cowId"`
@@ -215,3 +200,44 @@ type CowMatingChart struct {
 	Lact2 [][]string `json:"lact2"`
 	Lact3 [][]string `json:"lact3"`
 }
+
+// MultiFactorPregnancyRateResponse 多维度受胎率
+type MultiFactorPregnancyRateResponse struct {
+	Code    int32                         `json:"code"`
+	Message string                        `json:"message"`
+	Data    *MultiFactorPregnancyRateData `json:"data"`
+}
+
+// MultiFactorPregnancyRateList 多维度受胎率分析
+type MultiFactorPregnancyRateList struct {
+	StatisticMethod1   string  `json:"statisticMethod1"`   // 统计方式名称1 (月度、品种)
+	StatisticMethod2   string  `json:"statisticMethod2"`   // 统计方式名称2 (月度、品种)
+	PregnantRate       float32 `json:"pregnantRate"`       // 受胎率%(怀孕数 / 怀孕数 + 空怀数)
+	PregnantCount      int32   `json:"pregnantCount"`      // 怀孕总数
+	EmptyPregnantCount int32   `json:"emptyPregnantCount"` // 空怀数
+	OtherCount         int32   `json:"otherCount"`         // 其他数 (配种后结果未知的个数,小于等于三次配种后,尚未孕检已经淘汰的个数)
+	AbortionCount      int32   `json:"abortionCount"`      // 流产数 (已经怀孕后流产的个数)
+	TotalCount         int32   `json:"totalCount"`         // 合计( 怀孕总数+空怀数+其他数)
+	SpcRate            float32 `json:"spcRate"`            // spc(1 / 受胎率)
+	Months             string  `json:"months"`             // 月份
+	OperationName      string  `json:"operationName"`      // 配种员名称
+	Bull               string  `json:"bull"`               // 公牛
+	Lact               string  `json:"lact"`               // 胎次
+	MatingTimes        string  `json:"matingTimes"`        // 配次
+	ExposeEstrusType   string  `json:"exposeEstrusType"`   // 发情揭发方式
+	Week               string  `json:"week"`               // 周
+}
+
+type MultiFactorPregnancyRateData struct {
+	Total    int32                           `json:"total"`
+	PageSize int32                           `json:"pageSize"`
+	Page     int32                           `json:"page"`
+	List     []*MultiFactorPregnancyRateList `json:"list"`
+	Chart    *MultiFactorPregnancyRateChart  `json:"chart"`
+}
+
+type MultiFactorPregnancyRateChart struct {
+	Header          []string                     `json:"header"` // 标题头
+	PregnantRateMap map[string]map[string]string `json:"pregnantRateMap"`
+	KepMap          []string                     `json:"kepMap"`
+}

+ 9 - 40
model/event_pregnant_check.go

@@ -11,6 +11,8 @@ type EventPregnantCheck struct {
 	Id                  int64                              `json:"id"`
 	CowId               int64                              `json:"cowId"`
 	CowType             pasturePb.CowType_Kind             `json:"cowType"`
+	PenId               int32                              `json:"penId"`
+	PenName             string                             `json:"penName"`
 	DayAge              int32                              `json:"dayAge"`
 	Lact                int8                               `json:"lact"`
 	MatingAge           int32                              `json:"matingAge"`
@@ -20,6 +22,7 @@ type EventPregnantCheck struct {
 	PregnantCheckName   string                             `json:"pregnantCheckName"`
 	PregnantCheckResult pasturePb.PregnantCheckResult_Kind `json:"pregnantCheckResult"`
 	PregnantCheckMethod pasturePb.PregnantCheckMethod_Kind `json:"pregnantCheckMethod"`
+	BullId              string                             `json:"bullId"`
 	Status              pasturePb.IsShow_Kind              `json:"status"`
 	OperationId         int64                              `json:"operationId"`
 	OperationName       string                             `json:"operationName"`
@@ -32,26 +35,29 @@ func (e *EventPregnantCheck) TableName() string {
 	return "event_pregnant_check"
 }
 
-func NewEventPregnantCheck(cow *Cow, pregnantCheckName string) *EventPregnantCheck {
+func NewEventPregnantCheck(cow *Cow, penMap map[int32]*Pen, pregnantCheckName string) *EventPregnantCheck {
 	return &EventPregnantCheck{
 		CowId:             cow.Id,
 		CowType:           cow.CowType,
+		PenId:             cow.PenId,
+		PenName:           penMap[cow.PenId].Name,
 		DayAge:            cow.GetDayAge(),
 		Lact:              int8(cow.Lact),
 		PlanDay:           util.TimeParseLocalUnix(time.Now().Format(LayoutDate2)),
 		EndDay:            util.TimeParseLocalEndUnix(time.Now().Format(LayoutDate2)),
 		PregnantCheckName: pregnantCheckName,
+		BullId:            cow.LastBullNumber,
 		Status:            pasturePb.IsShow_No,
 	}
 }
 
-func NewEventPregnantCheckList(cowList []*Cow, pregnantCheckName string) []*EventPregnantCheck {
+func NewEventPregnantCheckList(cowList []*Cow, penMap map[int32]*Pen, pregnantCheckName string) []*EventPregnantCheck {
 	res := make([]*EventPregnantCheck, len(cowList))
 	for i, cow := range cowList {
 		if cow.BreedStatus != pasturePb.BreedStatus_Breeding {
 			continue
 		}
-		res[i] = NewEventPregnantCheck(cow, pregnantCheckName)
+		res[i] = NewEventPregnantCheck(cow, penMap, pregnantCheckName)
 	}
 	return res
 }
@@ -84,43 +90,6 @@ func (e EventPregnantCheckSlice) ToPB(
 	return result
 }
 
-type PregnantCheckHeader struct {
-	Id        string `json:"id"`
-	CowId     string `json:"cowId"`
-	CowType   string `json:"cowType"`
-	DayAge    string `json:"dayAge"`
-	Lact      string `json:"lact"`
-	PlanDay   string `json:"planDay"`
-	PenName   string `json:"penName"`
-	CheckName string `json:"checkName"`
-}
-
-type PregnantCheckBody struct {
-	Id        int64                  `json:"id"`
-	CowId     int64                  `json:"cowId"`
-	CowType   pasturePb.CowType_Kind `json:"cowType"`
-	DayAge    int64                  `json:"dayAge"`
-	Lact      int32                  `json:"lact"`
-	PlanDay   string                 `json:"planDay"`
-	PenName   string                 `json:"penName"`
-	CheckName string                 `json:"checkName"`
-}
-
-func (e EventPregnantCheckSlice) ToPB2() []*PregnantCheckBody {
-	res := make([]*PregnantCheckBody, len(e))
-	for i, v := range e {
-		res[i] = &PregnantCheckBody{
-			Id:        v.Id,
-			CowId:     v.CowId,
-			DayAge:    int64(v.DayAge),
-			Lact:      int32(v.Lact),
-			PlanDay:   time.Unix(v.PlanDay, 0).Format(LayoutDate2),
-			CheckName: PregnantCheckNameMap[v.PregnantCheckName],
-		}
-	}
-	return res
-}
-
 func (e EventPregnantCheckSlice) ToPB3(
 	pregnantCheckResultMap map[pasturePb.PregnantCheckResult_Kind]string,
 	pregnantCheckMethodMap map[pasturePb.PregnantCheckMethod_Kind]string,

+ 0 - 18
model/event_weaning.go

@@ -45,21 +45,3 @@ func NewEventWeaningList(cowList []*Cow) []*EventWeaning {
 	}
 	return weaningList
 }
-
-type WeaningHeader struct {
-	Id      string `json:"id"`
-	CowId   string `json:"cowId"`
-	DayAge  string `json:"dayAge"`
-	PlanDay string `json:"planDay"`
-	Status  string `json:"status"`
-	PenName string `json:"penName"`
-}
-
-type WeaningBody struct {
-	Id      int64                 `json:"id"`
-	CowId   int64                 `json:"cowId"`
-	DayAge  int64                 `json:"dayAge"`
-	PlanDay string                `json:"planDay"`
-	Status  pasturePb.IsShow_Kind `json:"status"`
-	PenName string                `json:"penName"`
-}

+ 2 - 2
model/pen.go

@@ -9,7 +9,7 @@ import (
 const IsAllYes = "Yes"
 
 type Pen struct {
-	Id                int64                 `json:"id"`
+	Id                int32                 `json:"id"`
 	Name              string                `json:"name"`
 	Remarks           string                `json:"remarks"`
 	PenType           int32                 `json:"pen_type"`
@@ -43,7 +43,7 @@ func (p PenSlice) ToPB(configBarnTypes []*ConfigPenType) []*pasturePb.SearchBarn
 		}
 
 		res[i] = &pasturePb.SearchBarnList{
-			Id:                int32(v.Id),
+			Id:                v.Id,
 			Name:              v.Name,
 			IsShow:            v.IsShow,
 			Remarks:           v.Remarks,

+ 1 - 1
module/backend/analysis.go

@@ -49,7 +49,7 @@ func (s *StoreEntry) GrowthCurve(ctx context.Context, req *pasturePb.SearchGrowt
 		currentWeight := float32(cow.CurrentWeight) / 100
 		penName := ""
 		for _, v := range penList {
-			if int64(cow.PenId) != v.Id {
+			if cow.PenId != v.Id {
 				continue
 			}
 			penName = v.Name

+ 25 - 17
module/backend/analysis_breed.go

@@ -538,7 +538,7 @@ func (s *StoreEntry) SingleFactorAnalysisMethodLact(ctx context.Context, req *pa
 	return res, nil
 }
 
-func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.MultiFactorPregnancyRateRequest) (*pasturePb.MultiFactorPregnancyRateResponse, error) {
+func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.MultiFactorPregnancyRateRequest) (*model.MultiFactorPregnancyRateResponse, error) {
 	startTimeUnix := util.TimeParseLocalUnix(req.StartDayTime)
 	endTimeUnix := util.TimeParseLocalEndUnix(req.EndDayTime)
 	if startTimeUnix == 0 || endTimeUnix == 0 || endTimeUnix <= startTimeUnix {
@@ -617,39 +617,39 @@ func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.
 		}
 	}
 
-	list := make([]*pasturePb.MultiFactorPregnancyRateList, 0)
+	list := make([]*model.MultiFactorPregnancyRateList, 0)
 	if err := pref.Group(groupMap[fmt.Sprintf("%d%d", req.XAxle, req.YAxle)]).
 		Order(fmt.Sprintf("%s", multiFactorAnalysisMethod[req.XAxle])).Find(&list).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	chart := &pasturePb.MultiFactorPregnancyRateChart{
-		Headers:      make([]string, 0),
-		PregnantRate: make(map[string]*pasturePb.PregnancyRate),
+	chart := &model.MultiFactorPregnancyRateChart{
+		Header:          make([]string, 0),
+		PregnantRateMap: make(map[string]map[string]string),
 	}
 
 	for _, v := range list {
 		switch req.XAxle {
 		case pasturePb.MultiFactorAnalysisMethod_Months:
-			chart.Headers = append(chart.Headers, v.Months)
+			chart.Header = append(chart.Header, v.Months)
 			v.StatisticMethod1 = v.Months
 		case pasturePb.MultiFactorAnalysisMethod_Week:
-			chart.Headers = append(chart.Headers, v.Week)
+			chart.Header = append(chart.Header, v.Week)
 			v.StatisticMethod1 = v.Week
 		case pasturePb.MultiFactorAnalysisMethod_Operation:
-			chart.Headers = append(chart.Headers, v.OperationName)
+			chart.Header = append(chart.Header, v.OperationName)
 			v.StatisticMethod1 = v.OperationName
 		case pasturePb.MultiFactorAnalysisMethod_Bull:
-			chart.Headers = append(chart.Headers, v.Bull)
+			chart.Header = append(chart.Header, v.Bull)
 			v.StatisticMethod1 = v.Bull
 		case pasturePb.MultiFactorAnalysisMethod_Lact:
-			chart.Headers = append(chart.Headers, v.Lact)
+			chart.Header = append(chart.Header, v.Lact)
 			v.StatisticMethod1 = v.Lact
 		case pasturePb.MultiFactorAnalysisMethod_Mating_Times:
-			chart.Headers = append(chart.Headers, v.MatingTimes)
+			chart.Header = append(chart.Header, v.MatingTimes)
 			v.StatisticMethod1 = v.MatingTimes
 		case pasturePb.MultiFactorAnalysisMethod_Breeding_Method:
-			chart.Headers = append(chart.Headers, v.ExposeEstrusType)
+			chart.Header = append(chart.Header, v.ExposeEstrusType)
 			v.StatisticMethod1 = v.ExposeEstrusType
 		}
 
@@ -670,10 +670,14 @@ func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.
 			v.StatisticMethod2 = v.ExposeEstrusType
 		}
 
-		chart.Keys = append(chart.Keys, v.StatisticMethod1)
-		chart.PregnantRate[v.StatisticMethod1] = &pasturePb.PregnancyRate{
-			Params: make(map[string]string),
+		if chart.PregnantRateMap[v.StatisticMethod1] == nil {
+			chart.PregnantRateMap[v.StatisticMethod1] = make(map[string]string)
 		}
+
+		if chart.KepMap == nil {
+			chart.KepMap = make([]string, 0)
+		}
+
 		pregnantRate := float64(0)
 		if v.EmptyPregnantCount+v.PregnantCount > 0 {
 			pregnantRate = float64(v.PregnantCount) / float64(v.EmptyPregnantCount+v.PregnantCount)
@@ -684,12 +688,16 @@ func (s *StoreEntry) MultipleFactorAnalysis(ctx context.Context, req *pasturePb.
 			spcRate = float32(util.RoundToTwoDecimals((float64(v.PregnantCount) / float64(v.TotalCount)) * 100))
 		}
 		v.SpcRate = spcRate
+		chart.PregnantRateMap[v.StatisticMethod1][v.StatisticMethod2] = fmt.Sprintf("%.0f", v.PregnantRate)
+		chart.KepMap = append(chart.KepMap, v.StatisticMethod2)
 	}
 
-	return &pasturePb.MultiFactorPregnancyRateResponse{
+	chart.Header = util.RemoveDuplicates(chart.Header)
+	chart.KepMap = util.RemoveDuplicates(chart.KepMap)
+	return &model.MultiFactorPregnancyRateResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &pasturePb.MultiFactorPregnancyRateData{
+		Data: &model.MultiFactorPregnancyRateData{
 			Total: int32(len(list)),
 			List:  list,
 			Chart: chart,

+ 196 - 119
module/backend/calendar.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"kpt-pasture/model"
+	"kpt-pasture/util"
 	"net/http"
 	"time"
 
@@ -37,7 +38,7 @@ func (s *StoreEntry) CalendarToDoList(ctx context.Context, req *pasturePb.Calend
 
 	}
 
-	if req.CalendarType > pasturePb.CalendarType_Invalid {
+	if req.CalendarType > 0 {
 		pref.Where("calendar_type = ?", req.CalendarType)
 	}
 
@@ -109,237 +110,313 @@ func (s *StoreEntry) CalendarTableDetail(
 	if newCalendar.Id <= 0 {
 		return nil, xerr.New("不存在该日历数据")
 	}
-
 	return s.getCalendarCowList(ctx, req.CalendarType, req.Start, pagination)
 }
 
 func (s *StoreEntry) getCalendarCowList(
 	ctx context.Context,
 	calendarType pasturePb.CalendarType_Kind,
-	startDate string,
-	pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
+	showDay string,
+	pagination *pasturePb.PaginationModel) (interface{}, error) {
+	req := &pasturePb.ItemsRequest{EndDay: showDay, CalendarType: calendarType, Status: pasturePb.IsShow_No}
 	switch calendarType {
 	case pasturePb.CalendarType_Immunisation: // 免疫
-		return s.ImmunisationCowList(ctx, startDate, pagination)
+		return s.ImmunisationCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_PG, pasturePb.CalendarType_RnGH: // 同期
-		return s.SameTimeCowList(ctx, startDate, pagination, calendarType)
+		return s.SameTimeCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_Pregnancy_Check: // 孕检
-		return s.PregnancyCheckCowList(ctx, startDate, pagination)
+		return s.PregnancyCheckCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_WorkOrder: // 工作单
-		return s.WorkOrderCowList(ctx, startDate, pagination)
+		return s.WorkOrderCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_Weaning: // 断奶
-		return s.WeaningCowList(ctx, startDate, pagination)
+		return s.WeaningCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_Treatment: // 治疗
-		return s.TreatmentCowList(ctx, startDate, pagination)
+		return s.TreatmentCowList(ctx, req, pagination)
 	case pasturePb.CalendarType_Mating: // 配种
-		return s.MatingCowList(ctx, startDate, pagination)
+		return s.MatingCowList(ctx, req, pagination)
 	default:
 		return nil, xerr.New("不支持的日历类型")
 	}
 }
 
-func (s *StoreEntry) ImmunisationCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	immunizationPlanCowList := make([]*model.CowImmunizationPlan, 0)
+func (s *StoreEntry) ImmunisationCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.ImmunizationItemsResponse, error) {
+	eventImmunizationPlanList := make([]*model.EventImmunizationPlan, 0)
 	count := int64(0)
-	if err := s.DB.Model(&model.CowImmunizationPlan{}).
-		Where("plan_day <= ?", dateTime).
-		Where("status = ?", pasturePb.IsShow_No).
-		Order("id desc").Count(&count).Limit(int(pagination.PageSize)).Offset(int(pagination.PageOffset)).
-		Find(&immunizationPlanCowList).Error; err != nil {
+	pref := s.DB.Model(&model.EventImmunizationPlan{})
+	if req.StartDay != "" {
+		dateTime := util.TimeParseLocalUnix(req.StartDay)
+		pref.Where("plan_day >= ?", dateTime)
+	}
+
+	if req.EndDay != "" {
+		dateTime := util.TimeParseLocalEndUnix(req.EndDay)
+		pref.Where("plan_day <= ?", dateTime)
+	}
+
+	if req.CowId > 0 {
+		pref.Where("cow_id = ?", req.CowId)
+	}
+
+	if req.ImmunizationId > 0 {
+		pref.Where("plan_id = ?", req.ImmunizationId)
+	}
+
+	if req.Lact >= 0 {
+		pref.Where("lact = ?", req.Lact)
+	}
+
+	if req.PenId > 0 {
+		pref.Where("pen_id = ?", req.PenId)
+	}
+
+	if req.Status > 0 {
+		pref.Where("status = ?", req.Status)
+	}
+
+	if err := pref.Order("id desc").
+		Count(&count).
+		Limit(int(pagination.PageSize)).
+		Offset(int(pagination.PageOffset)).
+		Order("id desc").
+		Find(&eventImmunizationPlanList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.CalendarResponse{
+	return &pasturePb.ImmunizationItemsResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &model.CalendarData{
+		Data: &pasturePb.ImmunizationItemsData{
 			Total:    int32(count),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
-			Header: model.ImmunizationCalendarHeader{
-				Id:                   "编号",
-				CowId:                "牛号",
-				PlanStartTime:        "免疫开始时间",
-				ImmunizationPlanName: "免疫名称",
-				Status:               "状态",
+			Header: map[string]string{
+				"id":                   "编号",
+				"cowId":                "牛号",
+				"penName":              "栏舍",
+				"dayAge":               "日龄",
+				"planStartTime":        "免疫开始时间",
+				"immunizationPlanName": "免疫名称",
+				"status":               "状态",
 			},
-			List: model.ImmunizationPlanCowSlice(immunizationPlanCowList).ToPB(),
+			List: model.EventImmunizationPlanSlice(eventImmunizationPlanList).ToPB(),
 		},
 	}, nil
 
 }
 
-func (s *StoreEntry) SameTimeCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel, calendarType pasturePb.CalendarType_Kind) (*model.CalendarResponse, error) {
+func (s *StoreEntry) SameTimeCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SameTimeItemResponse, error) {
 	sameTimeBodyList := make([]*model.SameTimeBody, 0)
 	count := int64(0)
 	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCowSameTime).TableName())).
-		Select("a.id,a.cow_id,a.status,b.breed_status,b.cow_type,b.pen_id,b.day_age,b.calving_age,b.abortion_age").
+		Select("a.id,a.cow_id,a.pen_name,a.status,b.breed_status,b.cow_type,b.day_age,b.calving_age,b.abortion_age").
 		Joins("left join cow as b on a.cow_id = b.id").
-		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
-		Where("a.plan_day <= ?", dateTime).
-		Where("a.status = ?", pasturePb.IsShow_No)
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
+	if req.EndDay != "" {
+		dateTime := util.TimeParseLocalEndUnix(req.EndDay)
+		pref.Where("a.plan_day <= ?", dateTime)
+	}
+
+	if req.CalendarType > 0 {
+		pref.Where("a.same_time_type = ?", req.CalendarType)
+	}
 
-	if calendarType == pasturePb.CalendarType_PG {
-		pref.Where("a.same_time_type = ?", calendarType)
+	if req.CowType >= 0 {
+		pref.Where("b.cow_type = ?", req.CowType)
 	}
 
-	if calendarType == pasturePb.CalendarType_RnGH {
-		pref.Where("a.same_time_type = ?", calendarType)
+	if req.Status > 0 {
+		pref.Where("a.status = ?", pasturePb.IsShow_No)
 	}
 
 	if err := pref.Order("a.id desc").Count(&count).
 		Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).
+		Order("id desc").
 		Find(&sameTimeBodyList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
-	cowTypeMap := s.CowTypeMap()
 	breedStatusMap := s.CowBreedStatusMap()
 	penMap := s.PenMap(ctx)
-	return &model.CalendarResponse{
+	return &pasturePb.SameTimeItemResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &model.CalendarData{
+		Data: &pasturePb.SameTimeItemsData{
 			Total:    int32(count),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
-			Header: model.SameTimeHeader{
-				Id:              "编号",
-				CowId:           "牛号",
-				BreedStatusName: "繁殖状态",
-				CowTypeName:     "牛只类型",
-				PenName:         "栏舍",
-				Lact:            "胎次",
-				CalvingAge:      "产后天数",
-				AbortionAge:     "流产天数",
-				DayAge:          "日龄",
-				Status:          "状态",
+			Header: map[string]string{
+				"id":              "编号",
+				"cowId":           "牛号",
+				"breedStatusName": "繁殖状态",
+				"cowTypeName":     "牛只类型",
+				"penName":         "栏舍",
+				"lact":            "胎次",
+				"calvingAge":      "产后天数",
+				"abortionAge":     "流产天数",
+				"dayAge":          "日龄",
+				"status":          "状态",
 			},
-			List: model.SameTimeBodySlice(sameTimeBodyList).ToPB(cowTypeMap, breedStatusMap, penMap),
+			List: model.SameTimeBodySlice(sameTimeBodyList).ToPB(breedStatusMap, penMap),
 		},
 	}, nil
 }
 
-func (s *StoreEntry) PregnancyCheckCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	newCowPregnancyCheckList := make([]*model.EventPregnantCheck, 0)
+func (s *StoreEntry) PregnancyCheckCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnancyCheckItemsResponse, error) {
+	newPregnancyCheckItems := make([]*pasturePb.PregnancyCheckItems, 0)
 	var count int64
-	if err := s.DB.Model(&model.EventPregnantCheck{}).
-		Where("plan_day <= ?", dateTime).
-		Where("status = ?", pasturePb.IsShow_No).
-		Order("id desc").Count(&count).
+	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventPregnantCheck).TableName())).
+		Select("a.id,a.cow_id,a.pen_id,a.status,b.breed_status,b.cow_type,b.day_age,b.calving_age,b.abortion_age,a.bull_id").
+		Joins("left join cow as b on a.cow_id = b.id").
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
+	if req.EndDay != "" {
+		dateTime := util.TimeParseLocalEndUnix(req.EndDay)
+		pref.Where("plan_day <= ?", dateTime)
+	}
+
+	if req.CowType > 0 {
+		pref.Where("cow_type = ?", req.CowType)
+	}
+
+	if req.Status > 0 {
+		pref.Where("a.status = ?", req.Status)
+	}
+
+	if err := pref.Order("id desc").
+		Count(&count).
 		Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).
-		Find(&newCowPregnancyCheckList).Error; err != nil {
+		Order("id desc").
+		Find(&newPregnancyCheckItems).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.CalendarResponse{
+	return &pasturePb.PregnancyCheckItemsResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &model.CalendarData{
+		Data: &pasturePb.PregnancyCheckItemsData{
 			Total:    int32(count),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
-			Header: model.PregnantCheckHeader{
-				Id:        "编号",
-				CowId:     "牛号",
-				CowType:   "牛只类型",
-				PenName:   "栏舍",
-				Lact:      "胎次",
-				DayAge:    "日龄",
-				PlanDay:   "孕检日期",
-				CheckName: "孕检名称",
+			Header: map[string]string{
+				"id":              "编号",
+				"cowId":           "牛号",
+				"cowTypeName":     "牛只类型",
+				"penName":         "栏舍",
+				"lact":            "胎次",
+				"dayAge":          "日龄",
+				"planDay":         "孕检日期",
+				"checkTypeName":   "孕检名称",
+				"status":          "状态",
+				"matingTimes":     "配次",
+				"calvingAtFormat": "产检日期",
+				"matingAtFormat":  "配种日期",
+				"matingAge":       "配后天数",
+				"bullId":          "配种公牛",
 			},
-			List: model.EventPregnantCheckSlice(newCowPregnancyCheckList).ToPB2(),
+			List: newPregnancyCheckItems,
 		},
 	}, nil
 }
 
-func (s *StoreEntry) WorkOrderCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	return nil, nil
-}
-
-func (s *StoreEntry) WeaningCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	weaningBodyList := make([]*model.WeaningBody, 0)
+func (s *StoreEntry) WeaningCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.WeaningItemsResponse, error) {
+	weaningItems := make([]*pasturePb.WeaningItems, 0)
 	count := int64(0)
 
-	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCowSameTime).TableName())).
+	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventWeaning).TableName())).
 		Select("a.*,b.day_age").
 		Joins("left join cow as b on a.cow_id = b.id").
-		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
-		Where("a.plan_day <= ?", dateTime).
-		Where("a.status = ?", pasturePb.IsShow_No)
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
+	if req.EndDay != "" {
+		dateTime := util.TimeParseLocalEndUnix(req.EndDay)
+		pref.Where("a.plan_day <= ?", dateTime)
+	}
+
+	if req.Status > 0 {
+		pref.Where("a.status = ?", req.Status)
+	}
 
 	if err := pref.Order("a.id desc").Count(&count).
 		Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).
-		Find(&weaningBodyList).Error; err != nil {
+		Find(&weaningItems).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.CalendarResponse{
+	return &pasturePb.WeaningItemsResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &model.CalendarData{
+		Data: &pasturePb.WeaningItemsData{
 			Total:    int32(count),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
-			Header: model.WeaningHeader{
-				Id:      "编号",
-				CowId:   "牛号",
-				PenName: "栏舍",
-				PlanDay: "断奶日期",
-				DayAge:  "日龄",
-				Status:  "状态",
+			Header: map[string]string{
+				"id":      "编号",
+				"cowId":   "牛号",
+				"penName": "栏舍",
+				"planDay": "断奶日期",
+				"dayAge":  "日龄",
+				"status":  "状态",
 			},
-			List: weaningBodyList,
+			List: weaningItems,
 		},
 	}, nil
 }
 
-func (s *StoreEntry) TreatmentCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	return nil, nil
-}
-
-func (s *StoreEntry) MatingCowList(ctx context.Context, dateTime string, pagination *pasturePb.PaginationModel) (*model.CalendarResponse, error) {
-	cowMatingBodyList := make([]*model.CowMatingBody, 0)
+func (s *StoreEntry) MatingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingItemsResponse, error) {
+	matingItems := make([]*pasturePb.MatingItems, 0)
 	count := int64(0)
-	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCowSameTime).TableName())).
+	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventMating).TableName())).
 		Select("a.id,a.cow_id,a.status,b.breed_status,b.cow_type,b.pen_id,b.day_age,b.calving_age,b.abortion_age").
 		Joins("left join cow as b on a.cow_id = b.id").
-		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission).
-		Where("a.plan_day <= ?", dateTime).
-		Where("a.status = ?", pasturePb.IsShow_No)
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
+	if req.EndDay != "" {
+		dateTime := util.TimeParseLocalEndUnix(req.EndDay)
+		pref.Where("a.plan_day <= ?", dateTime)
+	}
+
+	if req.Status > 0 {
+		pref.Where("a.status = ?", req.Status)
+	}
 
 	if err := pref.Order("a.id desc").Count(&count).
 		Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).
-		Find(&cowMatingBodyList).Error; err != nil {
+		Find(&matingItems).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
-	cowTypeMap := s.CowTypeMap()
-	breedStatusMap := s.CowBreedStatusMap()
-	penMap := s.PenMap(ctx)
-	return &model.CalendarResponse{
+
+	return &pasturePb.MatingItemsResponse{
 		Code:    http.StatusOK,
 		Message: "ok",
-		Data: &model.CalendarData{
+		Data: &pasturePb.MatingItemsData{
 			Total:    int32(count),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
-			Header: model.SameTimeHeader{
-				Id:              "编号",
-				CowId:           "牛号",
-				BreedStatusName: "繁殖状态",
-				CowTypeName:     "牛只类型",
-				PenName:         "栏舍",
-				Lact:            "胎次",
-				CalvingAge:      "产后天数",
-				AbortionAge:     "流产天数",
-				DayAge:          "日龄",
-				Status:          "状态",
+			Header: map[string]string{
+				"id":              "编号",
+				"cowId":           "牛号",
+				"breedStatusName": "繁殖状态",
+				"cowTypeName":     "牛只类型",
+				"penName":         "栏舍",
+				"lact":            "胎次",
+				"calvingAge":      "产后天数",
+				"abortionAge":     "流产天数",
+				"dayAge":          "日龄",
+				"status":          "状态",
 			},
-			List: model.CowMatingBodySlice(cowMatingBodyList).ToPB(cowTypeMap, breedStatusMap, penMap),
+			List: matingItems,
 		},
 	}, nil
 }
+
+func (s *StoreEntry) WorkOrderCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (interface{}, error) {
+	return nil, nil
+}
+
+func (s *StoreEntry) TreatmentCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (interface{}, error) {
+	return nil, nil
+}

+ 3 - 11
module/backend/event_breed.go

@@ -570,16 +570,8 @@ func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSam
 		return xerr.WithStack(err)
 	}
 
-	cowList, err := s.ParseCowIds(ctx, req.CowId)
-	if err != nil {
-		return xerr.WithStack(err)
-	}
-	cowIds := make([]int64, 0)
-	for _, v := range cowList {
-		cowIds = append(cowIds, v.Id)
-	}
-
 	drugs := &model.Drugs{}
+	var err error
 	if req.DrugsId > 0 {
 		if drugs, err = s.GetDrugsById(ctx, int64(req.DrugsId)); err != nil {
 			return xerr.WithStack(err)
@@ -592,14 +584,14 @@ func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSam
 
 	if err = s.DB.Transaction(func(tx *gorm.DB) error {
 		if err = tx.Model(new(model.CowSameTime)).
-			Where("cow_id IN ?", cowIds).
+			Where("cow_id = ?", req.CowId).
 			Where("same_time_id = ?", req.SameTimeId).
 			Update("same_time_status", pasturePb.SameTimeStatus_In_Progress).Error; err != nil {
 			return xerr.WithStack(err)
 		}
 
 		if err = tx.Model(new(model.EventCowSameTime)).
-			Where("cow_id IN ?", cowIds).
+			Where("cow_id = ?", req.CowId).
 			Where("same_time_id = ?", req.SameTimeId).
 			Where("same_time_type = ?", req.SameTimeType).
 			Updates(map[string]interface{}{

+ 10 - 2
module/backend/interface.go

@@ -217,7 +217,7 @@ type AnalyseService interface {
 	CalvingReport(ctx context.Context, req *pasturePb.CalvingReportRequest) (*pasturePb.CalvingReportResponse, error)
 	DiseaseCureReport(ctx context.Context, req *pasturePb.DiseaseCureRateRequest) (*pasturePb.DiseaseCureRateResponse, error)
 	SingleFactorInfantSurvivalRateAnalysis(ctx context.Context, req *pasturePb.SingleFactorPregnancyRateRequest) (*pasturePb.SingleFactorPregnancyRateResponse, error)
-	MultipleFactorAnalysis(ctx context.Context, req *pasturePb.MultiFactorPregnancyRateRequest) (*pasturePb.MultiFactorPregnancyRateResponse, error)
+	MultipleFactorAnalysis(ctx context.Context, req *pasturePb.MultiFactorPregnancyRateRequest) (*model.MultiFactorPregnancyRateResponse, error)
 }
 
 //go:generate mockgen -destination mock/DashboardService.go -package kptservicemock kpt-pasture/module/backend DashboardService
@@ -232,7 +232,15 @@ type WorkService interface {
 	OrderIsShow(ctx context.Context, id int64) error
 	UserWorkOrderList(ctx context.Context, workOrderStatus pasturePb.WorkOrderStatus_Kind, pagination *pasturePb.PaginationModel) (*pasturePb.UserWorkOrderResponse, error)
 
-	CalendarToDoList(ctx context.Context, req *pasturePb.CalendarToDoRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CalendarToDoResponse, error)
+	// CalendarList 日历相关
 	CalendarList(ctx context.Context, req *pasturePb.CalendarRequest) (*pasturePb.CalendarResponse, error)
+	CalendarToDoList(ctx context.Context, req *pasturePb.CalendarToDoRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CalendarToDoResponse, error)
 	CalendarTableDetail(ctx context.Context, req *pasturePb.CalendarTableRequest, pagination *pasturePb.PaginationModel) (interface{}, error)
+
+	// ImmunisationCowList 清单相关
+	ImmunisationCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.ImmunizationItemsResponse, error)
+	SameTimeCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SameTimeItemResponse, error)
+	PregnancyCheckCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnancyCheckItemsResponse, error)
+	WeaningCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.WeaningItemsResponse, error)
+	MatingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingItemsResponse, error)
 }

+ 1 - 1
module/backend/pasture.go

@@ -46,7 +46,7 @@ func (s *StoreEntry) SearchBarnList(ctx context.Context, req *pasturePb.SearchNa
 
 func (s *StoreEntry) CreateOrUpdateBarn(ctx context.Context, req *pasturePb.SearchBarnList) error {
 	if req.Id > 0 {
-		barn := &model.Pen{Id: int64(req.Id)}
+		barn := &model.Pen{Id: req.Id}
 		if err := s.DB.Model(&model.Pen{}).First(barn).Error; err != nil {
 			if !errors.Is(err, gorm.ErrRecordNotFound) {
 				return xerr.WithStack(err)

+ 3 - 5
module/backend/sql.go

@@ -69,10 +69,8 @@ func (s *StoreEntry) SystemDeptList(ctx context.Context) ([]*model.SystemDept, e
 	return deptList, nil
 }
 
-func (s *StoreEntry) GetPenById(ctx context.Context, penId int64) (*model.Pen, error) {
-	penData := &model.Pen{
-		Id: penId,
-	}
+func (s *StoreEntry) GetPenById(ctx context.Context, penId int32) (*model.Pen, error) {
+	penData := &model.Pen{Id: penId}
 	if err := s.DB.First(penData).Error; err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
 			return nil, xerr.Customf("该栏舍数据不存在: %d", penId)
@@ -94,7 +92,7 @@ func (s *StoreEntry) PenMap(ctx context.Context) map[int32]*model.Pen {
 	penList, _ := s.GetPenList(ctx)
 	penMap := make(map[int32]*model.Pen)
 	for _, v := range penList {
-		penMap[int32(v.Id)] = v
+		penMap[v.Id] = v
 	}
 	return penMap
 }

+ 21 - 16
module/crontab/cow_cron.go

@@ -68,13 +68,15 @@ func (e *Entry) UpdateCowInfo() error {
 		e.CreateCrontabLog(UpdateCowInfo)
 	}()
 	for _, cow := range cowList {
-		if err := e.DB.Model(new(model.Cow)).Where("id = ?", cow.Id).Updates(map[string]interface{}{
-			"day_age":       cow.GetDayAge(),
-			"calving_at":    cow.GetCalvingAge(),
-			"pregnancy_age": cow.GetDaysPregnant(),
-			"admission_age": cow.GetAdmissionAge(),
-			"abortion_age":  cow.GetAbortionAge(),
-		}).Error; err != nil {
+		if err := e.DB.Model(new(model.Cow)).
+			Where("id = ?", cow.Id).
+			Updates(map[string]interface{}{
+				"day_age":       cow.GetDayAge(),
+				"calving_at":    cow.GetCalvingAge(),
+				"pregnancy_age": cow.GetDaysPregnant(),
+				"admission_age": cow.GetAdmissionAge(),
+				"abortion_age":  cow.GetAbortionAge(),
+			}).Error; err != nil {
 			zaplog.Error("Crontab", zap.Any("UpdateCowDayAge", err))
 		}
 	}
@@ -93,7 +95,9 @@ func (e *Entry) ImmunizationPlan() error {
 	var todayCount int32 = 0
 	defer func() {
 		var count int64 = 0
-		if err := e.DB.Model(new(model.CowImmunizationPlan)).Where("status = ?", pasturePb.IsShow_Ok).Count(&count).Error; err != nil {
+		if err := e.DB.Model(new(model.EventImmunizationPlan)).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Count(&count).Error; err != nil {
 			zaplog.Error("Crontab", zap.Any("ImmunizationPlanDefer", err))
 		}
 		todayCount += int32(count)
@@ -104,13 +108,11 @@ func (e *Entry) ImmunizationPlan() error {
 	}()
 
 	for _, plan := range planList {
-		if plan == nil {
-			continue
-		}
 		cowList := make([]*model.Cow, 0)
-		pref := e.DB.Table(fmt.Sprintf("%s as a", new(model.ImmunizationPlan).TableName())).
+		pref := e.DB.Table(fmt.Sprintf("%s as a", new(model.Cow).TableName())).
 			Select("a.*").
-			Where("a.is_show = ?", pasturePb.IsShow_Ok)
+			Where("a.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
 		if plan.CowType > 0 {
 			pref.Where("a.cow_type = ?", plan.CowType)
 		}
@@ -129,7 +131,7 @@ func (e *Entry) ImmunizationPlan() error {
 			pref.Where("a.admission_age = ?", plan.Value)
 		case pasturePb.ImmunizationConditions_Other_Vaccine_After:
 			if plan.ImmunizationPlanId > 0 {
-				pref.Joins("INNER JOIN immunization_plan_cow as b ON b.immunization_plan_id = ?", plan.ImmunizationPlanId).
+				pref.Joins("INNER JOIN event_immunization_plan as b ON b.immunization_plan_id = ? ", plan.ImmunizationPlanId).
 					Where("b.cow_id = a.id").
 					Where("DATE_ADD(b.reality_time, INTERVAL ? DAY) = ?", plan.Value, time.Now().Format(model.LayoutDate2)).
 					Where("b.status = ?", pasturePb.IsShow_Ok)
@@ -143,9 +145,11 @@ func (e *Entry) ImmunizationPlan() error {
 			continue
 		}
 		todayCount += int32(len(cowList))
-		newImmunizationPlanCowList := model.NewCowImmunizationPlanList(cowList, plan)
+		penList, _ := e.GetPenMapList()
+		newImmunizationPlanCowList := model.NewCowImmunizationPlanList(cowList, penList, plan)
 		newEventItemList := model.NewEventItemList(cowList, pasturePb.CalendarType_Immunisation)
 		if err := e.DB.Transaction(func(tx *gorm.DB) error {
+
 			if err := tx.Create(newImmunizationPlanCowList).Error; err != nil {
 				return xerr.WithStack(err)
 
@@ -339,7 +343,8 @@ func (e *Entry) SystemBasicCrontab() error {
 func (e *Entry) InitEventData(cowList []*model.Cow, systemBasicName string) {
 	switch systemBasicName {
 	case model.PregnantCheckForFirst, model.PregnantCheckForSecond:
-		eventPregnantCheckDataList := model.NewEventPregnantCheckList(cowList, systemBasicName)
+		penMap, _ := e.GetPenMapList()
+		eventPregnantCheckDataList := model.NewEventPregnantCheckList(cowList, penMap, systemBasicName)
 		if err := e.DB.Create(eventPregnantCheckDataList).Error; err != nil {
 			zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventPregnantCheckDataList", eventPregnantCheckDataList))
 		}

+ 21 - 0
module/crontab/sql.go

@@ -0,0 +1,21 @@
+package crontab
+
+import (
+	"kpt-pasture/model"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+	"gitee.com/xuyiping_admin/pkg/xerr"
+)
+
+func (e *Entry) GetPenMapList() (map[int32]*model.Pen, error) {
+	penList := make([]*model.Pen, 0)
+	if err := e.DB.Where("is_delete = ?", pasturePb.IsShow_Ok).Find(&penList).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	penMap := make(map[int32]*model.Pen)
+	for _, v := range penList {
+		penMap[v.Id] = v
+	}
+	return penMap, nil
+}

+ 3 - 5
module/crontab/work_cron.go

@@ -61,12 +61,10 @@ func (e *Entry) GenerateCalendarBySameTimePlan(cowList []*model.Cow, sameTime *m
 				calendarName = backend.CalendarTypeMap()[pasturePb.CalendarType_RnGH]
 				calendarType = pasturePb.CalendarType_RnGH
 			}
-			newEventItemList = append(newEventItemList, model.NewEventItemList(newCowList, calendarType)...)
 			histCount = e.GetTowardSameTimeCowSum(sameTime.Id, collateNode.SameTimeType)
-			newSameTimeCowDetailList = append(
-				newSameTimeCowDetailList,
-				model.NewCowSameTimeDetailList(newCowList, sameTime.Id, showDay.Unix(), collateNode.SameTimeType)...,
-			)
+			newEventCowSameTimeList := model.NewEventCowSameTimeList(newCowList, sameTime.Id, showDay.Unix(), collateNode.SameTimeType)
+			newSameTimeCowDetailList = append(newSameTimeCowDetailList, newEventCowSameTimeList...)
+			newEventItemList = append(newEventItemList, model.NewEventItemList(newCowList, calendarType)...)
 		}
 
 		calendarList = append(calendarList, &model.Calendar{

+ 26 - 0
util/util.go

@@ -249,7 +249,33 @@ func ConfidenceInterval(data []float64) (float64, float64) {
 
 // ConfidenceInterval2 计算95%置信区间
 func ConfidenceInterval2(p float64, total float64) (min, max float64) {
+	if p <= 0 || total <= 0 {
+		return 0, 0
+	}
 	z := 1.96 // 95%置信水平对应的Z值
 	marginOf := z * math.Sqrt(p*(1-p)/total) * 100
 	return math.Max(0, p*100-math.Ceil(marginOf)), math.Max(1, p*100+math.Ceil(marginOf))
 }
+
+// RemoveDuplicates 去除切片中的重复元素
+func RemoveDuplicates(slice []string) []string {
+	if len(slice) <= 0 {
+		return slice
+	}
+	// 创建一个map来跟踪已经遇到的元素
+	seen := make(map[string]struct{})
+	// 创建一个新的切片来存储不重复的元素
+	var result []string
+
+	// 遍历原始切片
+	for _, v := range slice {
+		// 如果元素尚未在map中,则将其添加到结果切片和map中
+		if _, exists := seen[v]; !exists {
+			seen[v] = struct{}{}
+			result = append(result, v)
+		}
+	}
+
+	// 返回不重复的切片
+	return result
+}

+ 47 - 0
util/util_test.go

@@ -335,6 +335,12 @@ func TestConfidenceInterval2(t *testing.T) {
 			min:   32,
 			max:   50,
 		},
+		{
+			p:     0,
+			total: 0,
+			min:   0,
+			max:   0,
+		},
 	}
 
 	for _, tt := range tests {
@@ -343,3 +349,44 @@ func TestConfidenceInterval2(t *testing.T) {
 		assert.Equal(t, tt.max, max)
 	}
 }
+
+func TestRemoveDuplicates(t *testing.T) {
+	tests := []struct {
+		actual []string
+		got    []string
+	}{
+		{
+			actual: []string{
+				"1", "1",
+			},
+			got: []string{
+				"1",
+			},
+		},
+		{
+			actual: []string{
+				"1", "1", "2",
+			},
+			got: []string{
+				"1", "2",
+			},
+		},
+		{
+			actual: []string{
+				"1",
+			},
+			got: []string{
+				"1",
+			},
+		},
+		{
+			actual: []string{},
+			got:    []string{},
+		},
+	}
+
+	for _, tt := range tests {
+		got := RemoveDuplicates(tt.actual)
+		assert.Equal(t, tt.got, got)
+	}
+}