diff --git a/common/group-ratio.go b/common/group-ratio.go index 1ec73c780..015df8768 100644 --- a/common/group-ratio.go +++ b/common/group-ratio.go @@ -3,9 +3,11 @@ package common import "encoding/json" var GroupRatio = map[string]float64{ - "default": 1, - "vip": 1, - "svip": 1, + LinuxDoTrustLevel0: 1, + LinuxDoTrustLevel1: 1, + LinuxDoTrustLevel2: 1, + LinuxDoTrustLevel3: 1, + LinuxDoTrustLevel4: 1, } func GroupRatio2JSONString() string { diff --git a/common/linuxdo-group.go b/common/linuxdo-group.go new file mode 100644 index 000000000..f1a03cc7b --- /dev/null +++ b/common/linuxdo-group.go @@ -0,0 +1,17 @@ +package common + +import "fmt" + +const ( + LinuxDoTrustLevel0 = "Level0" + LinuxDoTrustLevel1 = "level1" + LinuxDoTrustLevel2 = "level2" + LinuxDoTrustLevel3 = "level3" + LinuxDoTrustLevel4 = "level4" +) + +type TrustLevel int + +func (l TrustLevel) String() string { + return fmt.Sprintf("level%d", l) +} diff --git a/common/topup-ratio.go b/common/topup-ratio.go index e045d9b75..df7b73253 100644 --- a/common/topup-ratio.go +++ b/common/topup-ratio.go @@ -3,9 +3,11 @@ package common import "encoding/json" var TopupGroupRatio = map[string]float64{ - "default": 1, - "vip": 1, - "svip": 1, + LinuxDoTrustLevel0: 1, + LinuxDoTrustLevel1: 1, + LinuxDoTrustLevel2: 1, + LinuxDoTrustLevel3: 1, + LinuxDoTrustLevel4: 1, } func TopupGroupRatio2JSONString() string { diff --git a/controller/linuxdo.go b/controller/linuxdo.go index de4c982d6..b7d8fbf74 100644 --- a/controller/linuxdo.go +++ b/controller/linuxdo.go @@ -6,14 +6,16 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gin-contrib/sessions" - "github.com/gin-gonic/gin" "net/http" "net/url" - "one-api/common" - "one-api/model" "strconv" "time" + + "one-api/common" + "one-api/model" + + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" ) type LinuxDoOAuthResponse struct { @@ -23,12 +25,73 @@ type LinuxDoOAuthResponse struct { } type LinuxDoUser struct { - ID int `json:"id"` - Username string `json:"username"` - Name string `json:"name"` - Active bool `json:"active"` - TrustLevel int `json:"trust_level"` - Silenced bool `json:"silenced"` + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + Active bool `json:"active"` + TrustLevel common.TrustLevel `json:"trust_level"` + Silenced bool `json:"silenced"` +} + +type UserHandler interface { + Do() (*model.User, error) +} + +type existingUserHandler struct { + *LinuxDoUser +} + +func (h existingUserHandler) Do() (*model.User, error) { + user := &model.User{ + LinuxDoId: strconv.Itoa(h.ID), + } + + err := user.FillUserByLinuxDoId() + if err != nil { + return nil, err + } + + trustLevelStr := h.TrustLevel.String() + if user.Group != trustLevelStr { + user.Group = trustLevelStr + err = user.Update(false) + if err != nil { + return nil, fmt.Errorf("更新用户组失败: %w", err) + } + } + + return user, err +} + +type newUserHandler struct { + ginCtx *gin.Context + linuxDoUser *LinuxDoUser +} + +func (h newUserHandler) Do() (*model.User, error) { + if !common.RegisterEnabled { + return nil, errors.New("管理员关闭了新用户注册") + } + + affCode := h.ginCtx.Query("aff") + + user := new(model.User) + user.LinuxDoId = strconv.Itoa(h.linuxDoUser.ID) + user.InviterId, _ = model.GetUserIdByAffCode(affCode) + user.Username = "linuxdo_" + strconv.Itoa(model.GetMaxUserId()+1) + if h.linuxDoUser.Name != "" { + user.DisplayName = h.linuxDoUser.Name + } else { + user.DisplayName = h.linuxDoUser.Username + } + user.Role = common.RoleCommonUser + user.Status = common.UserStatusEnabled + user.Group = h.linuxDoUser.TrustLevel.String() + if err := user.Insert(user.InviterId); err != nil { + return nil, fmt.Errorf("创建用户失败: %w", err) + } + + return user, nil } func getLinuxDoUserInfoByCode(code string) (*LinuxDoUser, error) { @@ -107,7 +170,7 @@ func LinuxDoOAuth(c *gin.Context) { return } code := c.Query("code") - linuxdoUser, err := getLinuxDoUserInfoByCode(code) + linuxDoUser, err := getLinuxDoUserInfoByCode(code) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, @@ -115,46 +178,21 @@ func LinuxDoOAuth(c *gin.Context) { }) return } - user := model.User{ - LinuxDoId: strconv.Itoa(linuxdoUser.ID), - } - if model.IsLinuxDoIdAlreadyTaken(user.LinuxDoId) { - err := user.FillUserByLinuxDoId() - if err != nil { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": err.Error(), - }) - return - } + + var userHandler UserHandler + if model.IsLinuxDoIdAlreadyTaken(strconv.Itoa(linuxDoUser.ID)) { + userHandler = existingUserHandler{linuxDoUser} } else { - if common.RegisterEnabled { - affCode := c.Query("aff") - user.InviterId, _ = model.GetUserIdByAffCode(affCode) - - user.Username = "linuxdo_" + strconv.Itoa(model.GetMaxUserId()+1) - if linuxdoUser.Name != "" { - user.DisplayName = linuxdoUser.Name - } else { - user.DisplayName = linuxdoUser.Username - } - user.Role = common.RoleCommonUser - user.Status = common.UserStatusEnabled - - if err := user.Insert(user.InviterId); err != nil { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": err.Error(), - }) - return - } - } else { - c.JSON(http.StatusOK, gin.H{ - "success": false, - "message": "管理员关闭了新用户注册", - }) - return - } + userHandler = newUserHandler{c, linuxDoUser} + } + + user, err := userHandler.Do() + if err != nil { + c.JSON(http.StatusOK, gin.H{ + "success": false, + "message": err.Error(), + }) + return } if user.Status != common.UserStatusEnabled { @@ -164,7 +202,8 @@ func LinuxDoOAuth(c *gin.Context) { }) return } - setupLogin(&user, c) + + setupLogin(user, c) } func LinuxDoBind(c *gin.Context) { @@ -207,6 +246,7 @@ func LinuxDoBind(c *gin.Context) { return } user.LinuxDoId = strconv.Itoa(linuxdoUser.ID) + user.Group = linuxdoUser.TrustLevel.String() err = user.Update(false) if err != nil { c.JSON(http.StatusOK, gin.H{ diff --git a/model/user.go b/model/user.go index 9c9d42e73..1abeb3c4f 100644 --- a/model/user.go +++ b/model/user.go @@ -3,10 +3,11 @@ package model import ( "errors" "fmt" - "one-api/common" "strings" "time" + "one-api/common" + "gorm.io/gorm" ) @@ -29,7 +30,7 @@ type User struct { Quota int `json:"quota" gorm:"type:int;default:0"` UsedQuota int `json:"used_quota" gorm:"type:int;default:0;column:used_quota"` // used quota RequestCount int `json:"request_count" gorm:"type:int;default:0;"` // request number - Group string `json:"group" gorm:"type:varchar(64);default:'default'"` + Group string `json:"group" gorm:"type:varchar(64);default:'level0'"` AffCode string `json:"aff_code" gorm:"type:varchar(32);column:aff_code;uniqueIndex"` AffCount int `json:"aff_count" gorm:"type:int;default:0;column:aff_count"` AffQuota int `json:"aff_quota" gorm:"type:int;default:0;column:aff_quota"` // 邀请剩余额度 diff --git a/web/src/helpers/render.js b/web/src/helpers/render.js index 62fb0dcde..cee91edb5 100644 --- a/web/src/helpers/render.js +++ b/web/src/helpers/render.js @@ -16,12 +16,12 @@ export function renderGroup(group) { groups.sort(); return <> {groups.map((group) => { - if (group === 'vip' || group === 'pro') { + if (group === 'level3' || group === 'level4') { return {group}; - } else if (group === 'svip' || group === 'premium') { + } else if (group === 'level2' || group === 'level1') { return {group}; } - if (group === 'default') { + if (group === 'level0') { return {group}; } else { return {group};