package backend import ( "context" "fmt" "kpt-pasture/model" "kpt-pasture/util" "net/http" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/xerr" ) // PregnancyReport 孕检报告 func (s *StoreEntry) PregnancyReport(ctx context.Context, req *pasturePb.PregnancyReportRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnancyReportResponse, error) { startDayUnix := util.TimeParseLocalUnix(req.StartDayTime) endDayUnix := util.TimeParseLocalEndUnix(req.EndDayTime) if startDayUnix > endDayUnix || startDayUnix == 0 || endDayUnix == 0 { return nil, xerr.Custom("开始时间不能大于结束时间") } eventPregnantCheckList := make([]*model.EventPregnantCheck, 0) pref := s.DB.Model(new(model.EventPregnantCheck)).Where("status = ?", pasturePb.IsShow_Ok).Where("cow_type = ?", req.CowType) if startDayUnix > 0 && endDayUnix > 0 && endDayUnix >= startDayUnix { pref = pref.Where("create_time BETWEEN ? AND ?", startDayUnix, endDayUnix) } if req.PregnantCheckResult > 0 { pref = pref.Where("pregnant_check_result = ?", req.PregnantCheckResult) } var count int64 = 0 if err := pref.Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Order("id desc"). Find(&eventPregnantCheckList).Error; err != nil { return nil, xerr.WithStack(err) } pregnantCheckResultMap := s.PregnantCheckResultMap() pregnantCheckMethodMap := s.PregnantCheckMethodMap() return &pasturePb.PregnancyReportResponse{ Code: http.StatusOK, Message: "ok", Data: &pasturePb.PregnancyReportData{ List: model.EventPregnantCheckSlice(eventPregnantCheckList).ToPB3(pregnantCheckResultMap, pregnantCheckMethodMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } // CalvingReport 产犊报告 func (s *StoreEntry) CalvingReport(ctx context.Context, req *pasturePb.CalvingReportRequest) (*pasturePb.CalvingReportResponse, error) { lastDayOfMonth, err := util.GetLastDayOfMonth(req.EndDayTime) if err != nil { return nil, xerr.WithStack(err) } endDayTimeUnix := util.TimeParseLocalEndUnix(lastDayOfMonth) startDayTimeUnix := util.TimeParseLocalUnix(fmt.Sprintf("%s-01", req.StartDayTime)) if startDayTimeUnix == 0 || endDayTimeUnix == 0 || endDayTimeUnix <= startDayTimeUnix { return nil, xerr.Custom("开始时间不能大于结束时间") } eventCalving1 := make([]*pasturePb.CalvingReportTable, 0) pref1 := s.DB.Model(new(model.EventCalving)). Select(fmt.Sprint(`DATE_FORMAT(FROM_UNIXTIME(reality_day), '%Y-%m') AS statistic_method,cow_kind,`)+fmt.Sprintf( `SUM(child_number) AS totalCount, SUM(CASE WHEN child_number > 1 THEN child_number ELSE 0 END) AS twins, SUM(CASE WHEN pregnancy_age <= %d THEN 1 ELSE 0 END) AS premature_labor_count, SUM(CASE WHEN pregnancy_age >= %d THEN 1 ELSE 0 END) AS late_labor_count, count(*) as total_count`, req.PrematureLabor, req.LateLabor), ).Where("reality_day BETWEEN ? AND ? ", startDayTimeUnix, endDayTimeUnix) if req.AnalysisMethod > 0 { switch req.AnalysisMethod { case pasturePb.CalvingAnalysisMethod_Months: pref1.Group("statistic_method").Order("statistic_method") case pasturePb.CalvingAnalysisMethod_CowKind: pref1.Group("cow_kind").Order("cow_kind") } } if err = pref1.Find(&eventCalving1).Error; err != nil { return nil, xerr.WithStack(err) } eventCalving2 := make([]*pasturePb.CalvingReportTable, 0) pref2 := s.DB.Model(new(model.CalvingCalf)). Select(fmt.Sprint(`DATE_FORMAT(FROM_UNIXTIME(birth_at), '%Y-%m') AS statistic_method, cow_kind, SUM(CASE WHEN sex = 1 THEN 1 ELSE 0 END) AS bulls, SUM(CASE WHEN sex = 2 THEN 1 ELSE 0 END) AS cows, SUM(CASE WHEN is_live = 1 THEN 1 ELSE 0 END) AS survive_count, SUM(CASE WHEN is_live = 2 THEN 1 ELSE 0 END) AS die_count, SUM(CASE WHEN is_live = 2 AND sex = 1 THEN 1 ELSE 0 END) AS bulls_die_count, SUM(CASE WHEN is_live = 2 AND sex = 2 THEN 1 ELSE 0 END) AS cows_die_count, SUM(CASE WHEN is_adoption = 1 THEN 1 ELSE 0 END) AS adopt_count`)). Where("birth_at BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix) if req.AnalysisMethod > 0 { switch req.AnalysisMethod { case pasturePb.CalvingAnalysisMethod_Months: pref2.Group("statistic_method").Order("statistic_method") case pasturePb.CalvingAnalysisMethod_CowKind: pref2.Group("cow_kind").Order("cow_kind") } } if err = pref2.Find(&eventCalving2).Error; err != nil { return nil, xerr.WithStack(err) } // 合并数据集 for _, v1 := range eventCalving1 { for _, v2 := range eventCalving2 { if v1.StatisticMethod != v2.StatisticMethod && v1.CowKind != v2.CowKind { continue } v1.Bulls = v2.Bulls v1.Cows = v2.Cows v1.SurviveCount = v2.SurviveCount v1.DieCount = v2.DieCount v1.BullsDieCount = v2.BullsDieCount v1.CowsDieCount = v2.CowsDieCount v1.AdoptCount = v2.AdoptCount } } cowKindMap := s.CowKindMap() for _, v := range eventCalving1 { if req.AnalysisMethod == pasturePb.CalvingAnalysisMethod_CowKind { v.StatisticMethod = cowKindMap[v.CowKind] } if v.TotalCount > 0 { v.TwinsRate = float32(util.RoundToTwoDecimals(float64(v.Twins) / float64(v.TotalCount) * 100)) v.BullsDieRate = float32(util.RoundToTwoDecimals(float64(v.Bulls) / float64(v.TotalCount) * 100)) v.CowsRate = float32(util.RoundToTwoDecimals(float64(v.Cows) / float64(v.TotalCount) * 100)) v.DieRate = float32(util.RoundToTwoDecimals(float64(v.DieCount) / float64(v.TotalCount) * 100)) } if v.Bulls > 0 { v.BullsDieRate = float32(util.RoundToTwoDecimals(float64(v.BullsDieCount) / float64(v.Bulls) * 100)) } if v.Cows > 0 { v.CowsDieRate = float32(util.RoundToTwoDecimals(float64(v.CowsDieCount) / float64(v.Cows) * 100)) } v.NormalLaborCount = v.TotalCount - (v.PrematureLaborCount + v.LateLaborCount) if v.NormalLaborCount <= 0 { v.NormalLaborCount = 0 } } return &pasturePb.CalvingReportResponse{ Code: http.StatusOK, Message: "ok", Data: &pasturePb.CalvingReportData{ List: eventCalving1, Total: int32(len(eventCalving1)), }, }, nil } func (s *StoreEntry) DiseaseCureReport(ctx context.Context, req *pasturePb.DiseaseCureRateRequest) (*pasturePb.DiseaseCureRateResponse, error) { lastDayOfMonth, err := util.GetLastDayOfMonth(req.EndDayTime) if err != nil { return nil, xerr.WithStack(err) } endDayTimeUnix := util.TimeParseLocalEndUnix(lastDayOfMonth) startDayTimeUnix := util.TimeParseLocalUnix(fmt.Sprintf("%s-01", req.StartDayTime)) if startDayTimeUnix == 0 || endDayTimeUnix == 0 || endDayTimeUnix <= startDayTimeUnix { return nil, xerr.Custom("开始时间不能大于结束时间") } diseaseCureRateList1 := make([]*pasturePb.DiseaseCureRateList, 0) diseaseCureRateList2 := make([]*pasturePb.DiseaseCureRateList, 0) pref1 := s.DB.Model(new(model.EventCowDisease)). Select( fmt.Sprint(`DATE_FORMAT(FROM_UNIXTIME(diagnosed_at), '%Y-%m') AS months,`)+ fmt.Sprintf(` diagnose_id as disease_id, diagnose_name as disease_name, diagnose_operation_id as operation_id, diagnose_operation_name as operation_name, disease_type, COUNT(DISTINCT CASE WHEN health_status = %d THEN cow_id END) AS disease_treatment_count, -- 治疗头数 COUNT(DISTINCT CASE WHEN health_status = %d AND curable_at > 0 THEN cow_id END) AS disease_cure_count, -- 治愈头数 COUNT(DISTINCT CASE WHEN diagnosed_result = %d THEN cow_id END) AS disease_count, -- 发病数 COUNT(DISTINCT CASE WHEN health_status IN (%d, %d) THEN cow_id END) AS die_out_count, -- 死淘数 COUNT(DISTINCT CASE WHEN health_status = %d AND TIMESTAMPDIFF(DAY, FROM_UNIXTIME(disease_at), FROM_UNIXTIME(curable_at)) <= 7 THEN cow_id END) AS seven_cure_count, -- 7天内治愈头数 COUNT(DISTINCT CASE WHEN health_status = %d AND TIMESTAMPDIFF(DAY, FROM_UNIXTIME(disease_at), FROM_UNIXTIME(curable_at)) <= 14 THEN cow_id END) AS seventeen_cure_count, -- 14天内治愈头数 COUNT(DISTINCT CASE WHEN health_status = %d AND TIMESTAMPDIFF(DAY, FROM_UNIXTIME(disease_at), FROM_UNIXTIME(curable_at)) <= 30 THEN cow_id END) AS thirty_cure_count -- 30天内治愈头数 `, pasturePb.HealthStatus_Treatment, pasturePb.HealthStatus_Curable, pasturePb.IsShow_Ok, pasturePb.HealthStatus_Out, pasturePb.HealthStatus_Dead, pasturePb.HealthStatus_Curable, pasturePb.HealthStatus_Curable, pasturePb.HealthStatus_Curable, )). Where("diagnosed_result = ?", pasturePb.IsShow_Ok). Where("diagnosed_at BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix) if req.CowType > 0 { pref1.Where("cow_type = ?", req.CowType) } pref2 := s.DB.Model(new(model.EventCowTreatment)). Select(` DATE_FORMAT(FROM_UNIXTIME(treatment_at), '%Y-%m') AS months, disease_id, disease_name, disease_type, prescription_id, prescription_name, operation_id, operation_name, COUNT(DISTINCT cow_id) AS disease_treatment_count`, ).Where("treatment_at BETWEEN ? AND ?", startDayTimeUnix, endDayTimeUnix) switch req.AnalysisMethod { case pasturePb.DiseaseAnalysisMethod_Months: pref1.Where("diagnosed_at > 0").Group("months").Order("months") pref2.Where("treatment_at > 0").Group("months").Order("months") case pasturePb.DiseaseAnalysisMethod_Disease_Category: pref1.Where("disease_type > 0").Group("disease_type").Order("disease_type") pref2.Where("disease_type > 0").Group("disease_type").Order("disease_type") case pasturePb.DiseaseAnalysisMethod_Disease: pref1.Where("diagnose_id > 0").Group("diagnose_id").Order("diagnose_id") pref2.Where("disease_id > 0").Group("disease_id").Order("disease_id") case pasturePb.DiseaseAnalysisMethod_Operator: pref1.Where("diagnose_operation_id > 0").Group("diagnose_operation_id").Order("diagnose_operation_id") pref2.Where("operation_id > 0").Group("operation_id").Order("operation_id") default: return nil, xerr.Custom("请选择统计方式") } if err = pref1.Find(&diseaseCureRateList1).Error; err != nil { return nil, xerr.WithStack(err) } if err = pref2.Find(&diseaseCureRateList2).Error; err != nil { return nil, xerr.WithStack(err) } for _, v1 := range diseaseCureRateList1 { for _, v2 := range diseaseCureRateList2 { switch req.AnalysisMethod { case pasturePb.DiseaseAnalysisMethod_Months: if v1.Months != v2.Months { continue } v1.DiseaseTreatmentCount = v2.DiseaseTreatmentCount case pasturePb.DiseaseAnalysisMethod_Disease_Category: if v1.DiseaseType != v2.DiseaseType { continue } v1.DiseaseTreatmentCount = v2.DiseaseTreatmentCount case pasturePb.DiseaseAnalysisMethod_Disease: if v1.DiseaseId != v2.DiseaseId { continue } v1.DiseaseTreatmentCount = v2.DiseaseTreatmentCount case pasturePb.DiseaseAnalysisMethod_Operator: if v1.OperationId != v2.OperationId { continue } v1.DiseaseTreatmentCount = v2.DiseaseTreatmentCount case pasturePb.DiseaseAnalysisMethod_Prescription: if v1.PrescriptionId != v2.PrescriptionId { continue } v1.DiseaseTreatmentCount = v2.DiseaseTreatmentCount } } } chart := &pasturePb.DiseaseCureRateChart{ Headers: make([]string, 0), DiseaseCureCount: make([]int32, 0), DiseaseCureRate: make([]float32, 0), DiseaseCount: make([]int32, 0), } for _, v := range diseaseCureRateList1 { switch req.AnalysisMethod { case pasturePb.DiseaseAnalysisMethod_Months: v.StatisticMethod = v.Months case pasturePb.DiseaseAnalysisMethod_Disease_Category: diseaseTypeMap := s.DiseaseTypeMap() v.StatisticMethod = diseaseTypeMap[v.DiseaseType] case pasturePb.DiseaseAnalysisMethod_Disease: v.StatisticMethod = v.DiseaseName case pasturePb.DiseaseAnalysisMethod_Operator: v.StatisticMethod = v.OperationName case pasturePb.DiseaseAnalysisMethod_Prescription: v.StatisticMethod = v.PrescriptionName } chart.Headers = append(chart.Headers, v.StatisticMethod) chart.DiseaseCureCount = append(chart.DiseaseCureCount, v.DiseaseTreatmentCount) diseaseCureRate := float32(0) if v.DiseaseTreatmentCount > 0 { diseaseCureRate = float32(util.RoundToTwoDecimals(float64(v.DiseaseCureCount) / float64(v.DiseaseCount) * 100)) } chart.DiseaseCureRate = append(chart.DiseaseCureRate, diseaseCureRate) chart.DiseaseCount = append(chart.DiseaseCount, v.DiseaseCount) } return &pasturePb.DiseaseCureRateResponse{ Code: http.StatusOK, Message: "ok", Data: &pasturePb.DiseaseCureRateData{ List: diseaseCureRateList1, Chart: chart, }, }, nil }