package controller import ( "fmt" "net/http" "one-api/common" "one-api/model" "strconv" "time" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" ) // GetAllServers 获取所有服务器配置(管理员) func GetAllServers(c *gin.Context) { p, _ := strconv.Atoi(c.Query("p")) if p < 0 { p = 0 } pageSize, _ := strconv.Atoi(c.Query("page_size")) if pageSize <= 0 { pageSize = common.ItemsPerPage } pageInfo := &common.PageInfo{ Page: p, PageSize: pageSize, } servers, total, err := model.GetAllServers(pageInfo) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": servers, "total": total, }) } // SearchServers 搜索服务器配置(管理员) func SearchServers(c *gin.Context) { keyword := c.Query("keyword") p, _ := strconv.Atoi(c.Query("p")) if p < 0 { p = 0 } pageSize, _ := strconv.Atoi(c.Query("page_size")) if pageSize <= 0 { pageSize = common.ItemsPerPage } servers, total, err := model.SearchServers(keyword, p*pageSize, pageSize) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": servers, "total": total, }) } // GetServer 获取单个服务器配置(管理员) func GetServer(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } server, err := model.GetServerById(id) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": server, }) } // AddServer 添加服务器配置(管理员) func AddServer(c *gin.Context) { server := model.Server{} err := c.ShouldBindJSON(&server) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } err = server.Insert() if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": server, }) } // UpdateServer 更新服务器配置(管理员) func UpdateServer(c *gin.Context) { server := model.Server{} err := c.ShouldBindJSON(&server) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } err = server.Update() if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": server, }) } // DeleteServer 删除服务器配置(管理员) func DeleteServer(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } err = model.DeleteServerById(id) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", }) } // GetEnabledServers 获取启用的服务器列表(用户) func GetEnabledServers(c *gin.Context) { servers, err := model.GetEnabledServers() if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": servers, }) } // GetAllPurchasedServers 获取所有已购服务器(管理员) func GetAllPurchasedServers(c *gin.Context) { p, _ := strconv.Atoi(c.Query("p")) if p < 0 { p = 0 } pageSize, _ := strconv.Atoi(c.Query("page_size")) if pageSize <= 0 { pageSize = common.ItemsPerPage } pageInfo := &common.PageInfo{ Page: p, PageSize: pageSize, } servers, total, err := model.GetAllPurchasedServers(pageInfo) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } // 获取用户名 type PurchasedServerWithUsername struct { model.PurchasedServer Username string `json:"username"` } serversWithUsername := make([]PurchasedServerWithUsername, len(servers)) for i, server := range servers { username, _ := model.GetUsernameById(server.UserId, false) serversWithUsername[i] = PurchasedServerWithUsername{ PurchasedServer: *server, Username: username, } } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": serversWithUsername, "total": total, }) } // SearchPurchasedServers 搜索已购服务器(管理员) func SearchPurchasedServers(c *gin.Context) { keyword := c.Query("keyword") p, _ := strconv.Atoi(c.Query("p")) if p < 0 { p = 0 } pageSize, _ := strconv.Atoi(c.Query("page_size")) if pageSize <= 0 { pageSize = common.ItemsPerPage } servers, total, err := model.SearchPurchasedServers(keyword, p*pageSize, pageSize) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } // 获取用户名 type PurchasedServerWithUsername struct { model.PurchasedServer Username string `json:"username"` } serversWithUsername := make([]PurchasedServerWithUsername, len(servers)) for i, server := range servers { username, _ := model.GetUsernameById(server.UserId, false) serversWithUsername[i] = PurchasedServerWithUsername{ PurchasedServer: *server, Username: username, } } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": serversWithUsername, "total": total, }) } // GetUserPurchasedServers 获取用户已购服务器列表 func GetUserPurchasedServers(c *gin.Context) { userId := c.GetInt("id") p, _ := strconv.Atoi(c.Query("p")) if p < 0 { p = 0 } pageSize, _ := strconv.Atoi(c.Query("page_size")) if pageSize <= 0 { pageSize = common.ItemsPerPage } pageInfo := &common.PageInfo{ Page: p, PageSize: pageSize, } servers, total, err := model.GetUserPurchasedServers(userId, pageInfo) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", "data": servers, "total": total, }) } type PurchaseServerRequest struct { ServerId int `json:"server_id" binding:"required"` TradeNo string `json:"trade_no"` } // PurchaseServer 购买服务器 func PurchaseServer(c *gin.Context) { var req PurchaseServerRequest err := c.ShouldBindJSON(&req) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "参数错误", }) return } userId := c.GetInt("id") // 获取服务器配置 server, err := model.GetServerById(req.ServerId) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "服务器配置不存在", }) return } if server.Status != 1 { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "服务器已下架", }) return } // 检查库存 if server.Stock == 0 { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "服务器库存不足", }) return } // 计算需要扣除的额度 dPrice := decimal.NewFromFloat(server.Price) dQuotaPerUnit := decimal.NewFromFloat(common.QuotaPerUnit) quotaNeeded := int(dPrice.Mul(dQuotaPerUnit).IntPart()) // 检查用户额度 userQuota, err := model.GetUserQuota(userId, true) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "获取用户额度失败", }) return } if userQuota < quotaNeeded { c.JSON(http.StatusOK, gin.H{ "success": false, "message": fmt.Sprintf("额度不足,需要 %s,当前额度 %s", common.LogQuota(quotaNeeded), common.LogQuota(userQuota)), }) return } // 扣除用户额度 err = model.DecreaseUserQuota(userId, quotaNeeded) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": "扣除额度失败", }) return } // 创建已购服务器记录 now := time.Now().Unix() expireTime := now + int64(server.Duration*24*3600) tradeNo := req.TradeNo if tradeNo == "" { tradeNo = fmt.Sprintf("SRV%dNO%s", userId, fmt.Sprintf("%s%d", common.GetRandomString(6), time.Now().Unix())) } purchasedServer := &model.PurchasedServer{ UserId: userId, ServerId: server.Id, ServerTitle: server.Title, ServerConfig: server.Config, Price: server.Price, Duration: server.Duration, PurchaseTime: now, ExpireTime: expireTime, Status: 1, TradeNo: tradeNo, } err = purchasedServer.Insert() if err != nil { // 回滚额度 _ = model.IncreaseUserQuota(userId, quotaNeeded, true) c.JSON(http.StatusOK, gin.H{ "success": false, "message": "创建订单失败", }) return } // 更新库存 if server.Stock > 0 { server.Stock-- _ = server.Update() } // 记录日志 model.RecordLog(userId, model.LogTypeSystem, fmt.Sprintf("购买服务器 %s,消耗额度 %s,有效期 %d 天", server.Title, common.LogQuota(quotaNeeded), server.Duration)) c.JSON(http.StatusOK, gin.H{ "success": true, "message": "购买成功", "data": purchasedServer, }) } // DeletePurchasedServer 删除已购服务器记录(管理员) func DeletePurchasedServer(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } err = model.DeletePurchasedServerById(id) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, "message": err.Error(), }) return } c.JSON(http.StatusOK, gin.H{ "success": true, "message": "", }) }