304 lines
8.4 KiB
Go
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
|
|
}
|