feat(kol): expose PUT /kol/manage/profile and POST /kol/manage/profile/avatar

This commit is contained in:
2026-04-18 14:06:20 +08:00
parent 1393b25419
commit d2922478ed
2 changed files with 75 additions and 3 deletions
@@ -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 {
+3 -1
View File
@@ -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)