package backend import ( "context" "fmt" "kpt-pasture/model" "kpt-pasture/util" "net/http" "regexp" "time" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/xerr" ) // CalendarToDoList 获取日历待办列表 func (s *StoreEntry) CalendarToDoList(ctx context.Context, req *pasturePb.CalendarToDoRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CalendarToDoResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } calendarToDoList := make([]*pasturePb.CalendarToDoList, 0) pastureWhereSql := fmt.Sprintf(" AND pasture_id = %d", userModel.AppPasture.Id) whereSql := "" if req.CowId > 0 { whereSql += fmt.Sprintf(" AND cow_id = %d", req.CowId) } if req.CalendarType > 0 { calendarTypeMap := CalendarTypeMap() calendarTypeName := calendarTypeMap[req.CalendarType] if len(calendarTypeName) > 0 { re := regexp.MustCompile(`[a-zA-Z]`) // 使用正则表达式替换匹配的字母为空字符串 calendarTypeName = re.ReplaceAllString(calendarTypeName, "") whereSql += fmt.Sprintf(" AND calendar_type_name = '%s'", calendarTypeName) } } sql := `SELECT a.cow_id,b.pen_name,a.calendar_type_name,DATE_FORMAT(FROM_UNIXTIME(a.plan_day), '%Y-%m-%d') AS plan_day,b.lact, b.ear_number FROM ( SELECT cow_id,plan_day,'免疫' as calendar_type_name FROM event_immunization_plan WHERE status = 2 ` + pastureWhereSql + ` UNION ALL SELECT cow_id,plan_day ,'同期' as calendar_type_name FROM event_cow_same_time WHERE status = 2 ` + pastureWhereSql + ` UNION ALL SELECT cow_id,plan_day ,'孕检' as calendar_type_name FROM event_pregnant_check WHERE status = 2 ` + pastureWhereSql + ` UNION ALL SELECT cow_id,plan_day ,'断奶' as calendar_type_name FROM event_weaning WHERE status = 2 ` + pastureWhereSql + ` UNION ALL SELECT cow_id,plan_day ,'配种' as calendar_type_name FROM event_mating WHERE status = 2 ` + pastureWhereSql + ` UNION ALL SELECT cow_id,plan_day ,'产犊' as calendar_type_name FROM event_calving WHERE status = 2 ` + pastureWhereSql + ` ) as a JOIN cow b ON a.cow_id = b.id WHERE 1 = 1 ` completeSql := fmt.Sprintf("%s %s ORDER BY a.plan_day ASC LIMIT %d OFFSET %d", sql, whereSql, pagination.PageSize, pagination.PageOffset) if err = s.DB.Raw(completeSql).Find(&calendarToDoList).Error; err != nil { return nil, err } return &pasturePb.CalendarToDoResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.CalendarToDoData{ List: calendarToDoList, Total: int32(len(calendarToDoList)), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } func (s *StoreEntry) CalendarList(ctx context.Context, req *pasturePb.CalendarRequest) (*pasturePb.CalendarResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } calendarList := make([]*model.Calendar, 0) if err = s.DB.Model(&model.Calendar{}). Where("show_day >= ?", req.ShowStartDay). Where("show_day <= ?", req.ShowEndDay). Where("pasture_id = ?", userModel.AppPasture.Id). Where("is_show = ?", pasturePb.IsShow_Ok). Find(&calendarList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.CalendarResponse{ Code: http.StatusOK, Msg: "ok", Data: model.CalendarSlice(calendarList).ToPB(), }, nil } func (s *StoreEntry) CalendarTableDetail( ctx context.Context, req *pasturePb.CalendarTableRequest, pagination *pasturePb.PaginationModel, ) (interface{}, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } if req.Start != time.Now().Format(model.LayoutDate2) { return nil, xerr.Custom("只能获取当天的数据") } newCalendar := &model.Calendar{} if err = s.DB.Model(&model.Calendar{}). Where("calendar_type = ?", req.CalendarType). Where("show_day = ?", req.Start). Where("is_show = ?", pasturePb.IsShow_Ok). Where("pasture_id = ?", userModel.AppPasture.Id). First(newCalendar).Error; err != nil { return nil, xerr.WithStack(err) } if newCalendar.Id <= 0 { return nil, xerr.New("不存在该日历数据") } return s.getCalendarCowList(ctx, req.CalendarType, req.Start, pagination, userModel.AppPasture.Id) } func (s *StoreEntry) getCalendarCowList( ctx context.Context, calendarType pasturePb.CalendarType_Kind, showDay string, pagination *pasturePb.PaginationModel, pastureId int64, ) (interface{}, error) { req := &pasturePb.ItemsRequest{EndDay: showDay, CalendarType: calendarType, PastureId: int32(pastureId)} switch calendarType { case pasturePb.CalendarType_Immunisation: // 免疫 return s.ImmunisationCowList(ctx, req, pagination) case pasturePb.CalendarType_PG, pasturePb.CalendarType_RnGH: // 同期 return s.SameTimeCowList(ctx, req, pagination) case pasturePb.CalendarType_Pregnancy_Check: // 孕检 return s.PregnancyCheckCowList(ctx, req, pagination) case pasturePb.CalendarType_WorkOrder: // 工作单 return s.WorkOrderCowList(ctx, req, pagination) case pasturePb.CalendarType_Weaning: // 断奶 return s.WeaningCowList(ctx, req, pagination) case pasturePb.CalendarType_Treatment: // 治疗 return s.TreatmentCowList(ctx, req, pagination) case pasturePb.CalendarType_Mating: // 配种 return s.MatingCowList(ctx, req, pagination) case pasturePb.CalendarType_Calving: // 产犊 return s.CalvingCowList(ctx, req, pagination) default: return nil, xerr.New("不支持的日历类型") } } func (s *StoreEntry) ImmunisationCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.ImmunizationItemsResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventImmunizationPlanList := make([]*model.EventImmunizationPlan, 0) count := int64(0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventImmunizationPlan).TableName())). Select("a.id,a.cow_id,a.plan_day,a.plan_name as immunization_plan_name,b.pen_name,b.day_age,b.ear_number"). Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())). Where("a.status = ?", pasturePb.IsShow_No). Where("a.pasture_id = ?", userModel.AppPasture.Id) if req.StartDay != "" && req.EndDay != "" { startTime := util.TimeParseLocalUnix(req.StartDay) endTime := util.TimeParseLocalEndUnix(req.EndDay) pref.Where("a.plan_day between ? and ?", startTime, endTime) } if req.CowId > 0 { pref.Where("a.cow_id = ?", req.CowId) } if req.ImmunizationId > 0 { pref.Where("a.plan_id = ?", req.ImmunizationId) } if req.PenId > 0 { pref.Where("b.pen_id = ?", req.PenId) } 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 &pasturePb.ImmunizationItemsResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.ImmunizationItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "penName": "栏舍", "dayAge": "日龄", "planDay": "免疫时间", "immunizationPlanName": "免疫名称", }, List: model.EventImmunizationPlanSlice(eventImmunizationPlanList).ToPB(), }, }, nil } func (s *StoreEntry) SameTimeCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SameTimeItemResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } sameTimeBodyList := make([]*model.SameTimeItemBody, 0) count := int64(0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCowSameTime).TableName())). Select(`a.id,a.cow_id,a.ear_number,a.pen_name,a.status,a.same_time_type,b.breed_status,a.same_time_name,a.plan_day, b.cow_type,b.day_age,b.calving_age,b.abortion_age,b.last_calving_at,b.last_abortion_at,b.lact,b.pen_name,b.mating_times`). Joins("left join cow as b on a.cow_id = b.id"). Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("a.pasture_id = ?", userModel.AppPasture.Id). Where("a.status = ?", pasturePb.IsShow_No) if req.EndDay != "" { dateTime := util.TimeParseLocalEndUnix(req.EndDay) pref.Where("a.plan_day <= ?", dateTime) } if req.CowType > 0 { pref.Where("b.cow_type = ?", req.CowType) } if err = pref.Order("a.plan_day ASC").Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&sameTimeBodyList).Error; err != nil { return nil, xerr.WithStack(err) } breedStatusMap := s.CowBreedStatusMap() penMap := s.PenMap(ctx, int64(req.PastureId)) sameTimeTypeMap := s.SameTimeTypeMap() return &pasturePb.SameTimeItemResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.SameTimeItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "breedStatusName": "繁殖状态", "cowTypeName": "牛只类型", "planDayAtFormat": "执行日期", "penName": "栏舍", "lact": "胎次", "calvingAge": "产后天数", "abortionAge": "流产天数", "dayAge": "日龄", "status": "状态", "sameTimeTypeName": "处理方式", "matingTimes": "本胎次配次", "calvingAtFormat": "产犊日期", "abortionAtFormat": "流产日期", "sameTimeName": "同期名称", }, List: model.SameTimeBodySlice(sameTimeBodyList).ToPB(breedStatusMap, penMap, sameTimeTypeMap), }, }, nil } func (s *StoreEntry) PregnancyCheckCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnancyCheckItemsResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } newPregnancyCheckItems := make([]*pasturePb.PregnancyCheckItems, 0) var count int64 pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventPregnantCheck).TableName())). Select("a.id,a.cow_id,a.ear_number,a.pen_id,a.status,b.breed_status,b.pen_name,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). Where("a.pasture_id = ?", userModel.AppPasture.Id). Where("a.status = ?", pasturePb.IsShow_No) if req.EndDay != "" { dateTime := util.TimeParseLocalEndUnix(req.EndDay) pref.Where("a.plan_day <= ?", dateTime) } if req.CowType > 0 { pref.Where("a.cow_type = ?", req.CowType) } if req.Status > 0 { pref.Where("a.status = ?", req.Status) } if req.PregnantCheckType > 0 { pref.Where("a.pregnant_check_name = ?", model.PregnantCheckNameValueMap[req.PregnantCheckType]) } if err = pref.Order("a.plan_day ASC"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&newPregnancyCheckItems).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.PregnancyCheckItemsResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.PregnancyCheckItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "cowTypeName": "牛只类型", "penName": "栏舍", "lact": "胎次", "dayAge": "日龄", "planDay": "孕检日期", "checkTypeName": "孕检名称", "status": "状态", "matingTimes": "配次", "calvingAtFormat": "产检日期", "matingAtFormat": "配种日期", "matingAge": "配后天数", "bullId": "配种公牛", }, List: newPregnancyCheckItems, }, }, nil } func (s *StoreEntry) WeaningCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.WeaningItemsResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } weaningItems := make([]*pasturePb.WeaningItems, 0) count := int64(0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventWeaning).TableName())). Select("a.id,a.cow_id,b.current_weight as weight,a.status,b.birth_at,b.day_age,b.pen_name"). Joins("left join cow as b on a.cow_id = b.id"). Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("a.status = ?", pasturePb.IsShow_No). Where("a.pasture_id = ?", userModel.AppPasture.Id) if req.EndDay != "" { dateTime := util.TimeParseLocalEndUnix(req.EndDay) pref.Where("a.plan_day <= ?", dateTime) } if err = pref.Order("a.plan_day ASC").Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&weaningItems).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.WeaningItemsResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.WeaningItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "penName": "栏舍", "planDay": "断奶日期", "dayAge": "日龄", "status": "状态", "birthAt": "出生日期", "weight": "体重", }, List: weaningItems, }, }, nil } func (s *StoreEntry) MatingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingItemsResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } matingItems := make([]*pasturePb.MatingItems, 0) count := int64(0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventMating).TableName())). Select(`a.id,a.cow_id,a.status,a.ear_number, CASE a.expose_estrus_type WHEN 1 THEN '脖环揭发' WHEN 2 THEN '脚环/计步器' WHEN 3 THEN '自然发情' WHEN 4 THEN '同期' ELSE '其他' END AS expose_estrus_type_name, b.breed_status,b.cow_type,b.pen_id,b.day_age,b.calving_age,b.abortion_age,b.pen_name`). Joins("left join cow as b on a.cow_id = b.id"). Where("a.pasture_id = ?", userModel.AppPasture.Id). Where("a.status = ?", pasturePb.IsShow_No) if req.EndDay != "" { dateTime := util.TimeParseLocalEndUnix(req.EndDay) pref.Where("a.plan_day <= ?", dateTime) } if req.PenId > 0 { pref.Where("b.pen_id = ?", req.PenId) } if err = pref.Order("a.plan_day ASC"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&matingItems).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.MatingItemsResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.MatingItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "breedStatusName": "繁殖状态", "cowTypeName": "牛只类型", "penName": "栏舍", "lact": "胎次", "calvingAge": "产后天数", "abortionAge": "流产天数", "dayAge": "日龄", "status": "状态", "exposeEstrusTypeName": "发情揭发方式", }, List: matingItems, }, }, nil } func (s *StoreEntry) CalvingCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.CalvingItemsResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } calvingItems := make([]*pasturePb.CalvingItems, 0) count := int64(0) pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCalving).TableName())). Select(`a.id,a.cow_id,a.ear_number,a.status,b.breed_status,b.pen_id,DATE_FORMAT(FROM_UNIXTIME(last_mating_at), '%Y-%m-%d') AS mating_at_format, b.day_age,b.last_bull_number as bull_id,b.pen_name,DATEDIFF(NOW(),FROM_UNIXTIME(last_mating_at)) AS mating_age,DATE_FORMAT(FROM_UNIXTIME(a.plan_day), '%Y-%m-%d') AS plan_day`). Joins("left join cow as b on a.cow_id = b.id"). Where("a.status = ?", pasturePb.IsShow_No). Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("a.pasture_id = ?", userModel.AppPasture.Id) 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.plan_day ASC"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&calvingItems).Error; err != nil { return nil, xerr.WithStack(err) } breedStatusMap := s.CowBreedStatusMap() for _, v := range calvingItems { breedStatusName := "" if breedStatus, ok := breedStatusMap[v.BreedStatus]; ok { breedStatusName = breedStatus } v.BreedStatusName = breedStatusName } return &pasturePb.CalvingItemsResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.CalvingItemsData{ Total: int32(count), Page: pagination.Page, PageSize: pagination.PageSize, Header: map[string]string{ "id": "编号", "cowId": "牛号", "earNumber": "耳标号", "breedStatusName": "繁殖状态", "penName": "栏舍", "lact": "胎次", "matingAge": "配后天数", "dayAge": "日龄", "status": "是否完成", "bullId": "配种公牛号", "planDay": "预产时间", "matingAtFormat": "配种时间", }, List: calvingItems, }, }, nil } // WorkOrderCowList 暂时不处理工单业务 func (s *StoreEntry) WorkOrderCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (interface{}, error) { return nil, nil } // TreatmentCowList 治疗清单 func (s *StoreEntry) TreatmentCowList(ctx context.Context, req *pasturePb.ItemsRequest, pagination *pasturePb.PaginationModel) (interface{}, error) { return nil, nil }