Files
goalfylearning-admin/internal/api/handlers/finance_handler.go

634 lines
18 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"reflect"
"strconv"
"strings"
"github.com/gin-gonic/gin"
"goalfymax-admin/internal/services"
"goalfymax-admin/pkg/utils"
)
type FinanceHandler struct {
response *utils.Response
}
func NewFinanceHandler() *FinanceHandler {
return &FinanceHandler{response: utils.NewResponse()}
}
func getPageParams(c *gin.Context) (int, int) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
if page < 1 {
page = 1
}
if size < 1 {
size = 20
}
offset := (page - 1) * size
return offset, size
}
func (h *FinanceHandler) ListSandboxRecords(c *gin.Context) {
offset, size := getPageParams(c)
// 兼容多种参数命名user/user_idproject/project_id
userID := c.DefaultQuery("user_id", c.Query("user"))
project := c.DefaultQuery("project", c.Query("project_id"))
start := c.Query("start")
end := c.Query("end")
res, err := services.ListSandboxRecords(offset, size, userID, project, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) ListTokenUsages(c *gin.Context) {
offset, size := getPageParams(c)
userID := c.DefaultQuery("user_id", c.Query("user"))
project := c.DefaultQuery("project", c.Query("project_id"))
start := c.Query("start") // 对于token使用按day进行过滤
end := c.Query("end")
res, err := services.ListTokenUsages(offset, size, userID, project, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) ListMCPUsages(c *gin.Context) {
offset, size := getPageParams(c)
userID := c.DefaultQuery("user_id", c.Query("user"))
project := c.DefaultQuery("project", c.Query("project_id"))
start := c.Query("start")
end := c.Query("end")
res, err := services.ListMCPUsages(offset, size, userID, project, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) ListTransactionLogs(c *gin.Context) {
offset, size := getPageParams(c)
userID := c.Query("user_id")
orderID := c.Query("order_id")
txType := c.Query("type")
status := c.Query("status")
start := c.Query("start")
end := c.Query("end")
res, err := services.ListTransactionLogs(offset, size, userID, orderID, txType, status, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) ListPaymentRecords(c *gin.Context) {
offset, size := getPageParams(c)
userID := c.Query("user_id")
orderID := c.Query("order_id")
paypalOrderID := c.Query("paypal_order_id")
status := c.Query("status")
refundStatus := c.Query("refund_status")
payerEmail := c.Query("payer_email")
start := c.Query("start")
end := c.Query("end")
res, err := services.ListPaymentRecords(offset, size, userID, orderID, paypalOrderID, status, refundStatus, payerEmail, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) RefundPaymentRecord(c *gin.Context) {
var req struct {
OrderID string `json:"order_id"`
PayPalCaptureID string `json:"paypal_capture_id"`
Amount *int64 `json:"amount"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
err := services.RefundPaymentRecord(req.OrderID, req.PayPalCaptureID, req.Amount)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "退款请求已提交"})
}
func (h *FinanceHandler) ListMcpAccountRechargeRecords(c *gin.Context) {
offset, size := getPageParams(c)
provider := c.Query("provider")
account := c.Query("account")
start := c.Query("start")
end := c.Query("end")
res, err := services.ListMcpAccountRechargeRecords(offset, size, provider, account, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) CreateMcpAccountRechargeRecord(c *gin.Context) {
var req struct {
ProviderID string `json:"provider_id" binding:"required"`
Amount float64 `json:"amount" binding:"required,gt=0"`
RechargeDate string `json:"recharge_date" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
// 获取当前操作人信息
var operatorID interface{}
operatorName := "系统管理员"
if user, exists := c.Get("user"); exists {
if userInfo, ok := user.(map[string]interface{}); ok {
// 尝试从userInfo中获取sub字段可能是UUID格式
if sub, ok := userInfo["sub"].(string); ok {
operatorID = sub
}
if name, ok := userInfo["name"].(string); ok {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok {
operatorName = email
}
}
}
// 如果user中没有sub尝试从user_id获取
if operatorID == nil {
operatorID, _ = c.Get("user_id")
}
err := services.CreateMcpAccountRechargeRecord(
req.ProviderID,
req.Amount,
req.RechargeDate,
operatorID,
operatorName,
req.Remark,
)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "创建成功"})
}
func (h *FinanceHandler) UpdateMcpAccountRechargeRecord(c *gin.Context) {
id := c.Param("id")
var req struct {
Amount *float64 `json:"amount"`
RechargeDate *string `json:"recharge_date"`
Remark *string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
err := services.UpdateMcpAccountRechargeRecord(id, req.Amount, req.RechargeDate, req.Remark)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "更新成功"})
}
func (h *FinanceHandler) DeleteMcpAccountRechargeRecord(c *gin.Context) {
id := c.Param("id")
err := services.DeleteMcpAccountRechargeRecord(id)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "删除成功"})
}
func (h *FinanceHandler) GetMcpProviderAccounts(c *gin.Context) {
status := c.Query("status")
var isUsed *bool
if v := c.Query("is_used"); v != "" {
if v == "true" {
val := true
isUsed = &val
} else if v == "false" {
val := false
isUsed = &val
}
}
list, err := services.GetMcpProviderAccounts(status, isUsed)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
func (h *FinanceHandler) GetMcpAccountBalances(c *gin.Context) {
list, err := services.GetMcpAccountBalances()
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
func (h *FinanceHandler) GetMcpAccountBalanceHistory(c *gin.Context) {
providerID := c.Param("provider_id")
start := c.Query("start")
end := c.Query("end")
list, err := services.GetMcpAccountBalanceHistory(providerID, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
// ========== 模型账号充值记录和余额管理 ==========
func (h *FinanceHandler) ListModelAccountRechargeRecords(c *gin.Context) {
offset, size := getPageParams(c)
provider := c.Query("provider")
modelName := c.Query("model_name")
start := c.Query("start")
end := c.Query("end")
res, err := services.ListModelAccountRechargeRecords(offset, size, provider, modelName, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Page(c, res.List, res.Total, offset/size+1, size)
}
func (h *FinanceHandler) CreateModelAccountRechargeRecord(c *gin.Context) {
var req struct {
Account string `json:"account" binding:"required"`
Amount float64 `json:"amount" binding:"required,gt=0"`
RechargeDate string `json:"recharge_date" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
// 获取当前操作人信息
var operatorID interface{}
operatorName := "系统管理员"
// 先尝试从 user_id 获取
if userID, exists := c.Get("user_id"); exists {
operatorID = userID
}
// 从 user 信息中获取名称
if user, exists := c.Get("user"); exists {
// user 可能是 *models.UserInfo 类型
if userInfo, ok := user.(map[string]interface{}); ok {
if name, ok := userInfo["name"].(string); ok && name != "" {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok && email != "" {
operatorName = email
}
} else {
// 尝试使用反射获取结构体字段
userVal := reflect.ValueOf(user)
if userVal.Kind() == reflect.Ptr {
userVal = userVal.Elem()
}
if userVal.Kind() == reflect.Struct {
if nameField := userVal.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
if name := nameField.String(); name != "" {
operatorName = name
}
}
if operatorName == "系统管理员" {
if emailField := userVal.FieldByName("Email"); emailField.IsValid() && emailField.Kind() == reflect.String {
if email := emailField.String(); email != "" {
operatorName = email
}
}
}
}
}
}
err := services.CreateModelAccountRechargeRecord(
req.Account,
req.Amount,
req.RechargeDate,
operatorID,
operatorName,
req.Remark,
)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "创建成功"})
}
func (h *FinanceHandler) UpdateModelAccountRechargeRecord(c *gin.Context) {
id := c.Param("id")
var req struct {
Amount *float64 `json:"amount"`
RechargeDate *string `json:"recharge_date"`
Remark *string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
err := services.UpdateModelAccountRechargeRecord(id, req.Amount, req.RechargeDate, req.Remark)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "更新成功"})
}
func (h *FinanceHandler) DeleteModelAccountRechargeRecord(c *gin.Context) {
id := c.Param("id")
err := services.DeleteModelAccountRechargeRecord(id)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "删除成功"})
}
func (h *FinanceHandler) GetModelConfigAccounts(c *gin.Context) {
var enabled *bool
if v := c.Query("enabled"); v != "" {
if v == "true" {
val := true
enabled = &val
} else if v == "false" {
val := false
enabled = &val
}
}
list, err := services.GetModelConfigAccounts(enabled)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
func (h *FinanceHandler) GetModelAccountBalances(c *gin.Context) {
list, err := services.GetModelAccountBalances()
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
func (h *FinanceHandler) GetModelAccountBalanceHistory(c *gin.Context) {
account := c.Param("account")
start := c.Query("start")
end := c.Query("end")
list, err := services.GetModelAccountBalanceHistory(account, start, end)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, list)
}
func (h *FinanceHandler) AdjustMcpAccountBalance(c *gin.Context) {
providerID := c.Param("provider_id")
var req struct {
Balance float64 `json:"balance" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
operatorName := "系统管理员"
if user, exists := c.Get("user"); exists {
if userInfo, ok := user.(map[string]interface{}); ok {
if name, ok := userInfo["name"].(string); ok && name != "" {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok && email != "" {
operatorName = email
}
} else {
userVal := reflect.ValueOf(user)
if userVal.Kind() == reflect.Ptr {
userVal = userVal.Elem()
}
if userVal.Kind() == reflect.Struct {
if nameField := userVal.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
if name := nameField.String(); name != "" {
operatorName = name
}
}
if operatorName == "系统管理员" {
if emailField := userVal.FieldByName("Email"); emailField.IsValid() && emailField.Kind() == reflect.String {
if email := emailField.String(); email != "" {
operatorName = email
}
}
}
}
}
}
if err := services.AdjustMcpAccountBalance(providerID, req.Balance, operatorName, req.Remark); err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "更新成功"})
}
func (h *FinanceHandler) AdjustModelAccountBalance(c *gin.Context) {
account := c.Param("account")
var req struct {
Balance float64 `json:"balance" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
operatorName := "系统管理员"
if user, exists := c.Get("user"); exists {
if userInfo, ok := user.(map[string]interface{}); ok {
if name, ok := userInfo["name"].(string); ok && name != "" {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok && email != "" {
operatorName = email
}
} else {
userVal := reflect.ValueOf(user)
if userVal.Kind() == reflect.Ptr {
userVal = userVal.Elem()
}
if userVal.Kind() == reflect.Struct {
if nameField := userVal.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
if name := nameField.String(); name != "" {
operatorName = name
}
}
if operatorName == "系统管理员" {
if emailField := userVal.FieldByName("Email"); emailField.IsValid() && emailField.Kind() == reflect.String {
if email := emailField.String(); email != "" {
operatorName = email
}
}
}
}
}
}
if err := services.AdjustModelAccountBalance(account, req.Balance, operatorName, req.Remark); err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "更新成功"})
}
func (h *FinanceHandler) CreateModelAccountBalance(c *gin.Context) {
var req struct {
Account string `json:"account" binding:"required"`
Balance float64 `json:"balance" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
operatorName := "系统管理员"
if user, exists := c.Get("user"); exists {
if userInfo, ok := user.(map[string]interface{}); ok {
if name, ok := userInfo["name"].(string); ok && name != "" {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok && email != "" {
operatorName = email
}
} else {
userVal := reflect.ValueOf(user)
if userVal.Kind() == reflect.Ptr {
userVal = userVal.Elem()
}
if userVal.Kind() == reflect.Struct {
if nameField := userVal.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
if name := nameField.String(); name != "" {
operatorName = name
}
}
if operatorName == "系统管理员" {
if emailField := userVal.FieldByName("Email"); emailField.IsValid() && emailField.Kind() == reflect.String {
if email := emailField.String(); email != "" {
operatorName = email
}
}
}
}
}
}
if err := services.CreateModelAccountBalanceRecord(req.Account, req.Balance, operatorName, req.Remark); err != nil {
if strings.Contains(err.Error(), "已存在") {
h.response.BadRequest(c, err.Error())
} else {
h.response.InternalServerError(c, err.Error())
}
return
}
h.response.Success(c, gin.H{"message": "创建成功"})
}
func (h *FinanceHandler) CreateMcpAccountBalance(c *gin.Context) {
var req struct {
ProviderID string `json:"provider_id" binding:"required"`
Balance float64 `json:"balance" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
operatorName := "系统管理员"
if user, exists := c.Get("user"); exists {
if userInfo, ok := user.(map[string]interface{}); ok {
if name, ok := userInfo["name"].(string); ok && name != "" {
operatorName = name
} else if email, ok := userInfo["email"].(string); ok && email != "" {
operatorName = email
}
} else {
userVal := reflect.ValueOf(user)
if userVal.Kind() == reflect.Ptr {
userVal = userVal.Elem()
}
if userVal.Kind() == reflect.Struct {
if nameField := userVal.FieldByName("Name"); nameField.IsValid() && nameField.Kind() == reflect.String {
if name := nameField.String(); name != "" {
operatorName = name
}
}
if operatorName == "系统管理员" {
if emailField := userVal.FieldByName("Email"); emailField.IsValid() && emailField.Kind() == reflect.String {
if email := emailField.String(); email != "" {
operatorName = email
}
}
}
}
}
}
if err := services.CreateMcpAccountBalanceRecord(req.ProviderID, req.Balance, operatorName, req.Remark); err != nil {
if strings.Contains(err.Error(), "已存在") {
h.response.BadRequest(c, err.Error())
} else {
h.response.InternalServerError(c, err.Error())
}
return
}
h.response.Success(c, gin.H{"message": "创建成功"})
}