package service import ( "context" "encoding/json" "errors" "gorm.io/gorm" "log/slog" ) import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" "gorm.io/datatypes" ) import ( "protocol-server/common" "protocol-server/models" pb "protocol-server/rpc_idl/dr_protocol_pb" ) var nilStruct *structpb.Struct func init() { var err error nilStruct, err = structpb.NewStruct(map[string]any{}) if err != nil { panic(err) } } func Json2Struct(o *datatypes.JSON) *structpb.Struct { var tempMap map[string]interface{} err := json.Unmarshal(*o, &tempMap) if err != nil { slog.Error("Error unmarshalling datatypes.JSON to map", "err", err) return nilStruct } protoStruct, err := structpb.NewStruct(tempMap) if err != nil { slog.Error("Error creating proto struct", "err", err) return nilStruct } return protoStruct } type ProtocolServer struct { pb.UnimplementedProtocolServer } func (s *ProtocolServer) GetPatientType(ctx context.Context, in *pb.PatientTypeRequest) (*pb.PatientTypeReply, error) { product, _, _ := common.GetHeader(ctx) res := pb.PatientTypeReply{} err := models.DB.Model(&models.PatientType{}).Scopes( models.String("product = ?", product.ToString()), models.Bool("is_enabled = ?", in.IsEnabled), ).Order("sort").Find(&res.PatientTypeList).Error if err != nil { return nil, status.Errorf(codes.Internal, "patient_type find err %v", err) } for _, pt := range res.GetPatientTypeList() { pt.PatientTypeLocal = pt.PatientTypeName } return &res, nil } func (s *ProtocolServer) GetBodyPart(ctx context.Context, in *pb.BodyPartRequest) (*pb.BodyPartReply, error) { product, _, _ := common.GetHeader(ctx) res := pb.BodyPartReply{} err := models.DB.Model(&models.BodyPart{}).Scopes( models.String("patient_type = ?", in.GetPatientType()), models.String("modality = ?", in.GetModality()), models.String("product = ?", product.ToString()), models.Bool("is_enabled = ?", in.IsEnabled), ).Order("sort").Find(&res.BodyPartList).Error if err != nil { return nil, status.Errorf(codes.Internal, "body_part find err %v", err) } for _, pt := range res.GetBodyPartList() { pt.BodyPartLocal = pt.BodyPartName } return &res, nil } func (s *ProtocolServer) GetProcedure(ctx context.Context, in *pb.ProcedureRequest) (*pb.ProcedureReply, error) { product, _, _ := common.GetHeader(ctx) res := pb.ProcedureReply{} err := models.DB.Model(&models.Procedure{}).Scopes( models.String("patient_type = ?", in.GetPatientType()), models.String("body_part_id = ?", in.GetBodyPartId()), models.String("product = ?", product.ToString()), models.Bool("is_enabled = ?", in.IsEnabled), models.Bool("is_pre_install = ?", in.IsPreInstall), ).Order("sort").Find(&res.ProcedureList).Error if err != nil { return nil, status.Errorf(codes.Internal, "procedure find err %v", err) } for _, pt := range res.GetProcedureList() { pt.ProcedureNameLocal = pt.ProcedureName pt.ProcedureDescriptionLocal = pt.ProcedureDescription } return &res, nil } func view2pb(view models.View) *pb.View { return &pb.View{ InternalId: view.InternalID, ViewId: view.ViewID, ViewName: view.ViewName, ViewNameLocal: view.ViewNameLocal, ViewOtherName: view.ViewOtherName, ViewDescription: view.ViewDescription, ViewPosition: view.ViewPosition, Application: view.Application, AnatomicRegion: view.AnatomicRegion, PatientType: view.PatientType, BodyPartId: view.BodyPartID, ViewIconName: view.ViewIconName, ViewBigIconName: view.ViewBigIconName, ViewCoachName: view.ViewCoachName, Modality: view.Modality, ConfigObject: Json2Struct(&view.ConfigObject), TechTemplate: view.TechTemplate, ImgProcTemplate: view.ImgProcTemplate, Sort: view.Sort, IsEnabled: view.IsEnabled, Product: view.Product, IsPreInstall: view.IsPreInstall, } } func (s *ProtocolServer) GetView(ctx context.Context, in *pb.ViewRequest) (*pb.ViewReply, error) { product, _, _ := common.GetHeader(ctx) procedure := models.Procedure{} res := pb.ViewReply{} if in.GetProcedureId() == "" { err := models.DB.Model(&models.View{}).Scopes( models.String("patient_type = ?", in.GetPatientType()), models.String("body_part_id = ?", in.GetBodyPartId()), models.String("product = ?", product.ToString()), models.Bool("is_enabled = ?", in.IsEnabled), models.Bool("is_pre_install = ?", in.IsPreInstall), ).Order("sort").Find(&procedure.Views).Error if err != nil { return nil, status.Errorf(codes.Internal, "procedure find err %v", err) } } else { err := models.DB.Model(&models.Procedure{}).Preload("Views").Scopes( models.String("procedure_id = ?", in.GetProcedureId()), models.String("product = ?", product.ToString()), models.Bool("is_enabled = ?", in.IsEnabled), models.Bool("is_pre_install = ?", in.IsPreInstall), ).Order("sort").First(&procedure).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, status.Errorf(codes.NotFound, "procedure %s not found", in.GetProcedureId()) } return nil, status.Errorf(codes.Internal, "procedure find err %v", err) } } for _, view := range procedure.Views { res.ViewList = append(res.ViewList, view2pb(view)) } return &res, nil }