Files
gpt-plus-gpt/internal/handler/account.go
2026-03-15 20:48:19 +08:00

172 lines
4.6 KiB
Go

package handler
import (
"fmt"
"net/http"
"gpt-plus/internal/db"
"gpt-plus/internal/service"
"github.com/gin-gonic/gin"
)
func RegisterAccountRoutes(api *gin.RouterGroup) {
api.GET("/accounts", ListAccounts)
api.GET("/accounts/:id", GetAccount)
api.POST("/accounts/check", CheckAccounts)
api.POST("/accounts/:id/check", CheckSingleAccount)
api.POST("/accounts/test-model", TestModel)
api.PUT("/accounts/:id/note", UpdateAccountNote)
api.POST("/accounts/export", ExportAccounts)
api.POST("/accounts/:id/transfer-to-cpa", TransferToCPA)
}
func ListAccounts(c *gin.Context) {
d := db.GetDB()
query := d.Model(&db.Account{}).Order("created_at DESC")
plan := c.Query("plan")
if plan != "" && plan != "all" {
query = query.Where("plan = ?", plan)
}
// "all" or empty: show everything
if status := c.Query("status"); status != "" {
query = query.Where("status = ?", status)
}
if search := c.Query("search"); search != "" {
query = query.Where("email LIKE ?", "%"+search+"%")
}
p := db.PaginationParams{Page: intQuery(c, "page", 1), Size: intQuery(c, "size", 20)}
var accounts []db.Account
result, err := db.Paginate(query, p, &accounts)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
for i := range accounts {
if accounts[i].Plan == "team_owner" {
d.Where("parent_id = ?", accounts[i].ID).Find(&accounts[i].SubAccounts)
}
if accounts[i].Plan == "team_member" && accounts[i].ParentID != nil {
var parent db.Account
if d.First(&parent, *accounts[i].ParentID).Error == nil {
accounts[i].Parent = &parent
}
}
}
result.Items = accounts
c.JSON(http.StatusOK, result)
}
func GetAccount(c *gin.Context) {
var account db.Account
d := db.GetDB()
if err := d.First(&account, c.Param("id")).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "账号不存在"})
return
}
if account.Plan == "team_owner" {
d.Where("parent_id = ?", account.ID).Find(&account.SubAccounts)
}
c.JSON(http.StatusOK, account)
}
func CheckAccounts(c *gin.Context) {
var req struct {
IDs []uint `json:"ids" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
results := service.CheckAccountStatuses(db.GetDB(), req.IDs)
c.JSON(http.StatusOK, gin.H{"message": "状态检查完成", "results": results})
}
func CheckSingleAccount(c *gin.Context) {
id := c.Param("id")
var uid uint
if _, err := fmt.Sscanf(id, "%d", &uid); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
return
}
results := service.CheckAccountStatuses(db.GetDB(), []uint{uid})
if len(results) > 0 {
c.JSON(http.StatusOK, results[0])
} else {
c.JSON(http.StatusNotFound, gin.H{"error": "账号不存在"})
}
}
func TestModel(c *gin.Context) {
var req struct {
ID uint `json:"id" binding:"required"`
Model string `json:"model"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
result := service.TestModelAvailability(db.GetDB(), req.ID, req.Model)
c.JSON(http.StatusOK, result)
}
func UpdateAccountNote(c *gin.Context) {
var req struct {
Note string `json:"note"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := db.GetDB().Model(&db.Account{}).Where("id = ?", c.Param("id")).Update("note", req.Note).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "备注已更新"})
}
func TransferToCPA(c *gin.Context) {
id := c.Param("id")
var uid uint
if _, err := fmt.Sscanf(id, "%d", &uid); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
return
}
result := service.TransferAccountToCPA(db.GetDB(), uid)
if result.OK {
c.JSON(http.StatusOK, result)
} else {
c.JSON(http.StatusInternalServerError, result)
}
}
func ExportAccounts(c *gin.Context) {
var req struct {
IDs []uint `json:"ids" binding:"required"`
Note string `json:"note"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
data, filename, err := service.ExportAccounts(db.GetDB(), req.IDs, req.Note)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.Header("Content-Disposition", "attachment; filename=\""+filename+"\"")
if len(req.IDs) > 1 {
c.Data(http.StatusOK, "application/zip", data)
} else {
c.Data(http.StatusOK, "application/json", data)
}
}