package backend import ( "context" "fmt" "kpt-pasture/model" "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 { // 牛只信息 cow, err := s.GetCowInfoByCowId(ctx, 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("请检查操作人信息") } currUser, err := s.GetCurrentSystemUser(ctx) if err != nil { return xerr.Custom("登录信息错误,请退出重新登录") } disease, err := s.GetDiseaseById(ctx, req.DiseaseId) if err != nil { return xerr.WithStack(err) } newEventCowDisease := model.NewEventCowDisease(cow, disease, req, operationUser, currUser) defer func() { if req.PenId > 0 { s.UpdateCowPenId(ctx, int64(req.CowId), int64(req.PenId)) } // 更新牛只健康状态 if newEventCowDisease.HealthStatus == pasturePb.HealthStatus_Disease || newEventCowDisease.HealthStatus == pasturePb.HealthStatus_Treatment { s.DB.Model(new(model.Cow)). Where("id = ?", req.CowId). Updates(map[string]interface{}{ "health_status": pasturePb.HealthStatus_Disease, }) } }() // 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 } var newEventCowTreatment *model.EventCowTreatment var 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, req.PrescriptionId) if err != nil { return xerr.WithStack(err) } prescriptionDrugs, err := s.PrescriptionDrugsByPrescriptionId(ctx, 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 { if err = tx.Model(new(model.EventCowDisease)).Create(newEventCowDisease).Error; err != nil { return xerr.WithStack(err) } newEventCowTreatment.CowDiseaseId = newEventCowDisease.Id // 已有的处方使用次数+1 if req.PrescriptionId > 0 { if err = tx.Model(new(model.Prescription)).Where("id = ?", req.PrescriptionId). Update("use_count", gorm.Expr("use_count + 1")).Error; err != nil { return xerr.WithStack(err) } } // 新的临时处方 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(newPrescriptionRequest, fmt.Sprintf("%d", disease.Id), 1, 0, 0, currUser) newPrescription.UseCount += 1 if err = tx.Model(new(model.Prescription)).Create(newPrescription).Error; err != nil { return xerr.WithStack(err) } prescription = newPrescription newPrescriptionDrugs := model.NewPrescriptionDrugs(prescription.Id, req.PrescriptionDetail) if err = tx.Model(new(model.PrescriptionDrugs)).Create(newPrescriptionDrugs).Error; err != nil { return xerr.WithStack(err) } newEventCowTreatment.PrescriptionId = prescription.Id newEventCowTreatment.PrescriptionName = prescription.Name } // 创建治疗记录 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(prescription, newCowTreatmentRequest, diseaseTypeMap, operationUser, currUser) // 创建治疗记录 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 } // CowDiseaseList 发病牛只清单 func (s *StoreEntry) CowDiseaseList(ctx context.Context, req *pasturePb.SearchEventCowTreatmentRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowDiseaseResponse, error) { cowDiseaseList := make([]*model.EventCowDisease, 0) var count int64 = 0 pref := s.DB.Select("a.*,b.name").Table(fmt.Sprintf("%s as a", new(model.EventCowDisease).TableName())). Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())). Where("a.diagnosed_result < ?", pasturePb.IsShow_No) 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("a.pen_id = ?", req.PenId) } if req.Lact > 0 { pref.Where("a.lact = ?", req.Lact) } if req.MinDayAge > 0 && req.MaxDayAge > 0 && req.MaxDayAge >= req.MinDayAge { pref.Where("a.day_age BETWEEN ? AND ?", req.MinDayAge, req.MaxDayAge) } 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, Message: "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 { cow, err := s.GetCowInfoByCowId(ctx, int64(req.CowId)) if err != nil { return xerr.Customf("错误的牛只信息: %d", req.CowId) } eventCowDisease := &model.EventCowDisease{} if err = s.DB.Where("cow_id = ?", req.CowId). Where("id = ?", req.Id). Where("health_status = ?", pasturePb.HealthStatus_Health). First(eventCowDisease).Error; err != nil { return xerr.Custom("异常牛只数据") } currentUser, err := s.GetCurrentSystemUser(ctx) if err != nil { return xerr.WithStack(err) } if req.DiagnosedResult == pasturePb.IsShow_No { // 未发病更新 eventCowDisease.EventUnDiseaseUpdate(currentUser, 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, 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.EventDiseaseUpdate(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 { eventCowDisease := &model.EventCowDisease{} if err := s.DB.Where("cow_id = ?", req.CowId). 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("异常牛只数据") } systemUser, err := s.GetSystemUserById(ctx, int64(req.OperationId)) if err != nil { return xerr.Customf("操作人数据异常: %d", req.OperationId) } prescription, err := s.GetPrescriptionById(ctx, req.PrescriptionId) if err != nil { return xerr.WithStack(err) } currUser, err := s.GetCurrentSystemUser(ctx) if err != nil { return xerr.WithStack(err) } cow, err := s.GetCowInfoByCowId(ctx, int64(req.CowId)) if err != nil { return xerr.Customf("异常牛数据: %d", req.CowId) } disease, err := s.GetDiseaseById(ctx, eventCowDisease.DiagnoseId) if err != nil { return xerr.WithStack(err) } req.DiseaseName = disease.Name req.DiseaseType = disease.DiseaseType prescriptionDrugs, err := s.PrescriptionDrugsByPrescriptionId(ctx, 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(prescription, req, diseaseTypeMap, systemUser, currUser) if err = s.DB.Transaction(func(tx *gorm.DB) error { if err = tx.Create(newEventCowTreatment).Error; err != nil { return xerr.WithStack(err) } eventCowDisease.EventHealthStatusUpdate(healthStatus) if err = tx.Model(eventCowDisease). Select("health_status"). Where("id = ?", req.Id). Where("cow_id = ?", req.CowId). Updates(eventCowDisease).Error; err != nil { return xerr.WithStack(err) } cow.EventDiseaseUpdate(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) { res := make([]*pasturePb.ConfigOptionsList, 0) prescriptionList := make([]*model.Prescription, 0) if err := s.DB.Model(new(model.Prescription)).Where("is_show = ?", pasturePb.IsShow_Ok).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, Message: "ok", Data: res, }, nil } // CowDiseaseTreatmentDetail 发病牛只治疗详情列表 func (s *StoreEntry) CowDiseaseTreatmentDetail( ctx context.Context, req *pasturePb.EventCowTreatmentDetailRequest, pagination *pasturePb.PaginationModel, ) (*pasturePb.EventCowTreatmentDetailResponse, error) { eventCowDiseaseList := make([]*model.EventCowDisease, 0) var count int64 = 0 pref := s.DB.Model(new(model.EventCowDisease)). Where("cow_id = ?", req.CowId) 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, Message: "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 { eventCowDiseaseList := make([]*model.EventCowDisease, 0) if err := s.DB.Where("id IN ?", req.Ids). Where("health_status = ?", pasturePb.HealthStatus_Treatment). 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 { eventCowTreatmentList = append(eventCowTreatmentList, &model.EventCowTreatment{ CowId: v.CowId, CowDiseaseId: v.Id, DiseaseId: int64(v.DiseaseId), DiseaseName: v.DiseaseName, TreatmentResult: pasturePb.TreatmentResult_Curable, OperationId: operationUser.Id, OperationName: operationUser.Name, Remarks: req.Remarks, TreatmentAt: int64(req.CurableAt), }) } 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, eventCowDisease.CowId) if err != nil { return xerr.WithStack(err) } // 更新牛只健康状态 cow.EventDiseaseUpdate(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 }