172 lines
4.6 KiB
Go
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)
|
|
}
|
|
}
|