mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-29 22:56:39 +08:00
* ♻️ refactor: move file directory * ♻️ refactor: move file directory * ♻️ refactor: support multiple config methods * 🔥 del: remove unused code * 💩 refactor: Refactor channel management and synchronization * 💄 improve: add channel website * ✨ feat: allow recording 0 consumption
216 lines
8.2 KiB
Go
216 lines
8.2 KiB
Go
package model
|
|
|
|
import (
|
|
"one-api/common"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Option struct {
|
|
Key string `json:"key" gorm:"primaryKey"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
func AllOption() ([]*Option, error) {
|
|
var options []*Option
|
|
var err error
|
|
err = DB.Find(&options).Error
|
|
return options, err
|
|
}
|
|
|
|
func GetOption(key string) (option Option, err error) {
|
|
err = DB.First(&option, Option{Key: key}).Error
|
|
return
|
|
}
|
|
|
|
func InitOptionMap() {
|
|
common.OptionMapRWMutex.Lock()
|
|
common.OptionMap = make(map[string]string)
|
|
common.OptionMap["PasswordLoginEnabled"] = strconv.FormatBool(common.PasswordLoginEnabled)
|
|
common.OptionMap["PasswordRegisterEnabled"] = strconv.FormatBool(common.PasswordRegisterEnabled)
|
|
common.OptionMap["EmailVerificationEnabled"] = strconv.FormatBool(common.EmailVerificationEnabled)
|
|
common.OptionMap["GitHubOAuthEnabled"] = strconv.FormatBool(common.GitHubOAuthEnabled)
|
|
common.OptionMap["WeChatAuthEnabled"] = strconv.FormatBool(common.WeChatAuthEnabled)
|
|
common.OptionMap["TurnstileCheckEnabled"] = strconv.FormatBool(common.TurnstileCheckEnabled)
|
|
common.OptionMap["RegisterEnabled"] = strconv.FormatBool(common.RegisterEnabled)
|
|
common.OptionMap["AutomaticDisableChannelEnabled"] = strconv.FormatBool(common.AutomaticDisableChannelEnabled)
|
|
common.OptionMap["AutomaticEnableChannelEnabled"] = strconv.FormatBool(common.AutomaticEnableChannelEnabled)
|
|
common.OptionMap["ApproximateTokenEnabled"] = strconv.FormatBool(common.ApproximateTokenEnabled)
|
|
common.OptionMap["LogConsumeEnabled"] = strconv.FormatBool(common.LogConsumeEnabled)
|
|
common.OptionMap["DisplayInCurrencyEnabled"] = strconv.FormatBool(common.DisplayInCurrencyEnabled)
|
|
common.OptionMap["DisplayTokenStatEnabled"] = strconv.FormatBool(common.DisplayTokenStatEnabled)
|
|
common.OptionMap["ChannelDisableThreshold"] = strconv.FormatFloat(common.ChannelDisableThreshold, 'f', -1, 64)
|
|
common.OptionMap["EmailDomainRestrictionEnabled"] = strconv.FormatBool(common.EmailDomainRestrictionEnabled)
|
|
common.OptionMap["EmailDomainWhitelist"] = strings.Join(common.EmailDomainWhitelist, ",")
|
|
common.OptionMap["SMTPServer"] = ""
|
|
common.OptionMap["SMTPFrom"] = ""
|
|
common.OptionMap["SMTPPort"] = strconv.Itoa(common.SMTPPort)
|
|
common.OptionMap["SMTPAccount"] = ""
|
|
common.OptionMap["SMTPToken"] = ""
|
|
common.OptionMap["Notice"] = ""
|
|
common.OptionMap["About"] = ""
|
|
common.OptionMap["HomePageContent"] = ""
|
|
common.OptionMap["Footer"] = common.Footer
|
|
common.OptionMap["SystemName"] = common.SystemName
|
|
common.OptionMap["Logo"] = common.Logo
|
|
common.OptionMap["ServerAddress"] = ""
|
|
common.OptionMap["GitHubClientId"] = ""
|
|
common.OptionMap["GitHubClientSecret"] = ""
|
|
common.OptionMap["WeChatServerAddress"] = ""
|
|
common.OptionMap["WeChatServerToken"] = ""
|
|
common.OptionMap["WeChatAccountQRCodeImageURL"] = ""
|
|
common.OptionMap["TurnstileSiteKey"] = ""
|
|
common.OptionMap["TurnstileSecretKey"] = ""
|
|
common.OptionMap["QuotaForNewUser"] = strconv.Itoa(common.QuotaForNewUser)
|
|
common.OptionMap["QuotaForInviter"] = strconv.Itoa(common.QuotaForInviter)
|
|
common.OptionMap["QuotaForInvitee"] = strconv.Itoa(common.QuotaForInvitee)
|
|
common.OptionMap["QuotaRemindThreshold"] = strconv.Itoa(common.QuotaRemindThreshold)
|
|
common.OptionMap["PreConsumedQuota"] = strconv.Itoa(common.PreConsumedQuota)
|
|
common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString()
|
|
common.OptionMap["GroupRatio"] = common.GroupRatio2JSONString()
|
|
common.OptionMap["TopUpLink"] = common.TopUpLink
|
|
common.OptionMap["ChatLink"] = common.ChatLink
|
|
common.OptionMap["QuotaPerUnit"] = strconv.FormatFloat(common.QuotaPerUnit, 'f', -1, 64)
|
|
common.OptionMap["RetryTimes"] = strconv.Itoa(common.RetryTimes)
|
|
common.OptionMap["RetryCooldownSeconds"] = strconv.Itoa(common.RetryCooldownSeconds)
|
|
|
|
common.OptionMapRWMutex.Unlock()
|
|
initModelRatio()
|
|
loadOptionsFromDatabase()
|
|
}
|
|
|
|
func initModelRatio() {
|
|
// 查询数据库中的ModelRatio
|
|
option, err := GetOption("ModelRatio")
|
|
if err != nil || option.Value == "" {
|
|
return
|
|
}
|
|
|
|
newModelRatio, err := common.MergeModelRatioByJSONString(option.Value)
|
|
if err != nil || newModelRatio == "" {
|
|
return
|
|
}
|
|
|
|
// 更新数据库中的ModelRatio
|
|
common.SysLog("update ModelRatio")
|
|
UpdateOption("ModelRatio", newModelRatio)
|
|
|
|
}
|
|
|
|
func loadOptionsFromDatabase() {
|
|
options, _ := AllOption()
|
|
for _, option := range options {
|
|
err := updateOptionMap(option.Key, option.Value)
|
|
if err != nil {
|
|
common.SysError("failed to update option map: " + err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
func SyncOptions(frequency int) {
|
|
for {
|
|
time.Sleep(time.Duration(frequency) * time.Second)
|
|
common.SysLog("syncing options from database")
|
|
loadOptionsFromDatabase()
|
|
}
|
|
}
|
|
|
|
func UpdateOption(key string, value string) error {
|
|
// Save to database first
|
|
option := Option{
|
|
Key: key,
|
|
}
|
|
// https://gorm.io/docs/update.html#Save-All-Fields
|
|
DB.FirstOrCreate(&option, Option{Key: key})
|
|
option.Value = value
|
|
// Save is a combination function.
|
|
// If save value does not contain primary key, it will execute Create,
|
|
// otherwise it will execute Update (with all fields).
|
|
DB.Save(&option)
|
|
// Update OptionMap
|
|
return updateOptionMap(key, value)
|
|
}
|
|
|
|
var optionIntMap = map[string]*int{
|
|
"SMTPPort": &common.SMTPPort,
|
|
"QuotaForNewUser": &common.QuotaForNewUser,
|
|
"QuotaForInviter": &common.QuotaForInviter,
|
|
"QuotaForInvitee": &common.QuotaForInvitee,
|
|
"QuotaRemindThreshold": &common.QuotaRemindThreshold,
|
|
"PreConsumedQuota": &common.PreConsumedQuota,
|
|
"RetryTimes": &common.RetryTimes,
|
|
"RetryCooldownSeconds": &common.RetryCooldownSeconds,
|
|
}
|
|
|
|
var optionBoolMap = map[string]*bool{
|
|
"PasswordRegisterEnabled": &common.PasswordRegisterEnabled,
|
|
"PasswordLoginEnabled": &common.PasswordLoginEnabled,
|
|
"EmailVerificationEnabled": &common.EmailVerificationEnabled,
|
|
"GitHubOAuthEnabled": &common.GitHubOAuthEnabled,
|
|
"WeChatAuthEnabled": &common.WeChatAuthEnabled,
|
|
"TurnstileCheckEnabled": &common.TurnstileCheckEnabled,
|
|
"RegisterEnabled": &common.RegisterEnabled,
|
|
"EmailDomainRestrictionEnabled": &common.EmailDomainRestrictionEnabled,
|
|
"AutomaticDisableChannelEnabled": &common.AutomaticDisableChannelEnabled,
|
|
"AutomaticEnableChannelEnabled": &common.AutomaticEnableChannelEnabled,
|
|
"ApproximateTokenEnabled": &common.ApproximateTokenEnabled,
|
|
"LogConsumeEnabled": &common.LogConsumeEnabled,
|
|
"DisplayInCurrencyEnabled": &common.DisplayInCurrencyEnabled,
|
|
"DisplayTokenStatEnabled": &common.DisplayTokenStatEnabled,
|
|
}
|
|
|
|
var optionStringMap = map[string]*string{
|
|
"SMTPServer": &common.SMTPServer,
|
|
"SMTPAccount": &common.SMTPAccount,
|
|
"SMTPFrom": &common.SMTPFrom,
|
|
"SMTPToken": &common.SMTPToken,
|
|
"ServerAddress": &common.ServerAddress,
|
|
"GitHubClientId": &common.GitHubClientId,
|
|
"GitHubClientSecret": &common.GitHubClientSecret,
|
|
"Footer": &common.Footer,
|
|
"SystemName": &common.SystemName,
|
|
"Logo": &common.Logo,
|
|
"WeChatServerAddress": &common.WeChatServerAddress,
|
|
"WeChatServerToken": &common.WeChatServerToken,
|
|
"WeChatAccountQRCodeImageURL": &common.WeChatAccountQRCodeImageURL,
|
|
"TurnstileSiteKey": &common.TurnstileSiteKey,
|
|
"TurnstileSecretKey": &common.TurnstileSecretKey,
|
|
"TopUpLink": &common.TopUpLink,
|
|
"ChatLink": &common.ChatLink,
|
|
}
|
|
|
|
func updateOptionMap(key string, value string) (err error) {
|
|
common.OptionMapRWMutex.Lock()
|
|
defer common.OptionMapRWMutex.Unlock()
|
|
common.OptionMap[key] = value
|
|
if ptr, ok := optionIntMap[key]; ok {
|
|
*ptr, _ = strconv.Atoi(value)
|
|
return
|
|
}
|
|
|
|
if ptr, ok := optionBoolMap[key]; ok {
|
|
*ptr = value == "true"
|
|
return
|
|
}
|
|
|
|
if ptr, ok := optionStringMap[key]; ok {
|
|
*ptr = value
|
|
return
|
|
}
|
|
|
|
switch key {
|
|
case "EmailDomainWhitelist":
|
|
common.EmailDomainWhitelist = strings.Split(value, ",")
|
|
case "ModelRatio":
|
|
err = common.UpdateModelRatioByJSONString(value)
|
|
case "GroupRatio":
|
|
err = common.UpdateGroupRatioByJSONString(value)
|
|
case "ChannelDisableThreshold":
|
|
common.ChannelDisableThreshold, _ = strconv.ParseFloat(value, 64)
|
|
case "QuotaPerUnit":
|
|
common.QuotaPerUnit, _ = strconv.ParseFloat(value, 64)
|
|
}
|
|
return err
|
|
}
|