Bind the linuxdo trust_level to the user group.

This commit is contained in:
icpd 2024-03-16 04:39:40 +08:00
parent 9adefa80b9
commit 1802953e68
6 changed files with 123 additions and 61 deletions

View File

@ -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 {

17
common/linuxdo-group.go Normal file
View File

@ -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)
}

View File

@ -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 {

View File

@ -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)
userHandler = newUserHandler{c, linuxDoUser}
}
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
}
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{

View File

@ -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"` // 邀请剩余额度

View File

@ -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 <Tag size='large' color='yellow'>{group}</Tag>;
} else if (group === 'svip' || group === 'premium') {
} else if (group === 'level2' || group === 'level1') {
return <Tag size='large' color='red'>{group}</Tag>;
}
if (group === 'default') {
if (group === 'level0') {
return <Tag size='large'>{group}</Tag>;
} else {
return <Tag size='large' color={stringToColor(group)}>{group}</Tag>;