diff --git a/constant/system.go b/constant/system-setting.go similarity index 100% rename from constant/system.go rename to constant/system-setting.go diff --git a/model/channel.go b/model/channel.go index 5b35851..7c46f59 100644 --- a/model/channel.go +++ b/model/channel.go @@ -1,6 +1,7 @@ package model import ( + "encoding/json" "gorm.io/gorm" "one-api/common" ) @@ -29,6 +30,31 @@ type Channel struct { StatusCodeMapping *string `json:"status_code_mapping" gorm:"type:varchar(1024);default:''"` Priority *int64 `json:"priority" gorm:"bigint;default:0"` AutoBan *int `json:"auto_ban" gorm:"default:1"` + OtherInfo string `json:"other_info"` +} + +func (channel *Channel) GetOtherInfo() map[string]interface{} { + var otherInfo map[string]interface{} + if channel.OtherInfo != "" { + err := json.Unmarshal([]byte(channel.OtherInfo), &otherInfo) + if err != nil { + common.SysError("failed to unmarshal other info: " + err.Error()) + } + } + return otherInfo +} + +func (channel *Channel) SetOtherInfo(otherInfo map[string]interface{}) { + otherInfoBytes, err := json.Marshal(otherInfo) + if err != nil { + common.SysError("failed to marshal other info: " + err.Error()) + return + } + channel.OtherInfo = string(otherInfoBytes) +} + +func (channel *Channel) Save() error { + return DB.Save(channel).Error } func GetAllChannels(startIdx int, num int, selectAll bool, idSort bool) ([]*Channel, error) { @@ -213,15 +239,30 @@ func (channel *Channel) Delete() error { return err } -func UpdateChannelStatusById(id int, status int) { +func UpdateChannelStatusById(id int, status int, reason string) { err := UpdateAbilityStatus(id, status == common.ChannelStatusEnabled) if err != nil { common.SysError("failed to update ability status: " + err.Error()) } - err = DB.Model(&Channel{}).Where("id = ?", id).Update("status", status).Error + channel, err := GetChannelById(id, true) if err != nil { - common.SysError("failed to update channel status: " + err.Error()) + // find channel by id error, directly update status + err = DB.Model(&Channel{}).Where("id = ?", id).Update("status", status).Error + if err != nil { + common.SysError("failed to update channel status: " + err.Error()) + } + } else { + // find channel by id success, update status and other info + info := channel.GetOtherInfo() + info["status_reason"] = reason + channel.SetOtherInfo(info) + channel.Status = status + err = channel.Save() + if err != nil { + common.SysError("failed to update channel status: " + err.Error()) + } } + } func UpdateChannelUsedQuota(id int, quota int) { diff --git a/service/channel.go b/service/channel.go index 41ca6b7..69a7d3a 100644 --- a/service/channel.go +++ b/service/channel.go @@ -11,14 +11,14 @@ import ( // disable & notify func DisableChannel(channelId int, channelName string, reason string) { - model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled) + model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled, reason) subject := fmt.Sprintf("通道「%s」(#%d)已被禁用", channelName, channelId) content := fmt.Sprintf("通道「%s」(#%d)已被禁用,原因:%s", channelName, channelId, reason) notifyRootUser(subject, content) } func EnableChannel(channelId int, channelName string) { - model.UpdateChannelStatusById(channelId, common.ChannelStatusEnabled) + model.UpdateChannelStatusById(channelId, common.ChannelStatusEnabled, "") subject := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) content := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) notifyRootUser(subject, content) diff --git a/web/src/components/TokensTable.js b/web/src/components/TokensTable.js index 015a5d2..6dbb31b 100644 --- a/web/src/components/TokensTable.js +++ b/web/src/components/TokensTable.js @@ -225,6 +225,14 @@ const TokensTable = () => { onOpenLink('next-mj', record.key); }, }, + { + node: 'item', + key: 'lobe', + name: 'Lobe Chat', + onClick: () => { + onOpenLink('lobe', record.key); + }, + }, { node: 'item', key: 'ama', @@ -377,51 +385,6 @@ const TokensTable = () => { await loadTokens(activePage - 1); }; - const onCopy = async (type, key) => { - let status = localStorage.getItem('status'); - let serverAddress = ''; - if (status) { - status = JSON.parse(status); - serverAddress = status.server_address; - } - if (serverAddress === '') { - serverAddress = window.location.origin; - } - let encodedServerAddress = encodeURIComponent(serverAddress); - const nextLink = localStorage.getItem('chat_link'); - const mjLink = localStorage.getItem('chat_link2'); - let nextUrl; - - if (nextLink) { - nextUrl = - nextLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`; - } else { - nextUrl = `https://chat.oneapi.pro/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`; - } - - let url; - switch (type) { - case 'ama': - url = - mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`; - break; - case 'opencat': - url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`; - break; - case 'next': - url = nextUrl; - break; - default: - url = `sk-${key}`; - } - // if (await copy(url)) { - // showSuccess('已复制到剪贴板!'); - // } else { - // showWarning('无法复制到剪贴板,请手动复制,已将令牌填入搜索框。'); - // setSearchKeyword(url); - // } - }; - const copyText = async (text) => { if (await copy(text)) { showSuccess('已复制到剪贴板!'); @@ -461,6 +424,9 @@ const TokensTable = () => { case 'opencat': url = `opencat://team/join?domain=${encodedServerAddress}&token=sk-${key}`; break; + case 'lobe': + url = `https://chat-preview.lobehub.com/?settings={"keyVaults":{"openai":{"apiKey":"sk-${key}","baseURL":"${encodedServerAddress}"}}}`; + break; case 'next-mj': url = mjLink + `/#/?settings={"key":"sk-${key}","url":"${serverAddress}"}`;