From be400155269beb4de79de4d32e82042ffa558677 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Wed, 25 Sep 2024 09:35:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EAI=E6=9C=8D=E5=8A=A1=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/service/iml.go | 48 ++++-- controller/service/service.go | 22 ++- controller/system/import.go | 8 +- module/ai/dto/output.go | 1 + module/ai/iml.go | 1 + module/service/dto/input.go | 3 + module/service/dto/output.go | 11 +- module/service/iml.go | 275 ++++++++++++++++++++-------------- module/service/module.go | 19 ++- plugins/core/ai.go | 2 +- plugins/core/service.go | 12 +- service/service/iml.go | 24 ++- service/service/model.go | 128 +++++++++++----- service/service/service.go | 1 + stores/service/model.go | 24 +-- 15 files changed, 375 insertions(+), 204 deletions(-) diff --git a/controller/service/iml.go b/controller/service/iml.go index f4b31e47..952f3235 100644 --- a/controller/service/iml.go +++ b/controller/service/iml.go @@ -8,31 +8,51 @@ import ( var ( _ IServiceController = (*imlServiceController)(nil) - _ IAppController = (*imlAppController)(nil) + + _ IAppController = (*imlAppController)(nil) ) type imlServiceController struct { - module service.IServiceModule `autowired:""` + module service.IServiceModule `autowired:""` + docModule service.IServiceDocModule `autowired:""` +} + +func (i *imlServiceController) CreateAIService(ctx *gin.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) { + kind := "ai" + input.Kind = &kind + return i.module.Create(ctx, teamID, input) +} + +func (i *imlServiceController) DeleteAIService(ctx *gin.Context, id string) error { + return i.module.Delete(ctx, id, "ai") +} + +func (i *imlServiceController) SearchMyAIServices(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) { + return i.module.SearchMyServicesByKind(ctx, teamID, keyword, "ai") +} + +func (i *imlServiceController) SearchAIServices(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) { + return i.module.Search(ctx, teamID, keyword, "ai") } func (i *imlServiceController) SearchMyServices(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.ServiceItem, error) { - return i.module.SearchMyServices(ctx, teamId, keyword) + return i.module.SearchMyServicesByKind(ctx, teamId, keyword, "") } -func (i *imlServiceController) Simple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { - return i.module.Simple(ctx, keyword) -} - -func (i *imlServiceController) MySimple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { - return i.module.MySimple(ctx, keyword) -} +//func (i *imlServiceController) Simple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { +// return i.module.Simple(ctx, keyword) +//} +// +//func (i *imlServiceController) MySimple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { +// return i.module.MySimple(ctx, keyword) +//} func (i *imlServiceController) Get(ctx *gin.Context, id string) (*service_dto.Service, error) { return i.module.Get(ctx, id) } func (i *imlServiceController) Search(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) { - return i.module.Search(ctx, teamID, keyword) + return i.module.Search(ctx, teamID, keyword, "") } func (i *imlServiceController) Create(ctx *gin.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) { @@ -44,15 +64,15 @@ func (i *imlServiceController) Edit(ctx *gin.Context, id string, input *service_ } func (i *imlServiceController) Delete(ctx *gin.Context, id string) error { - return i.module.Delete(ctx, id) + return i.module.Delete(ctx, id, "") } func (i *imlServiceController) ServiceDoc(ctx *gin.Context, id string) (*service_dto.ServiceDoc, error) { - return i.module.ServiceDoc(ctx, id) + return i.docModule.ServiceDoc(ctx, id) } func (i *imlServiceController) SaveServiceDoc(ctx *gin.Context, id string, input *service_dto.SaveServiceDoc) error { - return i.module.SaveServiceDoc(ctx, id, input) + return i.docModule.SaveServiceDoc(ctx, id, input) } type imlAppController struct { diff --git a/controller/service/service.go b/controller/service/service.go index 2f17144b..13bbee95 100644 --- a/controller/service/service.go +++ b/controller/service/service.go @@ -2,11 +2,11 @@ package service import ( "reflect" - + service_dto "github.com/APIParkLab/APIPark/module/service/dto" - + "github.com/gin-gonic/gin" - + "github.com/eolinker/go-common/autowire" ) @@ -23,17 +23,23 @@ type IServiceController interface { // Delete 删除 Delete(ctx *gin.Context, id string) error // Simple 获取简易列表 - Simple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) - // MySimple 获取我的简易列表 - MySimple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) + //Simple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) + //// MySimple 获取我的简易列表 + //MySimple(ctx *gin.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) ServiceDoc(ctx *gin.Context, id string) (*service_dto.ServiceDoc, error) SaveServiceDoc(ctx *gin.Context, id string, input *service_dto.SaveServiceDoc) error + + CreateAIService(ctx *gin.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) + //EditAIService(ctx *gin.Context, id string, input *service_dto.EditService) (*service_dto.Service, error) + DeleteAIService(ctx *gin.Context, id string) error + SearchMyAIServices(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) + SearchAIServices(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) } type IAppController interface { // CreateApp 创建应用 CreateApp(ctx *gin.Context, teamID string, project *service_dto.CreateApp) (*service_dto.App, error) - + UpdateApp(ctx *gin.Context, appId string, project *service_dto.UpdateApp) (*service_dto.App, error) Search(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.AppItem, error) SearchMyApps(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.AppItem, error) @@ -48,7 +54,7 @@ func init() { autowire.Auto[IServiceController](func() reflect.Value { return reflect.ValueOf(new(imlServiceController)) }) - + autowire.Auto[IAppController](func() reflect.Value { return reflect.ValueOf(new(imlAppController)) }) diff --git a/controller/system/import.go b/controller/system/import.go index cfcc23a6..fe480bc2 100644 --- a/controller/system/import.go +++ b/controller/system/import.go @@ -187,10 +187,10 @@ func (i *imlImportConfigController) importServices(ctx context.Context) error { } } - err = i.serviceModule.SaveServiceDoc(ctx, d.Id, &service_dto.SaveServiceDoc{Doc: d.Doc}) - if err != nil { - return fmt.Errorf("save service(%s) doc error: %v", d.Id, err) - } + //err = i.serviceModule.SaveServiceDoc(ctx, d.Id, &service_dto.SaveServiceDoc{Doc: d.Doc}) + //if err != nil { + // return fmt.Errorf("save service(%s) doc error: %v", d.Id, err) + //} } return nil } diff --git a/module/ai/dto/output.go b/module/ai/dto/output.go index 752f4252..b4930bb5 100644 --- a/module/ai/dto/output.go +++ b/module/ai/dto/output.go @@ -25,5 +25,6 @@ type SimpleProviderItem struct { type LLMItem struct { Id string `json:"id"` Logo string `json:"logo"` + Config string `json:"config"` Scopes []string `json:"scopes"` } diff --git a/module/ai/iml.go b/module/ai/iml.go index 4c52f80b..85074453 100644 --- a/module/ai/iml.go +++ b/module/ai/iml.go @@ -120,6 +120,7 @@ func (i *imlProviderModule) LLMs(ctx context.Context, driver string) ([]*ai_dto. items = append(items, &ai_dto.LLMItem{ Id: v.Id, Logo: v.Logo, + Config: p.InvokeConfig().DefaultConfig(), Scopes: v.Scopes, }) } diff --git a/module/service/dto/input.go b/module/service/dto/input.go index c75704ac..7962e67d 100644 --- a/module/service/dto/input.go +++ b/module/service/dto/input.go @@ -9,6 +9,8 @@ type CreateService struct { Logo string `json:"logo"` Tags []string `json:"tags"` Catalogue string `json:"catalogue"` + Kind *string `json:"kind,omitempty"` + Provider *string `json:"provider" aocheck:"ai_provider"` AsApp *bool `json:"as_app"` AsServer *bool `json:"as_server"` } @@ -20,6 +22,7 @@ type EditService struct { Catalogue *string `json:"catalogue"` Logo *string `json:"logo"` Tags *[]string `json:"tags"` + Provider *string `json:"provider" aocheck:"ai_provider"` } type CreateApp struct { diff --git a/module/service/dto/output.go b/module/service/dto/output.go index 4e34e420..649ea875 100644 --- a/module/service/dto/output.go +++ b/module/service/dto/output.go @@ -13,6 +13,7 @@ type ServiceItem struct { Description string `json:"description"` CreateTime auto.TimeLabel `json:"create_time"` UpdateTime auto.TimeLabel `json:"update_time"` + Provider *auto.Label `json:"provider,omitempty" aolabel:"ai_provider"` CanDelete bool `json:"can_delete"` } @@ -54,6 +55,7 @@ type Service struct { Catalogue auto.Label `json:"catalogue" aolabel:"catalogue"` Tags []auto.Label `json:"tags" aolabel:"tag"` Logo string `json:"logo"` + Provider *auto.Label `json:"provider,omitempty" aolabel:"ai_provider"` AsServer bool `json:"as_server"` AsApp bool `json:"as_app"` } @@ -69,7 +71,8 @@ type App struct { } func ToService(model *service.Service) *Service { - return &Service{ + + s := &Service{ Id: model.Id, Name: model.Name, Prefix: model.Prefix, @@ -83,6 +86,12 @@ func ToService(model *service.Service) *Service { AsServer: model.AsServer, AsApp: model.AsApp, } + switch model.Kind { + case service.AIService: + provider := auto.UUID(model.AdditionalConfig["provider"]) + s.Provider = &provider + } + return s } type MemberItem struct { diff --git a/module/service/iml.go b/module/service/iml.go index 684a610a..39683c89 100644 --- a/module/service/iml.go +++ b/module/service/iml.go @@ -48,11 +48,11 @@ type imlServiceModule struct { teamService team.ITeamService `autowired:""` teamMemberService team_member.ITeamMemberService `autowired:""` tagService tag.ITagService `autowired:""` - serviceDocService service_doc.IDocService `autowired:""` - serviceTagService service_tag.ITagService `autowired:""` - apiService api.IAPIService `autowired:""` - apiDocService api_doc.IAPIDocService `autowired:""` - transaction store.ITransaction `autowired:""` + + serviceTagService service_tag.ITagService `autowired:""` + apiService api.IAPIService `autowired:""` + apiDocService api_doc.IAPIDocService `autowired:""` + transaction store.ITransaction `autowired:""` } func (i *imlServiceModule) ExportAll(ctx context.Context) ([]*service_dto.ExportService, error) { @@ -82,10 +82,10 @@ func (i *imlServiceModule) ExportAll(ctx context.Context) ([]*service_dto.Export serviceTagMap[st.Sid] = append(serviceTagMap[st.Sid], tagMap[st.Tid].Name) } - docMap, err := i.serviceDocService.Map(ctx, serviceIds...) - if err != nil { - return nil, err - } + //docMap, err := i.serviceDocService.Map(ctx, serviceIds...) + //if err != nil { + // return nil, err + //} items := make([]*service_dto.ExportService, 0, len(services)) for _, s := range services { @@ -99,9 +99,9 @@ func (i *imlServiceModule) ExportAll(ctx context.Context) ([]*service_dto.Export Catalogue: s.Catalogue, Logo: s.Logo, } - if v, ok := docMap[s.Id]; ok { - info.Doc = v.Doc - } + //if v, ok := docMap[s.Id]; ok { + // info.Doc = v.Doc + //} if tags, ok := serviceTagMap[s.Id]; ok { info.Tags = tags } @@ -111,11 +111,12 @@ func (i *imlServiceModule) ExportAll(ctx context.Context) ([]*service_dto.Export } -func (i *imlServiceModule) searchMyServices(ctx context.Context, teamId string, keyword string) ([]*service.Service, error) { +func (i *imlServiceModule) searchMyServices(ctx context.Context, teamId string, keyword string, kind service.Kind) ([]*service.Service, error) { userID := utils.UserId(ctx) condition := make(map[string]interface{}) condition["as_server"] = true + condition["kind"] = kind.Int() if teamId != "" { _, err := i.teamService.Get(ctx, teamId) if err != nil { @@ -135,8 +136,8 @@ func (i *imlServiceModule) searchMyServices(ctx context.Context, teamId string, } -func (i *imlServiceModule) SearchMyServices(ctx context.Context, teamId string, keyword string) ([]*service_dto.ServiceItem, error) { - services, err := i.searchMyServices(ctx, teamId, keyword) +func (i *imlServiceModule) SearchMyServicesByKind(ctx context.Context, teamId string, keyword string, kind string) ([]*service_dto.ServiceItem, error) { + services, err := i.searchMyServices(ctx, teamId, keyword, service.Kind(kind)) if err != nil { return nil, err } @@ -154,79 +155,74 @@ func (i *imlServiceModule) SearchMyServices(ctx context.Context, teamId string, continue } apiCount := apiCountMap[model.Id] - items = append(items, &service_dto.ServiceItem{ - Id: model.Id, - Name: model.Name, - Description: model.Description, - CreateTime: auto.TimeLabel(model.CreateTime), - UpdateTime: auto.TimeLabel(model.UpdateTime), - Team: auto.UUID(model.Team), - ApiNum: apiCount, - CanDelete: apiCount == 0, - }) + item := toServiceItem(service.Kind(kind), model) + item.ApiNum = apiCount + item.CanDelete = apiCount == 0 + items = append(items, item) + } return items, nil } -func (i *imlServiceModule) SimpleAPPS(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { - w := make(map[string]interface{}) - w["as_app"] = true - services, err := i.serviceService.Search(ctx, keyword, w) - if err != nil { - return nil, err - } - return utils.SliceToSlice(services, func(p *service.Service) *service_dto.SimpleServiceItem { - return &service_dto.SimpleServiceItem{ - Id: p.Id, - Name: p.Name, - Description: p.Description, +//func (i *imlServiceModule) SimpleAPPS(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { +// w := make(map[string]interface{}) +// w["as_app"] = true +// services, err := i.serviceService.Search(ctx, keyword, w) +// if err != nil { +// return nil, err +// } +// return utils.SliceToSlice(services, func(p *service.Service) *service_dto.SimpleServiceItem { +// return &service_dto.SimpleServiceItem{ +// Id: p.Id, +// Name: p.Name, +// Description: p.Description, +// +// Team: auto.UUID(p.Team), +// } +// }), nil +//} - Team: auto.UUID(p.Team), - } - }), nil -} - -func (i *imlServiceModule) Simple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { - w := make(map[string]interface{}) - w["as_server"] = true - - services, err := i.serviceService.Search(ctx, keyword, w) - if err != nil { - return nil, err - } - - items := make([]*service_dto.SimpleServiceItem, 0, len(services)) - for _, p := range services { - - items = append(items, &service_dto.SimpleServiceItem{ - Id: p.Id, - Name: p.Name, - Description: p.Description, - Team: auto.UUID(p.Team), - }) - } - return items, nil -} - -func (i *imlServiceModule) MySimple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { - services, err := i.searchMyServices(ctx, "", keyword) - - if err != nil { - return nil, err - } - - items := make([]*service_dto.SimpleServiceItem, 0, len(services)) - for _, p := range services { - - items = append(items, &service_dto.SimpleServiceItem{ - Id: p.Id, - Name: p.Name, - Description: p.Description, - Team: auto.UUID(p.Team), - }) - } - return items, nil -} +//func (i *imlServiceModule) Simple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { +// w := make(map[string]interface{}) +// w["as_server"] = true +// +// services, err := i.serviceService.Search(ctx, keyword, w) +// if err != nil { +// return nil, err +// } +// +// items := make([]*service_dto.SimpleServiceItem, 0, len(services)) +// for _, p := range services { +// +// items = append(items, &service_dto.SimpleServiceItem{ +// Id: p.Id, +// Name: p.Name, +// Description: p.Description, +// Team: auto.UUID(p.Team), +// }) +// } +// return items, nil +//} +// +//func (i *imlServiceModule) MySimple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) { +// services, err := i.searchMyServices(ctx, "", keyword) +// +// if err != nil { +// return nil, err +// } +// +// items := make([]*service_dto.SimpleServiceItem, 0, len(services)) +// for _, p := range services { +// +// items = append(items, &service_dto.SimpleServiceItem{ +// Id: p.Id, +// Name: p.Name, +// Description: p.Description, +// Team: auto.UUID(p.Team), +// }) +// } +// return items, nil +//} func (i *imlServiceModule) Get(ctx context.Context, id string) (*service_dto.Service, error) { serviceInfo, err := i.serviceService.Get(ctx, id) @@ -245,7 +241,7 @@ func (i *imlServiceModule) Get(ctx context.Context, id string) (*service_dto.Ser return s, nil } -func (i *imlServiceModule) Search(ctx context.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) { +func (i *imlServiceModule) Search(ctx context.Context, teamID string, keyword string, kind string) ([]*service_dto.ServiceItem, error) { var list []*service.Service var err error if teamID != "" { @@ -253,9 +249,9 @@ func (i *imlServiceModule) Search(ctx context.Context, teamID string, keyword st if err != nil { return nil, err } - list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"team": teamID, "as_server": true}, "update_at desc") + list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"team": teamID, "as_server": true, "kind": service.Kind(kind).Int()}, "update_at desc") } else { - list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"as_server": true}, "update_at desc") + list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"as_server": true, "kind": service.Kind(kind).Int()}, "update_at desc") } if err != nil { return nil, err @@ -273,38 +269,64 @@ func (i *imlServiceModule) Search(ctx context.Context, teamID string, keyword st items := make([]*service_dto.ServiceItem, 0, len(list)) for _, model := range list { apiCount := apiCountMap[model.Id] - items = append(items, &service_dto.ServiceItem{ - Id: model.Id, - Name: model.Name, - Description: model.Description, - CreateTime: auto.TimeLabel(model.CreateTime), - UpdateTime: auto.TimeLabel(model.UpdateTime), - Team: auto.UUID(model.Team), - ApiNum: apiCount, - CanDelete: apiCount == 0, - }) + item := toServiceItem(service.Kind(kind), model) + item.ApiNum = apiCount + item.CanDelete = apiCount == 0 + items = append(items, item) } return items, nil } +func toServiceItem(kind service.Kind, model *service.Service) *service_dto.ServiceItem { + item := &service_dto.ServiceItem{ + Id: model.Id, + Name: model.Name, + Description: model.Description, + CreateTime: auto.TimeLabel(model.CreateTime), + UpdateTime: auto.TimeLabel(model.UpdateTime), + Team: auto.UUID(model.Team), + } + switch kind { + case service.RestService: + return item + case service.AIService: + provider := auto.UUID(model.AdditionalConfig["provider"]) + item.Provider = &provider + return item + default: + return item + } +} + func (i *imlServiceModule) Create(ctx context.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) { if input.Id == "" { input.Id = uuid.New().String() } mo := &service.Create{ - Id: input.Id, - Name: input.Name, - Description: input.Description, - Team: teamID, - ServiceType: service.ServiceType(input.ServiceType), - Catalogue: input.Catalogue, - Prefix: input.Prefix, - Logo: input.Logo, + Id: input.Id, + Name: input.Name, + Description: input.Description, + Team: teamID, + ServiceType: service.ServiceType(input.ServiceType), + Catalogue: input.Catalogue, + Prefix: input.Prefix, + Logo: input.Logo, + AdditionalConfig: make(map[string]string), } if mo.ServiceType == service.PublicService && mo.Catalogue == "" { return nil, fmt.Errorf("catalogue can not be empty") } + if input.Kind != nil { + mo.Kind = service.Kind(*input.Kind) + switch mo.Kind { + case service.AIService: + if input.Provider == nil { + return nil, fmt.Errorf("ai service: provider can not be empty") + } + mo.AdditionalConfig["provider"] = *input.Provider + } + } if input.AsApp == nil { // 默认值为false mo.AsApp = false @@ -343,10 +365,18 @@ func (i *imlServiceModule) Create(ctx context.Context, teamID string, input *ser } func (i *imlServiceModule) Edit(ctx context.Context, id string, input *service_dto.EditService) (*service_dto.Service, error) { - _, err := i.serviceService.Get(ctx, id) + info, err := i.serviceService.Get(ctx, id) if err != nil { return nil, err } + + switch info.Kind { + case service.AIService: + if input.Provider != nil { + info.AdditionalConfig["provider"] = *input.Provider + } + + } err = i.transaction.Transaction(ctx, func(ctx context.Context) error { serviceType := (*service.ServiceType)(input.ServiceType) if serviceType != nil && *serviceType == service.PublicService { @@ -356,11 +386,12 @@ func (i *imlServiceModule) Edit(ctx context.Context, id string, input *service_d } err = i.serviceService.Save(ctx, id, &service.Edit{ - Name: input.Name, - Description: input.Description, - Logo: input.Logo, - ServiceType: serviceType, - Catalogue: input.Catalogue, + Name: input.Name, + Description: input.Description, + Logo: input.Logo, + ServiceType: serviceType, + Catalogue: input.Catalogue, + AdditionalConfig: &info.AdditionalConfig, }) if err != nil { return err @@ -390,9 +421,18 @@ func (i *imlServiceModule) Edit(ctx context.Context, id string, input *service_d return i.Get(ctx, id) } -func (i *imlServiceModule) Delete(ctx context.Context, id string) error { - - err := i.transaction.Transaction(ctx, func(ctx context.Context) error { +func (i *imlServiceModule) Delete(ctx context.Context, id string, kind string) error { + info, err := i.serviceService.Get(ctx, id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil + } + return err + } + if info.Kind.Int() != service.Kind(kind).Int() { + return fmt.Errorf("kind is not match") + } + err = i.transaction.Transaction(ctx, func(ctx context.Context) error { count, err := i.apiService.CountByService(ctx, id) if err != nil { return err @@ -441,7 +481,12 @@ func (i *imlServiceModule) getTagUuids(ctx context.Context, tags []string) ([]st return tagList, nil } -func (i *imlServiceModule) ServiceDoc(ctx context.Context, pid string) (*serviceDto.ServiceDoc, error) { +type imlServiceDocModule struct { + serviceService service.IServiceService `autowired:""` + serviceDocService service_doc.IDocService `autowired:""` +} + +func (i *imlServiceDocModule) ServiceDoc(ctx context.Context, pid string) (*serviceDto.ServiceDoc, error) { _, err := i.serviceService.Check(ctx, pid, map[string]bool{"as_server": true}) if err != nil { @@ -473,7 +518,7 @@ func (i *imlServiceModule) ServiceDoc(ctx context.Context, pid string) (*service }, nil } -func (i *imlServiceModule) SaveServiceDoc(ctx context.Context, pid string, input *serviceDto.SaveServiceDoc) error { +func (i *imlServiceDocModule) SaveServiceDoc(ctx context.Context, pid string, input *serviceDto.SaveServiceDoc) error { _, err := i.serviceService.Check(ctx, pid, map[string]bool{"as_server": true}) if err != nil { diff --git a/module/service/module.go b/module/service/module.go index 0c69cf5a..dc2494f3 100644 --- a/module/service/module.go +++ b/module/service/module.go @@ -14,21 +14,23 @@ type IServiceModule interface { // Get 获取项目信息 Get(ctx context.Context, id string) (*service_dto.Service, error) // Search 搜索项目 - Search(ctx context.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) - // SearchMyServices 搜索 - SearchMyServices(ctx context.Context, teamId string, keyword string) ([]*service_dto.ServiceItem, error) + Search(ctx context.Context, teamID string, keyword string, kind string) ([]*service_dto.ServiceItem, error) + // SearchMyServicesByKind 搜索 + SearchMyServicesByKind(ctx context.Context, teamId string, keyword string, kind string) ([]*service_dto.ServiceItem, error) // Create 创建 Create(ctx context.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) // Edit 编辑 Edit(ctx context.Context, id string, input *service_dto.EditService) (*service_dto.Service, error) // Delete 删除项目 - Delete(ctx context.Context, id string) error + Delete(ctx context.Context, id string, kind string) error // Simple 获取简易项目列表 - Simple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) + //Simple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) // MySimple 获取我的简易项目列表 - MySimple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) + //MySimple(ctx context.Context, keyword string) ([]*service_dto.SimpleServiceItem, error) +} +type IServiceDocModule interface { ServiceDoc(ctx context.Context, pid string) (*service_dto.ServiceDoc, error) // SaveServiceDoc 保存服务文档 SaveServiceDoc(ctx context.Context, pid string, input *service_dto.SaveServiceDoc) error @@ -73,4 +75,9 @@ func init() { return reflect.ValueOf(appModule) }) + serviceDocModule := new(imlServiceDocModule) + autowire.Auto[IServiceDocModule](func() reflect.Value { + return reflect.ValueOf(serviceDocModule) + }) + } diff --git a/plugins/core/ai.go b/plugins/core/ai.go index 8a8c1f15..d1d9e602 100644 --- a/plugins/core/ai.go +++ b/plugins/core/ai.go @@ -10,7 +10,7 @@ func (p *plugin) aiAPIs() []pm3.Api { pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.Providers), pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.SimpleProviders), pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/config", []string{"context", "query:provider"}, []string{"provider"}, p.aiProviderController.Provider), - pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms"}, p.aiProviderController.LLMs), + pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms", "provider"}, p.aiProviderController.LLMs), //pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/enable", []string{"context", "query:provider"}, nil, p.aiProviderController.Enable), //pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/disable", []string{"context", "query:provider"}, nil, p.aiProviderController.Disable), pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/config", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderConfig), diff --git a/plugins/core/service.go b/plugins/core/service.go index 4d3f8c8a..85541d42 100644 --- a/plugins/core/service.go +++ b/plugins/core/service.go @@ -15,9 +15,17 @@ func (p *plugin) ServiceApis() []pm3.Api { pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.SearchMyServices), pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.Search), - pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services/mine", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.MySimple), + //pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services/mine", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.MySimple), + // + //pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.Simple), - pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.Simple), + // AI服务 + pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai-services", []string{"context", "query:service", "query:keyword"}, []string{"service"}, p.serviceController.SearchAIServices), + pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/ai-service", []string{"context", "query:service", "body"}, []string{"service"}, p.serviceController.Create), + pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai-service/info", []string{"context", "query:service", "body"}, []string{"service"}, p.serviceController.Edit), + pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/ai-service", []string{"context", "query:service"}, nil, p.serviceController.Delete), + pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_ai_services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.SearchMyAIServices), + pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai-service/info", []string{"context", "query:service"}, []string{"services"}, p.serviceController.Get), // 应用相关 pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/info", []string{"context", "query:app"}, []string{"app"}, p.appController.GetApp), diff --git a/service/service/iml.go b/service/service/iml.go index cbaf1acc..70e8eaf7 100644 --- a/service/service/iml.go +++ b/service/service/iml.go @@ -2,6 +2,7 @@ package service import ( "context" + "encoding/json" "fmt" "time" @@ -38,6 +39,20 @@ func (i *imlServiceService) ServiceList(ctx context.Context, serviceIds ...strin return utils.SliceToSlice(list, FromEntity), nil } +func (i *imlServiceService) ServiceListByKind(ctx context.Context, kind Kind, serviceIds ...string) ([]*Service, error) { + w := make(map[string]interface{}) + if len(serviceIds) > 0 { + w["uuid"] = serviceIds + } + w["as_server"] = true + w["kind"] = kind + list, err := i.store.List(ctx, w) + if err != nil { + return nil, err + } + return utils.SliceToSlice(list, FromEntity), nil +} + func (i *imlServiceService) SearchPublicServices(ctx context.Context, keyword string) ([]*Service, error) { w := map[string]interface{}{ "as_server": true, @@ -143,6 +158,7 @@ func createEntityHandler(i *Create) *service.Service { Prefix: i.Prefix, Team: i.Team, ServiceType: i.ServiceType.Int(), + Kind: i.Kind.Int(), Catalogue: i.Catalogue, AsServer: i.AsServer, AsApp: i.AsApp, @@ -158,11 +174,17 @@ func updateHandler(e *service.Service, i *Edit) { if i.ServiceType != nil { e.ServiceType = (*i.ServiceType).Int() } + if i.Kind != nil { + e.Kind = (*i.Kind).Int() + } if i.Catalogue != nil { e.Catalogue = *i.Catalogue } if i.Logo != nil { e.Logo = *i.Logo } - + if i.AdditionalConfig != nil { + cfg, _ := json.Marshal(*i.AdditionalConfig) + e.AdditionalConfig = string(cfg) + } } diff --git a/service/service/model.go b/service/service/model.go index 988b54ed..5309c0c6 100644 --- a/service/service/model.go +++ b/service/service/model.go @@ -1,8 +1,9 @@ package service import ( + "encoding/json" "time" - + "github.com/APIParkLab/APIPark/stores/service" ) @@ -30,7 +31,7 @@ func (s ServiceType) Int() int { } func ToServiceType(s int) ServiceType { - + switch s { case 1: return InnerService @@ -41,57 +42,102 @@ func ToServiceType(s int) ServiceType { } } +type Kind string + +const ( + RestService Kind = "rest" + AIService Kind = "ai" +) + +func (s Kind) String() string { + return string(s) +} + +func (s Kind) Int() int { + switch s { + case RestService: + return 0 + case AIService: + return 1 + default: + return 0 + } +} + +func ToServiceKind(s int) Kind { + switch s { + case 0: + return RestService + case 1: + return AIService + default: + return RestService + } +} + type Service struct { - Id string - Name string - Description string - Team string - Prefix string - Logo string - ServiceType ServiceType - Catalogue string - AsServer bool - AsApp bool - CreateTime time.Time - UpdateTime time.Time + Id string + Name string + Description string + Team string + Prefix string + Logo string + ServiceType ServiceType + Kind Kind + Catalogue string + AdditionalConfig map[string]string + AsServer bool + AsApp bool + CreateTime time.Time + UpdateTime time.Time } func FromEntity(e *service.Service) *Service { + additionalConfig := make(map[string]string) + if e.AdditionalConfig != "" { + _ = json.Unmarshal([]byte(e.AdditionalConfig), &additionalConfig) + } return &Service{ - Id: e.UUID, - Name: e.Name, - Description: e.Description, - Team: e.Team, - Prefix: e.Prefix, - Logo: e.Logo, - ServiceType: ToServiceType(e.ServiceType), - Catalogue: e.Catalogue, - AsServer: e.AsServer, - AsApp: e.AsApp, - CreateTime: e.CreateAt, - UpdateTime: e.UpdateAt, + Id: e.UUID, + Name: e.Name, + Description: e.Description, + Team: e.Team, + Prefix: e.Prefix, + Logo: e.Logo, + ServiceType: ToServiceType(e.ServiceType), + Kind: ToServiceKind(e.Kind), + Catalogue: e.Catalogue, + AsServer: e.AsServer, + AsApp: e.AsApp, + CreateTime: e.CreateAt, + UpdateTime: e.UpdateAt, + AdditionalConfig: additionalConfig, } } type Create struct { - Id string - Name string - Description string - Team string - Prefix string - Logo string - ServiceType ServiceType - Catalogue string - AsServer bool - AsApp bool + Id string + Name string + Description string + Team string + Prefix string + Logo string + ServiceType ServiceType + Kind Kind + Catalogue string + AdditionalConfig map[string]string + AsServer bool + AsApp bool } type Edit struct { - Name *string - Description *string - ServiceType *ServiceType - Catalogue *string - Logo *string + Name *string + Description *string + ServiceType *ServiceType + Kind *Kind + Catalogue *string + Logo *string + AdditionalConfig *map[string]string } type CreateTag struct { diff --git a/service/service/service.go b/service/service/service.go index 1f7dae45..d91e2d89 100644 --- a/service/service/service.go +++ b/service/service/service.go @@ -18,6 +18,7 @@ type IServiceService interface { SearchPublicServices(ctx context.Context, keyword string) ([]*Service, error) Check(ctx context.Context, id string, rule map[string]bool) (*Service, error) ServiceList(ctx context.Context, serviceIds ...string) ([]*Service, error) + ServiceListByKind(ctx context.Context, kind Kind, serviceIds ...string) ([]*Service, error) AppList(ctx context.Context, appIds ...string) ([]*Service, error) } diff --git a/stores/service/model.go b/stores/service/model.go index 49ddd4bc..b68d3409 100644 --- a/stores/service/model.go +++ b/stores/service/model.go @@ -7,17 +7,19 @@ type Service struct { UUID string `gorm:"type:varchar(36);not null;column:uuid;uniqueIndex:uuid;comment:UUID;"` Name string `gorm:"type:varchar(100);not null;column:name;comment:name"` - Description string `gorm:"size:255;not null;column:description;comment:description"` - Prefix string `gorm:"size:255;not null;column:prefix;comment:前缀"` - Team string `gorm:"size:36;not null;column:team;comment:团队id;index:team"` // 团队id - Logo string `gorm:"type:text;not null;column:logo;comment:logo"` - ServiceType int `gorm:"type:int(11);not null;column:service_type;comment:服务类型"` - Catalogue string `gorm:"type:text;not null;column:catalogue;comment:目录"` - CreateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_at;comment:创建时间"` - UpdateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;column:update_at;comment:修改时间"` - IsDelete int `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除"` - AsServer bool `gorm:"type:tinyint(1);not null;column:as_server;comment:是否为服务端项目"` - AsApp bool `gorm:"type:tinyint(1);not null;column:as_app;comment:是否为应用项目"` + Description string `gorm:"size:255;not null;column:description;comment:description"` + Prefix string `gorm:"size:255;not null;column:prefix;comment:前缀"` + Team string `gorm:"size:36;not null;column:team;comment:团队id;index:team"` // 团队id + Logo string `gorm:"type:text;not null;column:logo;comment:logo"` + ServiceType int `gorm:"type:int(11);not null;column:service_type;comment:服务类型"` + Catalogue string `gorm:"type:text;not null;column:catalogue;comment:目录"` + CreateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_at;comment:创建时间"` + UpdateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;column:update_at;comment:修改时间"` + IsDelete int `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除"` + Kind int `gorm:"type:tinyint(4);not null;column:kind;comment:服务种类,0:Rest服务,1:AI服务"` + AdditionalConfig string `gorm:"type:text;not null;column:additional_config;comment:额外配置"` + AsServer bool `gorm:"type:tinyint(1);not null;column:as_server;comment:是否为服务端项目"` + AsApp bool `gorm:"type:tinyint(1);not null;column:as_app;comment:是否为应用项目"` } func (p *Service) IdValue() int64 {