Files
geo/server/internal/tenant/transport/media_supply_handler.go
T

304 lines
8.4 KiB
Go

package transport
import (
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/geo-platform/tenant-api/internal/bootstrap"
"github.com/geo-platform/tenant-api/internal/shared/response"
"github.com/geo-platform/tenant-api/internal/tenant/app"
)
type MediaSupplyHandler struct {
svc *app.MediaSupplyService
}
func NewMediaSupplyHandler(a *bootstrap.App) *MediaSupplyHandler {
svc := a.MediaSupplyService
if svc == nil {
svc = app.NewMediaSupplyService(a.DB, a.Redis, a.Logger, a.ConfigStore).WithObjectStorage(a.ObjectStorage)
}
return &MediaSupplyHandler{
svc: svc,
}
}
func (h *MediaSupplyHandler) ListResources(c *gin.Context) {
modelID, err := parseOptionalIntQuery(c, "model_id")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_model_id", "媒体资源类型参数必须是数字"))
return
}
page, _ := parseOptionalIntQuery(c, "page")
pageSize, _ := parseOptionalIntQuery(c, "page_size")
minPriceCents, err := parseOptionalInt64Query(c, "min_price_cents")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_min_price_cents", "最低价格参数必须是数字"))
return
}
maxPriceCents, err := parseOptionalInt64Query(c, "max_price_cents")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_max_price_cents", "最高价格参数必须是数字"))
return
}
data, err := h.svc.ListCustomerResources(c.Request.Context(), app.ListSupplierMediaResourcesRequest{
ModelID: modelID,
Keyword: c.Query("keyword"),
RemarkKeyword: c.Query("remark_keyword"),
ChannelType: c.Query("channel_type"),
Portal: c.Query("portal"),
Region: c.Query("region"),
InclusionEffect: c.Query("inclusion_effect"),
SpecialIndustry: c.Query("special_industry"),
LinkType: c.Query("link_type"),
DeliverySpeed: c.Query("delivery_speed"),
AIInclude: c.Query("ai_include"),
OtherOption: c.Query("other_option"),
MinPriceCents: minPriceCents,
MaxPriceCents: maxPriceCents,
Sort: c.Query("sort"),
Page: page,
PageSize: pageSize,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) ListResourcesByIDs(c *gin.Context) {
ids, err := parseInt64ListQuery(c, "ids")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_resource_ids", "媒体资源参数必须是数字"))
return
}
modelID, err := parseOptionalIntQuery(c, "model_id")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_model_id", "媒体资源类型参数必须是数字"))
return
}
data, err := h.svc.ListCustomerResourcesByIDs(c.Request.Context(), ids, modelID)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) QueueSync(c *gin.Context) {
response.Error(c, response.ErrNotFound(40400, "not_found", "接口不存在"))
}
func (h *MediaSupplyHandler) SearchOptions(c *gin.Context) {
modelID, err := parseOptionalIntQuery(c, "model_id")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_model_id", "媒体资源类型参数必须是数字"))
return
}
data, err := h.svc.SearchOptions(c.Request.Context(), modelID)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) SetResourcePrice(c *gin.Context) {
response.Error(c, response.ErrNotFound(40400, "not_found", "接口不存在"))
}
func (h *MediaSupplyHandler) CreateOrder(c *gin.Context) {
var req app.CreateMediaSupplyOrderRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_params", "投稿参数不正确"))
return
}
data, err := h.svc.CreateOrder(c.Request.Context(), req)
if err != nil {
response.Error(c, err)
return
}
response.SuccessWithStatus(c, 201, data)
}
func (h *MediaSupplyHandler) WalletStatus(c *gin.Context) {
data, err := h.svc.WalletStatus(c.Request.Context())
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) ListWalletLedgers(c *gin.Context) {
page, _ := parseOptionalIntQuery(c, "page")
pageSize, _ := parseOptionalIntQuery(c, "page_size")
userID, err := parseOptionalInt64Query(c, "user_id")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_user_id", "用户参数必须是数字"))
return
}
createdFrom, err := parseOptionalTimeQuery(c, "created_from")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_created_from", "开始时间格式不正确"))
return
}
createdTo, err := parseOptionalTimeQuery(c, "created_to")
if err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_created_to", "结束时间格式不正确"))
return
}
data, err := h.svc.ListWalletLedgers(c.Request.Context(), app.ListMediaSupplyWalletLedgersRequest{
Page: page,
PageSize: pageSize,
UserID: userID,
CreatedFrom: createdFrom,
CreatedTo: createdTo,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) AdjustWallet(c *gin.Context) {
response.Error(c, response.ErrNotFound(40400, "not_found", "接口不存在"))
}
func (h *MediaSupplyHandler) ListOrders(c *gin.Context) {
page, _ := parseOptionalIntQuery(c, "page")
pageSize, _ := parseOptionalIntQuery(c, "page_size")
var articleID *int64
if raw := c.Query("article_id"); raw != "" {
parsed, err := strconv.ParseInt(raw, 10, 64)
if err != nil || parsed <= 0 {
response.Error(c, response.ErrBadRequest(40001, "invalid_article_id", "文章参数必须是数字"))
return
}
articleID = &parsed
}
data, err := h.svc.ListOrders(c.Request.Context(), app.ListMediaSupplyOrdersRequest{
Status: c.Query("status"),
ArticleID: articleID,
Page: page,
PageSize: pageSize,
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) GetOrder(c *gin.Context) {
orderID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil || orderID <= 0 {
response.Error(c, response.ErrBadRequest(40001, "invalid_id", "订单参数必须是数字"))
return
}
data, err := h.svc.GetOrder(c.Request.Context(), orderID)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) ImportSession(c *gin.Context) {
var req app.ImportMeijiequanSessionRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.Error(c, response.ErrBadRequest(40001, "invalid_params", "登录状态参数不正确"))
return
}
data, err := h.svc.ImportSession(c.Request.Context(), req)
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) LoginConfiguredAccount(c *gin.Context) {
data, err := h.svc.LoginConfiguredAccount(c.Request.Context())
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *MediaSupplyHandler) SessionStatus(c *gin.Context) {
data, err := h.svc.SessionStatus(c.Request.Context())
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func parseOptionalIntQuery(c *gin.Context, key string) (int, error) {
raw := c.Query(key)
if raw == "" {
return 0, nil
}
value, err := strconv.Atoi(raw)
if err != nil {
return 0, err
}
return value, nil
}
func parseOptionalInt64Query(c *gin.Context, key string) (int64, error) {
raw := c.Query(key)
if raw == "" {
return 0, nil
}
value, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return 0, err
}
return value, nil
}
func parseOptionalTimeQuery(c *gin.Context, key string) (*time.Time, error) {
raw := c.Query(key)
if raw == "" {
return nil, nil
}
value, err := time.Parse(time.RFC3339, raw)
if err != nil {
return nil, err
}
return &value, nil
}
func parseInt64ListQuery(c *gin.Context, key string) ([]int64, error) {
rawValues := c.QueryArray(key)
if len(rawValues) == 0 {
rawValues = []string{c.Query(key)}
}
values := make([]int64, 0, len(rawValues))
for _, raw := range rawValues {
for _, part := range strings.Split(raw, ",") {
part = strings.TrimSpace(part)
if part == "" {
continue
}
value, err := strconv.ParseInt(part, 10, 64)
if err != nil || value <= 0 {
return nil, strconv.ErrSyntax
}
values = append(values, value)
if len(values) >= 100 {
return values, nil
}
}
}
return values, nil
}