package backend import ( "context" "fmt" "kpt-pasture/model" "kpt-pasture/util" "net/http" "strings" "time" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "go.uber.org/zap" "gorm.io/gorm" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/xerr" ) // CowDiseaseCreate 牛只发病提交 func (s *StoreEntry) CowDiseaseCreate(ctx context.Context, req *pasturePb.EventCowDiseaseRequest, source string) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } // 牛只信息 cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { return xerr.Customf("牛只信息错误: %d", req.CowId) } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("请检查操作人信息") } disease, err := s.GetDiseaseById(ctx, userModel.AppPasture.Id, req.DiseaseId) if err != nil { return xerr.WithStack(err) } newEventCowDisease := model.NewEventCowDisease(userModel.AppPasture.Id, cow, disease, req, operationUser, userModel.SystemUser) defer func() { // 更新牛只健康状态 if newEventCowDisease.HealthStatus == pasturePb.HealthStatus_Disease || newEventCowDisease.HealthStatus == pasturePb.HealthStatus_Treatment { cow.EventHealthStatusUpdate(pasturePb.HealthStatus_Disease) if err = s.DB.Model(new(model.Cow)). Select("health_status"). Where("id = ?", req.CowId). Updates(cow).Error; err != nil { zaplog.Error("CowDiseaseCreate", zap.Any("EventHealthStatusUpdate", err)) } } if req.PenId > 0 { penMap := s.PenMap(ctx, userModel.AppPasture.Id) penData, ok := penMap[req.PenId] if !ok { return } cow.EventPenUpdate(penData) if err = s.DB.Model(new(model.Cow)). Select("pen_id", "pen_name"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { zaplog.Error("CowDiseaseCreate", zap.Any("EventPenUpdate", err)) } } }() // PC端直接跳过诊断过程 if source == model.SourcePC { newEventCowDisease.DiagnosedResult = pasturePb.IsShow_Ok newEventCowDisease.DiagnoseOperationId = int32(operationUser.Id) newEventCowDisease.DiagnoseOperationName = operationUser.Name newEventCowDisease.Source = model.SourcePC newEventCowDisease.DiagnoseId = req.DiseaseId newEventCowDisease.DiagnoseName = disease.Name newEventCowDisease.HealthStatus = pasturePb.HealthStatus_Disease } if req.PrescriptionId > 0 || len(req.PrescriptionDetail) > 0 { newEventCowDisease.HealthStatus = pasturePb.HealthStatus_Treatment newEventCowDisease.DiagnosedResult = pasturePb.IsShow_Ok newEventCowDisease.FirstTreatmentAt = int64(req.DiseaseAt) newEventCowDisease.LastTreatmentAt = int64(req.DiseaseAt) } newEventCowTreatment := &model.EventCowTreatment{} newCowTreatmentRequest := &pasturePb.CowTreatmentRequest{} var isCreatePrescription bool diseaseTypeMap := s.DiseaseTypeMap() prescription := &model.Prescription{} if req.PrescriptionId > 0 || len(req.PrescriptionDetail) > 0 { isCreatePrescription = true if req.PrescriptionId > 0 { prescription, err = s.GetPrescriptionById(ctx, userModel.AppPasture.Id, req.PrescriptionId) if err != nil { return xerr.WithStack(err) } prescriptionDrugs, err := s.PrescriptionDrugsByPrescriptionId(ctx, userModel.AppPasture.Id, prescription.Id) if err != nil { return xerr.WithStack(err) } req.PrescriptionDetail = model.PrescriptionDrugsSlice(prescriptionDrugs).ToPB() } } if err = s.DB.Transaction(func(tx *gorm.DB) error { lastPrescriptionName := "" // 已有的处方使用次数+1 if req.PrescriptionId > 0 { prescription.EventUseCountUpdate() if err = tx.Model(new(model.Prescription)). Where("id = ?", prescription.Id). Updates(prescription).Error; err != nil { return xerr.WithStack(err) } lastPrescriptionName = prescription.Name } // 新的临时处方 if req.PrescriptionId <= 0 && len(req.PrescriptionDetail) > 0 { newPrescriptionRequest := &pasturePb.PrescriptionRequest{ Name: fmt.Sprintf("%s-%s-%s", disease.Name, time.Now().Format("20060102"), operationUser.Name), ApplicableDiseaseIds: []int32{req.DiseaseId}, IsShow: pasturePb.IsShow_Ok, } newPrescription := model.NewPrescription( userModel.AppPasture.Id, newPrescriptionRequest, fmt.Sprintf("%d", disease.Id), 1, 0, 0, userModel.SystemUser, ) newPrescription.UseCount += 1 if err = tx.Model(new(model.Prescription)).Create(newPrescription).Error; err != nil { return xerr.WithStack(err) } prescription = newPrescription lastPrescriptionName = newPrescription.Name newPrescriptionDrugs := model.NewPrescriptionDrugs(userModel.AppPasture.Id, prescription.Id, req.PrescriptionDetail) if err = tx.Model(new(model.PrescriptionDrugs)).Create(newPrescriptionDrugs).Error; err != nil { return xerr.WithStack(err) } } // 创建 CowDisease newEventCowDisease.LastPrescriptionName = lastPrescriptionName if err = tx.Model(new(model.EventCowDisease)).Create(newEventCowDisease).Error; err != nil { return xerr.WithStack(err) } // 创建治疗记录 if isCreatePrescription { newCowTreatmentRequest = &pasturePb.CowTreatmentRequest{ CowId: req.CowId, PrescriptionId: prescription.Id, DiseaseId: req.DiseaseId, DiseaseName: disease.Name, DiseaseType: disease.DiseaseType, PrescriptionDetail: req.PrescriptionDetail, TreatmentResult: pasturePb.TreatmentResult_GoOn, Remarks: req.Remarks, TreatmentAt: req.DiseaseAt, } newEventCowTreatment = model.NewEventCowTreatment(userModel.AppPasture.Id, prescription, newCowTreatmentRequest, diseaseTypeMap, operationUser, userModel.SystemUser) newEventCowTreatment.CowDiseaseId = newEventCowDisease.Id // 创建治疗记录 if err = tx.Model(new(model.EventCowTreatment)).Create(newEventCowTreatment).Error; err != nil { return xerr.WithStack(err) } } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) EstrusCowList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventEstrusResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } var count int64 neckRingEstrusList := make([]*model.NeckRingEstrus, 0) pref := s.DB.Model(new(model.NeckRingEstrus)). Where("pasture_id = ?", userModel.AppPasture.Id). Where("is_show = ?", pasturePb.IsShow_Ok) if len(req.CowIds) > 0 { cowIds := strings.Split(util.ArrayInt32ToStrings(req.CowIds, ","), ",") pref.Where("cow_id IN ?", cowIds) } if req.Level > 0 { pref.Where("level = ?", req.Level) } if len(req.PenIds) > 0 { penIds := strings.Split(util.ArrayInt32ToStrings(req.PenIds, ","), ",") pref.Where("pen_id IN ?", penIds) } if err = pref.Order("level desc"). Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&neckRingEstrusList).Error; err != nil { return nil, xerr.WithStack(err) } cowMap := make(map[int64]*model.Cow) eventLogMap := make(map[int64]string) cowIds := make([]int64, 0) for _, v := range neckRingEstrusList { cowIds = append(cowIds, v.CowId) lastEventLog := s.GetCowLastEvent(userModel.AppPasture.Id, v.CowId, pasturePb.EventCategory_Breed) if lastEventLog != nil { eventLogMap[v.CowId] = lastEventLog.EventDescription } } if len(cowIds) > 0 { cowList, _ := s.GetCowInfoByCowIds(ctx, userModel.AppPasture.Id, cowIds) for _, cow := range cowList { cowMap[cow.Id] = cow } } return &pasturePb.EventEstrusResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EstrusItemsData{ List: model.NeckRingEstrusSlice(neckRingEstrusList).ToPB(cowMap, eventLogMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } // CowDiseaseList 发病牛只清单 func (s *StoreEntry) CowDiseaseList(ctx context.Context, req *pasturePb.SearchEventCowTreatmentRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowDiseaseResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } cowDiseaseList := make([]*model.EventCowDisease, 0) var count int64 = 0 pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCowDisease).TableName())). Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())). Select("a.*,b.pen_name"). Where("a.pasture_id = ?", userModel.AppPasture.Id) if len(req.CowIds) > 0 { pref.Where("a.cow_id IN ?", req.CowIds) } if req.DiseaseId > 0 { pref.Where("a.disease_id = ?", req.DiseaseId) } if req.PenId > 0 { pref.Where("b.pen_id = ?", req.PenId) } if req.HealthStatus > 0 { pref.Where("a.health_status = ?", req.HealthStatus) } if req.DiseasedStartAt > 0 && req.DiseaseEndAt > 0 && req.DiseaseEndAt >= req.DiseasedStartAt { pref.Where("a.disease_at BETWEEN ? AND ?", req.DiseasedStartAt, req.DiseaseEndAt) } if err = pref.Order("a.id desc"). Count(&count).Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Find(&cowDiseaseList).Error; err != nil { return nil, xerr.WithStack(err) } healthStatusMap := s.HealthStatusMap() return &pasturePb.EventCowDiseaseResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EventCowDiseaseData{ List: model.EventCowDiseaseSlice(cowDiseaseList).ToPB(healthStatusMap), Total: int32(count), PageSize: pagination.PageSize, Page: pagination.Page, }, }, nil } // CowDiseaseDiagnose 发病牛只诊断 func (s *StoreEntry) CowDiseaseDiagnose(ctx context.Context, req *pasturePb.CowDiagnosedRequest) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { return xerr.Customf("错误的牛只信息: %d", req.CowId) } eventCowDisease := &model.EventCowDisease{} if err = s.DB.Model(new(model.EventCowDisease)). Where("cow_id = ?", req.CowId). Where("id = ?", req.Id). Where("health_status = ?", pasturePb.HealthStatus_Health). Where("pasture_id = ?", userModel.AppPasture.Id). First(eventCowDisease).Error; err != nil { zaplog.Error("CowDiseaseDiagnose", zap.Any("req", req), zap.Any("userModel", userModel)) return xerr.Custom("异常牛只数据") } if eventCowDisease == nil || eventCowDisease.Id <= 0 { return xerr.Custom("异常牛只数据") } if req.DiagnosedResult == pasturePb.IsShow_No { // 未发病更新 eventCowDisease.EventUnDiseaseUpdate(userModel.SystemUser, req.Remarks) if err = s.DB.Model(eventCowDisease). Select("diagnosed_result", "diagnose_operation_id", "diagnose_operation_name", "remarks"). Where("id = ?", req.Id). Updates(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } return nil } // 已发病 disease, err := s.GetDiseaseById(ctx, userModel.AppPasture.Id, req.DiseaseId) if err != nil { return xerr.WithStack(err) } systemUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.WithStack(err) } if err = s.DB.Transaction(func(tx *gorm.DB) error { eventCowDisease.EventDiseaseUpdate(disease, systemUser, req.Temperature) if err = tx.Model(eventCowDisease). Select("health_status", "diagnosed_result", "diagnose_id", "diagnose_name", "temperature", "diagnose_operation_id", "diagnose_operation_name", "diagnosed_at"). Where("id = ?", req.Id). Where("cow_id = ?", req.CowId). Updates(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } cow.EventHealthStatusUpdate(pasturePb.HealthStatus_Disease) if err = tx.Model(cow). Select("health_status"). Where("id = ?", cow.Id). Updates(cow).Error; err != nil { return xerr.WithStack(err) } return nil }); err != nil { return xerr.WithStack(err) } return nil } // CowDiseaseTreatment 发病牛只治疗 func (s *StoreEntry) CowDiseaseTreatment(ctx context.Context, req *pasturePb.CowTreatmentRequest) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } // 牛只疾病信息 eventCowDisease := &model.EventCowDisease{} if err = s.DB.Where("cow_id = ?", req.CowId). Where("pasture_id = ?", userModel.AppPasture.Id). Where("id = ?", req.Id). First(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } if eventCowDisease.HealthStatus != pasturePb.HealthStatus_Disease && eventCowDisease.HealthStatus != pasturePb.HealthStatus_Treatment { return xerr.Custom("异常牛只数据") } cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(req.CowId)) if err != nil { return xerr.WithStack(err) } // 操作人信息 operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("操作人数据异常: %d", req.OperationId) } // 处方信息 prescription, err := s.GetPrescriptionById(ctx, userModel.AppPasture.Id, req.PrescriptionId) if err != nil { return xerr.WithStack(err) } // 疾病信息 disease, err := s.GetDiseaseById(ctx, userModel.AppPasture.Id, eventCowDisease.DiseaseId) if err != nil { return xerr.WithStack(err) } req.DiseaseName = disease.Name req.DiseaseType = disease.DiseaseType // 处方信息 prescriptionDrugs, err := s.PrescriptionDrugsByPrescriptionId(ctx, userModel.AppPasture.Id, prescription.Id) if err != nil { return xerr.WithStack(err) } // 处方详情 unitMap := s.UnitMap() prescriptionDetail := make([]*pasturePb.PrescriptionDrugsList, len(prescriptionDrugs)) for i, v := range prescriptionDrugs { prescriptionDetail[i] = &pasturePb.PrescriptionDrugsList{ DrugsId: int32(v.DrugsId), DrugsName: v.DrugsName, Unit: v.Unit, UnitName: unitMap[v.Unit], Dosages: v.Dosages, } } req.PrescriptionDetail = prescriptionDetail healthStatus := pasturePb.HealthStatus_Treatment if req.TreatmentResult == pasturePb.TreatmentResult_Curable { healthStatus = pasturePb.HealthStatus_Curable } if req.TreatmentResult == pasturePb.TreatmentResult_Out { healthStatus = pasturePb.HealthStatus_Out } if req.TreatmentResult == pasturePb.TreatmentResult_Dead { healthStatus = pasturePb.HealthStatus_Dead } diseaseTypeMap := s.DiseaseTypeMap() newEventCowTreatment := model.NewEventCowTreatment(userModel.AppPasture.Id, prescription, req, diseaseTypeMap, operationUser, userModel.SystemUser) if err = s.DB.Transaction(func(tx *gorm.DB) error { if err = tx.Create(newEventCowTreatment).Error; err != nil { return xerr.WithStack(err) } eventCowDisease.EventTreatmentUpdate(healthStatus, int64(req.TreatmentAt), prescription.Name) if err = tx.Model(eventCowDisease). Select("health_status", "first_treatment_at", "last_treatment_at", "last_prescription_name"). Where("id = ?", req.Id). Where("cow_id = ?", req.CowId). Updates(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } cow.EventHealthStatusUpdate(healthStatus) if err = tx.Model(new(model.Cow)). Select("health_status"). Where("id = ?", req.CowId). Updates(cow).Error; err != nil { return xerr.WithStack(err) } prescription.EventUseCountUpdate() if err = tx.Model(prescription). Select("use_count"). Where("id = ?", prescription.Id). Updates(prescription).Error; err != nil { return xerr.WithStack(err) } return nil }); err != nil { return xerr.WithStack(err) } return nil } func (s *StoreEntry) DiseaseSuggestPrescription(ctx context.Context, diseaseId int64) (*pasturePb.ConfigOptionsListResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } res := make([]*pasturePb.ConfigOptionsList, 0) prescriptionList := make([]*model.Prescription, 0) if err = s.DB.Model(new(model.Prescription)). Where("is_show = ?", pasturePb.IsShow_Ok). Where("pasture_id = ?", userModel.AppPasture.Id). Find(&prescriptionList).Error; err != nil { return nil, xerr.WithStack(err) } for _, v := range prescriptionList { disabled := false if strings.Contains(v.ApplicableDisease, fmt.Sprintf("%d", diseaseId)) { disabled = true } res = append(res, &pasturePb.ConfigOptionsList{ Value: v.Id, Label: v.Name, Disabled: disabled, }) } return &pasturePb.ConfigOptionsListResponse{ Code: http.StatusOK, Msg: "ok", Data: res, }, nil } // CowDiseaseTreatmentDetail 发病牛只治疗详情列表 func (s *StoreEntry) CowDiseaseTreatmentDetail( ctx context.Context, req *pasturePb.EventCowTreatmentDetailRequest, pagination *pasturePb.PaginationModel, ) (*pasturePb.EventCowTreatmentDetailResponse, error) { userModel, err := s.GetUserModel(ctx) if err != nil { return nil, xerr.WithStack(err) } eventCowDiseaseList := make([]*model.EventCowDisease, 0) var count int64 = 0 pref := s.DB.Model(new(model.EventCowDisease)). Where("cow_id = ?", req.CowId).Where("pasture_id = ?", userModel.AppPasture.Id) if req.DiseaseId > 0 { pref.Where("disease_id = ?", req.DiseaseId) } if req.DiseaseStartAt > 0 && req.DiseaseEndAt > 0 && req.DiseaseStartAt <= req.DiseaseEndAt { pref.Where("disease_at BETWEEN ? AND ?", req.DiseaseStartAt, req.DiseaseEndAt) } if err = pref.Count(&count). Limit(int(pagination.PageSize)). Offset(int(pagination.PageOffset)). Order("id desc"). Find(&eventCowDiseaseList).Error; err != nil { return nil, xerr.WithStack(err) } eventCowTreatmentList := make([]*model.EventCowTreatment, 0) cowDiseaseIds := make([]int64, len(eventCowDiseaseList)) for i, v := range eventCowDiseaseList { cowDiseaseIds[i] = v.Id } if err := s.DB.Model(new(model.EventCowTreatment)). Where("cow_disease_id IN ?", cowDiseaseIds). Where("cow_id = ?", req.CowId). Group("cow_disease_id"). Order("id desc"). Find(&eventCowTreatmentList).Error; err != nil { return nil, xerr.WithStack(err) } return &pasturePb.EventCowTreatmentDetailResponse{ Code: http.StatusOK, Msg: "ok", Data: &pasturePb.EventCowTreatmentDetail{ List: model.EventCowTreatmentSlice(eventCowTreatmentList).ToPB(eventCowDiseaseList), Total: int32(count), PageSize: pagination.Page, Page: pagination.PageSize, }, }, nil } func (s *StoreEntry) CowDiseaseCurable(ctx context.Context, req *pasturePb.EventCowCurableRequest) error { userModel, err := s.GetUserModel(ctx) if err != nil { return xerr.WithStack(err) } eventCowDiseaseList := make([]*model.EventCowDisease, 0) if err = s.DB.Where("id IN ?", req.Ids). Where("health_status = ?", pasturePb.HealthStatus_Treatment). Where("pasture_id = ?", userModel.AppPasture.Id). Find(&eventCowDiseaseList).Error; err != nil { zaplog.Error("GetEventCowDiseaseList", zap.Any("err", err), zap.Any("req", req)) return xerr.Custom("异常数据") } if len(eventCowDiseaseList) == 0 { return nil } operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("该用户不存在: %d", req.OperationId) } eventCowTreatmentList := make([]*model.EventCowTreatment, 0) for _, v := range eventCowDiseaseList { newEventCowTreatment := model.NewEventCowCurableTreatment(userModel.AppPasture.Id, userModel.SystemUser, operationUser, v, req.Remarks, int64(req.CurableAt)) eventCowTreatmentList = append(eventCowTreatmentList, newEventCowTreatment) } if len(eventCowTreatmentList) <= 0 { return nil } if err = s.DB.Transaction(func(tx *gorm.DB) error { cow := &model.Cow{} for _, eventCowDisease := range eventCowDiseaseList { eventCowDisease.EventCurableUpdate(int64(req.CurableAt)) if err = tx.Model(eventCowDisease). Select("health_status", "diagnosed_result", "curable_at"). Where("id = ?", eventCowDisease.Id). Where("health_status = ?", pasturePb.HealthStatus_Treatment). Updates(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } cow, err = s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, eventCowDisease.CowId) if err != nil { return xerr.WithStack(err) } // 更新牛只健康状态 cow.EventHealthStatusUpdate(pasturePb.HealthStatus_Curable) if err = tx.Model(cow). Select("health_status"). Where("id = ?", eventCowDisease.CowId). Updates(cow).Error; err != nil { return xerr.WithStack(err) } } if err = tx.Model(new(model.EventCowTreatment)).Create(eventCowTreatmentList).Error; err != nil { return xerr.WithStack(err) } return nil }); err != nil { return xerr.WithStack(err) } return nil }