469 lines
9.7 KiB
Go
469 lines
9.7 KiB
Go
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": "",
|
||
})
|
||
}
|