9bb7144593
Approving / manually binding / revoking KOL subscriptions belonged to the operations console, not the tenant-admin role on tenant-api. Add a fresh KolSubscriptionService + repository + handlers under the ops module with its own list/manual-bind/approve/revoke routes, wire a Redis-backed cache into ops-api so admin actions can invalidate tenant prompt caches, and delete the tenant-side admin service/handler now that ops-web owns the UI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
package transport
|
|
|
|
import (
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/geo-platform/tenant-api/internal/ops/app"
|
|
"github.com/geo-platform/tenant-api/internal/shared/response"
|
|
)
|
|
|
|
type approveKolSubscriptionRequest struct {
|
|
EndAt *time.Time `json:"end_at"`
|
|
}
|
|
|
|
type manualBindKolSubscriptionRequest struct {
|
|
Phone string `json:"phone" binding:"required"`
|
|
PackageID int64 `json:"package_id" binding:"required"`
|
|
EndAt *time.Time `json:"end_at"`
|
|
}
|
|
|
|
func listKolSubscriptionsHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
|
|
result, err := svc.List(c.Request.Context(), app.KolSubscriptionListInput{
|
|
Keyword: c.Query("keyword"),
|
|
Status: c.Query("status"),
|
|
Page: page,
|
|
Size: size,
|
|
})
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
response.Success(c, result)
|
|
}
|
|
}
|
|
|
|
func listKolSubscriptionPackagesHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
size, _ := strconv.Atoi(c.DefaultQuery("size", "50"))
|
|
result, err := svc.ListPackages(c.Request.Context(), app.KolPackageListInput{
|
|
Keyword: c.Query("keyword"),
|
|
Size: size,
|
|
})
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
response.Success(c, result)
|
|
}
|
|
}
|
|
|
|
func manualBindKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var body manualBindKolSubscriptionRequest
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
response.Error(c, response.ErrBadRequest(40000, "invalid_payload", err.Error()))
|
|
return
|
|
}
|
|
|
|
detail, err := svc.ManualBind(c.Request.Context(), actorFromGin(c), app.KolSubscriptionManualBindInput{
|
|
Phone: body.Phone,
|
|
PackageID: body.PackageID,
|
|
EndAt: body.EndAt,
|
|
})
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
response.Success(c, detail)
|
|
}
|
|
}
|
|
|
|
func approveKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id, err := parseIDParam(c)
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
|
|
var body approveKolSubscriptionRequest
|
|
if c.Request.ContentLength > 0 {
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
response.Error(c, response.ErrBadRequest(40000, "invalid_payload", err.Error()))
|
|
return
|
|
}
|
|
}
|
|
|
|
detail, err := svc.Approve(c.Request.Context(), actorFromGin(c), id, body.EndAt)
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
response.Success(c, detail)
|
|
}
|
|
}
|
|
|
|
func revokeKolSubscriptionHandler(svc *app.KolSubscriptionService) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id, err := parseIDParam(c)
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
|
|
detail, err := svc.Revoke(c.Request.Context(), actorFromGin(c), id)
|
|
if err != nil {
|
|
response.Error(c, err)
|
|
return
|
|
}
|
|
response.Success(c, detail)
|
|
}
|
|
}
|