Commit 739d0ee6 authored by shaw's avatar shaw
Browse files

fix: admin handlers 添加 DTO 转换修复 JSON 序列化

修复 PR #36 合并后部分 admin handler 直接返回 service 层对象导致
JSON 字段名为 PascalCase 而非期望的 snake_case 问题。

修复内容:
- account_handler: Refresh 接口添加 dto.AccountFromService
- openai_oauth_handler: RefreshAccountToken/CreateAccountFromOAuth 添加 dto 转换
- subscription_handler: BulkAssign 添加 dto.BulkAssignResultFromService
- usage_handler: List 接口添加 dto.UsageLogFromService 转换
- 新增 dto.BulkAssignResult 类型和对应的 mapper 函数
parent 22f07a7b
...@@ -376,7 +376,7 @@ func (h *AccountHandler) Refresh(c *gin.Context) { ...@@ -376,7 +376,7 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
return return
} }
response.Success(c, updatedAccount) response.Success(c, dto.AccountFromService(updatedAccount))
} }
// GetStats handles getting account statistics // GetStats handles getting account statistics
......
...@@ -3,6 +3,7 @@ package admin ...@@ -3,6 +3,7 @@ package admin
import ( import (
"strconv" "strconv"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/service" "github.com/Wei-Shaw/sub2api/internal/service"
...@@ -163,7 +164,7 @@ func (h *OpenAIOAuthHandler) RefreshAccountToken(c *gin.Context) { ...@@ -163,7 +164,7 @@ func (h *OpenAIOAuthHandler) RefreshAccountToken(c *gin.Context) {
return return
} }
response.Success(c, updatedAccount) response.Success(c, dto.AccountFromService(updatedAccount))
} }
// CreateAccountFromOAuth creates a new OpenAI OAuth account from token info // CreateAccountFromOAuth creates a new OpenAI OAuth account from token info
...@@ -224,5 +225,5 @@ func (h *OpenAIOAuthHandler) CreateAccountFromOAuth(c *gin.Context) { ...@@ -224,5 +225,5 @@ func (h *OpenAIOAuthHandler) CreateAccountFromOAuth(c *gin.Context) {
return return
} }
response.Success(c, account) response.Success(c, dto.AccountFromService(account))
} }
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/service" "github.com/Wei-Shaw/sub2api/internal/service"
...@@ -57,7 +58,11 @@ func (h *ProxyHandler) List(c *gin.Context) { ...@@ -57,7 +58,11 @@ func (h *ProxyHandler) List(c *gin.Context) {
return return
} }
response.Paginated(c, proxies, total, page, pageSize) out := make([]dto.Proxy, 0, len(proxies))
for i := range proxies {
out = append(out, *dto.ProxyFromService(&proxies[i]))
}
response.Paginated(c, out, total, page, pageSize)
} }
// GetAll handles getting all active proxies without pagination // GetAll handles getting all active proxies without pagination
...@@ -72,7 +77,11 @@ func (h *ProxyHandler) GetAll(c *gin.Context) { ...@@ -72,7 +77,11 @@ func (h *ProxyHandler) GetAll(c *gin.Context) {
response.ErrorFrom(c, err) response.ErrorFrom(c, err)
return return
} }
response.Success(c, proxies) out := make([]dto.ProxyWithAccountCount, 0, len(proxies))
for i := range proxies {
out = append(out, *dto.ProxyWithAccountCountFromService(&proxies[i]))
}
response.Success(c, out)
return return
} }
...@@ -82,7 +91,11 @@ func (h *ProxyHandler) GetAll(c *gin.Context) { ...@@ -82,7 +91,11 @@ func (h *ProxyHandler) GetAll(c *gin.Context) {
return return
} }
response.Success(c, proxies) out := make([]dto.Proxy, 0, len(proxies))
for i := range proxies {
out = append(out, *dto.ProxyFromService(&proxies[i]))
}
response.Success(c, out)
} }
// GetByID handles getting a proxy by ID // GetByID handles getting a proxy by ID
...@@ -100,7 +113,7 @@ func (h *ProxyHandler) GetByID(c *gin.Context) { ...@@ -100,7 +113,7 @@ func (h *ProxyHandler) GetByID(c *gin.Context) {
return return
} }
response.Success(c, proxy) response.Success(c, dto.ProxyFromService(proxy))
} }
// Create handles creating a new proxy // Create handles creating a new proxy
...@@ -125,7 +138,7 @@ func (h *ProxyHandler) Create(c *gin.Context) { ...@@ -125,7 +138,7 @@ func (h *ProxyHandler) Create(c *gin.Context) {
return return
} }
response.Success(c, proxy) response.Success(c, dto.ProxyFromService(proxy))
} }
// Update handles updating a proxy // Update handles updating a proxy
...@@ -157,7 +170,7 @@ func (h *ProxyHandler) Update(c *gin.Context) { ...@@ -157,7 +170,7 @@ func (h *ProxyHandler) Update(c *gin.Context) {
return return
} }
response.Success(c, proxy) response.Success(c, dto.ProxyFromService(proxy))
} }
// Delete handles deleting a proxy // Delete handles deleting a proxy
...@@ -233,7 +246,11 @@ func (h *ProxyHandler) GetProxyAccounts(c *gin.Context) { ...@@ -233,7 +246,11 @@ func (h *ProxyHandler) GetProxyAccounts(c *gin.Context) {
return return
} }
response.Paginated(c, accounts, total, page, pageSize) out := make([]dto.Account, 0, len(accounts))
for i := range accounts {
out = append(out, *dto.AccountFromService(&accounts[i]))
}
response.Paginated(c, out, total, page, pageSize)
} }
// BatchCreateProxyItem represents a single proxy in batch create request // BatchCreateProxyItem represents a single proxy in batch create request
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/service" "github.com/Wei-Shaw/sub2api/internal/service"
...@@ -47,7 +48,11 @@ func (h *RedeemHandler) List(c *gin.Context) { ...@@ -47,7 +48,11 @@ func (h *RedeemHandler) List(c *gin.Context) {
return return
} }
response.Paginated(c, codes, total, page, pageSize) out := make([]dto.RedeemCode, 0, len(codes))
for i := range codes {
out = append(out, *dto.RedeemCodeFromService(&codes[i]))
}
response.Paginated(c, out, total, page, pageSize)
} }
// GetByID handles getting a redeem code by ID // GetByID handles getting a redeem code by ID
...@@ -65,7 +70,7 @@ func (h *RedeemHandler) GetByID(c *gin.Context) { ...@@ -65,7 +70,7 @@ func (h *RedeemHandler) GetByID(c *gin.Context) {
return return
} }
response.Success(c, code) response.Success(c, dto.RedeemCodeFromService(code))
} }
// Generate handles generating new redeem codes // Generate handles generating new redeem codes
...@@ -89,7 +94,11 @@ func (h *RedeemHandler) Generate(c *gin.Context) { ...@@ -89,7 +94,11 @@ func (h *RedeemHandler) Generate(c *gin.Context) {
return return
} }
response.Success(c, codes) out := make([]dto.RedeemCode, 0, len(codes))
for i := range codes {
out = append(out, *dto.RedeemCodeFromService(&codes[i]))
}
response.Success(c, out)
} }
// Delete handles deleting a redeem code // Delete handles deleting a redeem code
...@@ -148,7 +157,7 @@ func (h *RedeemHandler) Expire(c *gin.Context) { ...@@ -148,7 +157,7 @@ func (h *RedeemHandler) Expire(c *gin.Context) {
return return
} }
response.Success(c, code) response.Success(c, dto.RedeemCodeFromService(code))
} }
// GetStats handles getting redeem code statistics // GetStats handles getting redeem code statistics
......
...@@ -177,7 +177,7 @@ func (h *SubscriptionHandler) BulkAssign(c *gin.Context) { ...@@ -177,7 +177,7 @@ func (h *SubscriptionHandler) BulkAssign(c *gin.Context) {
return return
} }
response.Success(c, result) response.Success(c, dto.BulkAssignResultFromService(result))
} }
// Extend handles extending a subscription // Extend handles extending a subscription
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination" "github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/pkg/timezone" "github.com/Wei-Shaw/sub2api/internal/pkg/timezone"
...@@ -94,7 +95,11 @@ func (h *UsageHandler) List(c *gin.Context) { ...@@ -94,7 +95,11 @@ func (h *UsageHandler) List(c *gin.Context) {
return return
} }
response.Paginated(c, records, result.Total, page, pageSize) out := make([]dto.UsageLog, 0, len(records))
for i := range records {
out = append(out, *dto.UsageLogFromService(&records[i]))
}
response.Paginated(c, out, result.Total, page, pageSize)
} }
// Stats handles getting usage statistics with filters // Stats handles getting usage statistics with filters
......
...@@ -3,6 +3,7 @@ package admin ...@@ -3,6 +3,7 @@ package admin
import ( import (
"strconv" "strconv"
"github.com/Wei-Shaw/sub2api/internal/handler/dto"
"github.com/Wei-Shaw/sub2api/internal/pkg/response" "github.com/Wei-Shaw/sub2api/internal/pkg/response"
"github.com/Wei-Shaw/sub2api/internal/service" "github.com/Wei-Shaw/sub2api/internal/service"
...@@ -68,7 +69,11 @@ func (h *UserHandler) List(c *gin.Context) { ...@@ -68,7 +69,11 @@ func (h *UserHandler) List(c *gin.Context) {
return return
} }
response.Paginated(c, users, total, page, pageSize) out := make([]dto.User, 0, len(users))
for i := range users {
out = append(out, *dto.UserFromService(&users[i]))
}
response.Paginated(c, out, total, page, pageSize)
} }
// GetByID handles getting a user by ID // GetByID handles getting a user by ID
...@@ -86,7 +91,7 @@ func (h *UserHandler) GetByID(c *gin.Context) { ...@@ -86,7 +91,7 @@ func (h *UserHandler) GetByID(c *gin.Context) {
return return
} }
response.Success(c, user) response.Success(c, dto.UserFromService(user))
} }
// Create handles creating a new user // Create handles creating a new user
...@@ -113,7 +118,7 @@ func (h *UserHandler) Create(c *gin.Context) { ...@@ -113,7 +118,7 @@ func (h *UserHandler) Create(c *gin.Context) {
return return
} }
response.Success(c, user) response.Success(c, dto.UserFromService(user))
} }
// Update handles updating a user // Update handles updating a user
...@@ -148,7 +153,7 @@ func (h *UserHandler) Update(c *gin.Context) { ...@@ -148,7 +153,7 @@ func (h *UserHandler) Update(c *gin.Context) {
return return
} }
response.Success(c, user) response.Success(c, dto.UserFromService(user))
} }
// Delete handles deleting a user // Delete handles deleting a user
...@@ -190,7 +195,7 @@ func (h *UserHandler) UpdateBalance(c *gin.Context) { ...@@ -190,7 +195,7 @@ func (h *UserHandler) UpdateBalance(c *gin.Context) {
return return
} }
response.Success(c, user) response.Success(c, dto.UserFromService(user))
} }
// GetUserAPIKeys handles getting user's API keys // GetUserAPIKeys handles getting user's API keys
...@@ -210,7 +215,11 @@ func (h *UserHandler) GetUserAPIKeys(c *gin.Context) { ...@@ -210,7 +215,11 @@ func (h *UserHandler) GetUserAPIKeys(c *gin.Context) {
return return
} }
response.Paginated(c, keys, total, page, pageSize) out := make([]dto.ApiKey, 0, len(keys))
for i := range keys {
out = append(out, *dto.ApiKeyFromService(&keys[i]))
}
response.Paginated(c, out, total, page, pageSize)
} }
// GetUserUsage handles getting user's usage statistics // GetUserUsage handles getting user's usage statistics
......
...@@ -292,3 +292,19 @@ func UserSubscriptionFromService(sub *service.UserSubscription) *UserSubscriptio ...@@ -292,3 +292,19 @@ func UserSubscriptionFromService(sub *service.UserSubscription) *UserSubscriptio
AssignedByUser: UserFromServiceShallow(sub.AssignedByUser), AssignedByUser: UserFromServiceShallow(sub.AssignedByUser),
} }
} }
func BulkAssignResultFromService(r *service.BulkAssignResult) *BulkAssignResult {
if r == nil {
return nil
}
subs := make([]UserSubscription, 0, len(r.Subscriptions))
for i := range r.Subscriptions {
subs = append(subs, *UserSubscriptionFromService(&r.Subscriptions[i]))
}
return &BulkAssignResult{
SuccessCount: r.SuccessCount,
FailedCount: r.FailedCount,
Subscriptions: subs,
Errors: r.Errors,
}
}
...@@ -210,3 +210,10 @@ type UserSubscription struct { ...@@ -210,3 +210,10 @@ type UserSubscription struct {
Group *Group `json:"group,omitempty"` Group *Group `json:"group,omitempty"`
AssignedByUser *User `json:"assigned_by_user,omitempty"` AssignedByUser *User `json:"assigned_by_user,omitempty"`
} }
type BulkAssignResult struct {
SuccessCount int `json:"success_count"`
FailedCount int `json:"failed_count"`
Subscriptions []UserSubscription `json:"subscriptions"`
Errors []string `json:"errors"`
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment