feat(kol): expose PUT /kol/manage/profile and POST /kol/manage/profile/avatar
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package transport
|
package transport
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -16,16 +18,18 @@ type KolManageHandler struct {
|
|||||||
pkgSvc *app.KolPackageService
|
pkgSvc *app.KolPackageService
|
||||||
promptSvc *app.KolPromptService
|
promptSvc *app.KolPromptService
|
||||||
assistSvc *app.KolAssistService
|
assistSvc *app.KolAssistService
|
||||||
|
assets *AssetHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKolManageHandler(a *bootstrap.App) *KolManageHandler {
|
func NewKolManageHandler(a *bootstrap.App, assets *AssetHandler) *KolManageHandler {
|
||||||
profileSvc := app.NewKolProfileService(a.KolProfiles)
|
profileSvc := app.NewKolProfileService(a.KolProfiles).WithObjectStorage(a.ObjectStorage)
|
||||||
|
|
||||||
return &KolManageHandler{
|
return &KolManageHandler{
|
||||||
profileSvc: profileSvc,
|
profileSvc: profileSvc,
|
||||||
pkgSvc: app.NewKolPackageService(profileSvc, a.KolPackages, a.KolPrompts).WithCache(a.Cache),
|
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),
|
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),
|
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))
|
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) {
|
func (h *KolManageHandler) ListPackages(c *gin.Context) {
|
||||||
actor, ok := actorFromRequest(c)
|
actor, ok := actorFromRequest(c)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ func RegisterRoutes(app *bootstrap.App) {
|
|||||||
templates.POST("/:id/generate", tplHandler.Generate)
|
templates.POST("/:id/generate", tplHandler.Generate)
|
||||||
|
|
||||||
kolManage := protected.Group("/tenant/kol/manage")
|
kolManage := protected.Group("/tenant/kol/manage")
|
||||||
kolManageHandler := NewKolManageHandler(app)
|
kolManageHandler := NewKolManageHandler(app, publicAssets)
|
||||||
kolManage.GET("/profile", kolManageHandler.GetProfile)
|
kolManage.GET("/profile", kolManageHandler.GetProfile)
|
||||||
|
kolManage.PUT("/profile", kolManageHandler.UpdateProfile)
|
||||||
|
kolManage.POST("/profile/avatar", kolManageHandler.UploadAvatar)
|
||||||
kolManage.GET("/packages", kolManageHandler.ListPackages)
|
kolManage.GET("/packages", kolManageHandler.ListPackages)
|
||||||
kolManage.POST("/packages", kolManageHandler.CreatePackage)
|
kolManage.POST("/packages", kolManageHandler.CreatePackage)
|
||||||
kolManage.PUT("/packages/:id", kolManageHandler.UpdatePackage)
|
kolManage.PUT("/packages/:id", kolManageHandler.UpdatePackage)
|
||||||
|
|||||||
Reference in New Issue
Block a user