From d2922478edb4c42ceecd731a97631fa0025fc1c1 Mon Sep 17 00:00:00 2001 From: liangxu Date: Sat, 18 Apr 2026 14:06:20 +0800 Subject: [PATCH] feat(kol): expose PUT /kol/manage/profile and POST /kol/manage/profile/avatar --- .../tenant/transport/kol_manage_handler.go | 74 ++++++++++++++++++- server/internal/tenant/transport/router.go | 4 +- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/server/internal/tenant/transport/kol_manage_handler.go b/server/internal/tenant/transport/kol_manage_handler.go index 68593f3..fc4c145 100644 --- a/server/internal/tenant/transport/kol_manage_handler.go +++ b/server/internal/tenant/transport/kol_manage_handler.go @@ -1,6 +1,8 @@ package transport import ( + "io" + "net/http" "strconv" "github.com/gin-gonic/gin" @@ -16,16 +18,18 @@ type KolManageHandler struct { pkgSvc *app.KolPackageService promptSvc *app.KolPromptService assistSvc *app.KolAssistService + assets *AssetHandler } -func NewKolManageHandler(a *bootstrap.App) *KolManageHandler { - profileSvc := app.NewKolProfileService(a.KolProfiles) +func NewKolManageHandler(a *bootstrap.App, assets *AssetHandler) *KolManageHandler { + profileSvc := app.NewKolProfileService(a.KolProfiles).WithObjectStorage(a.ObjectStorage) return &KolManageHandler{ profileSvc: profileSvc, pkgSvc: app.NewKolPackageService(profileSvc, a.KolPackages, a.KolPrompts).WithCache(a.Cache), promptSvc: app.NewKolPromptService(a.DB, profileSvc, a.KolPackages, a.KolPrompts, a.KolSubscriptions, a.KolPromptAsset).WithCache(a.Cache), assistSvc: app.NewKolAssistService(profileSvc, a.KolAssists, a.LLM, a.RabbitMQ), + assets: assets, } } @@ -44,6 +48,72 @@ func (h *KolManageHandler) GetProfile(c *gin.Context) { response.Success(c, app.NewKolProfileResponse(profile)) } +type updateKolProfileRequest struct { + DisplayName string `json:"display_name"` + Bio *string `json:"bio"` + AvatarURL *string `json:"avatar_url"` +} + +func (h *KolManageHandler) UpdateProfile(c *gin.Context) { + actor, ok := actorFromRequest(c) + if !ok { + return + } + + var req updateKolProfileRequest + if err := c.ShouldBindJSON(&req); err != nil { + response.Error(c, response.ErrBadRequest(40001, "invalid_params", err.Error())) + return + } + + profile, err := h.profileSvc.UpdateProfile(c.Request.Context(), actor, app.UpdateKolProfileServiceInput{ + DisplayName: req.DisplayName, + Bio: req.Bio, + AvatarURL: req.AvatarURL, + }) + if err != nil { + response.Error(c, err) + return + } + + response.Success(c, app.NewKolProfileResponse(profile)) +} + +func (h *KolManageHandler) UploadAvatar(c *gin.Context) { + actor, ok := actorFromRequest(c) + if !ok { + return + } + + fileHeader, err := c.FormFile("file") + if err != nil { + response.Error(c, response.ErrBadRequest(40004, "kol_avatar_invalid", "avatar file is required")) + return + } + + f, err := fileHeader.Open() + if err != nil { + response.Error(c, response.ErrBadRequest(40004, "kol_avatar_invalid", "avatar file cannot be opened")) + return + } + defer f.Close() + + content, err := io.ReadAll(f) + if err != nil { + response.Error(c, response.ErrBadRequest(40004, "kol_avatar_invalid", "avatar file cannot be read")) + return + } + + result, err := h.profileSvc.UploadAvatar(c.Request.Context(), actor, fileHeader.Filename, content) + if err != nil { + response.Error(c, err) + return + } + result.URL = h.assets.BuildArticleImageURL(result.ObjectKey) + + response.SuccessWithStatus(c, http.StatusCreated, result) +} + func (h *KolManageHandler) ListPackages(c *gin.Context) { actor, ok := actorFromRequest(c) if !ok { diff --git a/server/internal/tenant/transport/router.go b/server/internal/tenant/transport/router.go index f81ff3a..55a8fff 100644 --- a/server/internal/tenant/transport/router.go +++ b/server/internal/tenant/transport/router.go @@ -57,8 +57,10 @@ func RegisterRoutes(app *bootstrap.App) { templates.POST("/:id/generate", tplHandler.Generate) kolManage := protected.Group("/tenant/kol/manage") - kolManageHandler := NewKolManageHandler(app) + kolManageHandler := NewKolManageHandler(app, publicAssets) kolManage.GET("/profile", kolManageHandler.GetProfile) + kolManage.PUT("/profile", kolManageHandler.UpdateProfile) + kolManage.POST("/profile/avatar", kolManageHandler.UploadAvatar) kolManage.GET("/packages", kolManageHandler.ListPackages) kolManage.POST("/packages", kolManageHandler.CreatePackage) kolManage.PUT("/packages/:id", kolManageHandler.UpdatePackage)