From fc33f2f0a53398a568f6d3d13131afeca1f1dea5 Mon Sep 17 00:00:00 2001 From: mango Date: Tue, 7 Jan 2025 12:15:55 +0800 Subject: [PATCH 1/3] feat(channel balance): add channel balance for siliconflow and deepseek --- controller/channel-billing.go | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/controller/channel-billing.go b/controller/channel-billing.go index 96f82ee3..41f8d8f7 100644 --- a/controller/channel-billing.go +++ b/controller/channel-billing.go @@ -78,6 +78,36 @@ type APGC2DGPTUsageResponse struct { TotalUsed float64 `json:"total_used"` } +type SiliconFlowUsageResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Status bool `json:"status"` + Data struct { + ID string `json:"id"` + Name string `json:"name"` + Image string `json:"image"` + Email string `json:"email"` + IsAdmin bool `json:"isAdmin"` + Balance string `json:"balance"` + Status string `json:"status"` + Introduction string `json:"introduction"` + Role string `json:"role"` + ChargeBalance string `json:"chargeBalance"` + TotalBalance string `json:"totalBalance"` + Category string `json:"category"` + } `json:"data"` +} + +type DeepSeekUsageResponse struct { + IsAvailable bool `json:"is_available"` + BalanceInfos []struct { + Currency string `json:"currency"` + TotalBalance string `json:"total_balance"` + GrantedBalance string `json:"granted_balance"` + ToppedUpBalance string `json:"topped_up_balance"` + } `json:"balance_infos"` +} + // GetAuthHeader get auth header func GetAuthHeader(token string) http.Header { h := http.Header{} @@ -185,6 +215,57 @@ func updateChannelAPI2GPTBalance(channel *model.Channel) (float64, error) { return response.TotalRemaining, nil } +func updateChannelSiliconFlowBalance(channel *model.Channel) (float64, error) { + url := "https://api.siliconflow.cn/v1/user/info" + body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key)) + if err != nil { + return 0, err + } + response := SiliconFlowUsageResponse{} + err = json.Unmarshal(body, &response) + if err != nil { + return 0, err + } + if response.Code != 20000 { + return 0, fmt.Errorf("code: %d, message: %s", response.Code, response.Message) + } + balance, err := strconv.ParseFloat(response.Data.TotalBalance, 64) + if err != nil { + return 0, err + } + channel.UpdateBalance(balance) + return balance, nil +} + +func updateChannelDeepSeekBalance(channel *model.Channel) (float64, error) { + url := "https://api.deepseek.com/user/balance" + body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key)) + if err != nil { + return 0, err + } + response := DeepSeekUsageResponse{} + err = json.Unmarshal(body, &response) + if err != nil { + return 0, err + } + index := -1 + for i, balanceInfo := range response.BalanceInfos { + if balanceInfo.Currency == "CNY" { + index = i + break + } + } + if index == -1 { + return 0, errors.New("currency CNY not found") + } + balance, err := strconv.ParseFloat(response.BalanceInfos[index].TotalBalance, 64) + if err != nil { + return 0, err + } + channel.UpdateBalance(balance) + return balance, nil +} + func updateChannelAIGC2DBalance(channel *model.Channel) (float64, error) { url := "https://api.aigc2d.com/dashboard/billing/credit_grants" body, err := GetResponseBody("GET", url, channel, GetAuthHeader(channel.Key)) @@ -222,6 +303,10 @@ func updateChannelBalance(channel *model.Channel) (float64, error) { return updateChannelAPI2GPTBalance(channel) case common.ChannelTypeAIGC2D: return updateChannelAIGC2DBalance(channel) + case common.ChannelTypeSiliconFlow: + return updateChannelSiliconFlowBalance(channel) + case common.ChannelTypeDeepSeek: + return updateChannelDeepSeekBalance(channel) default: return 0, errors.New("尚未实现") } @@ -300,9 +385,9 @@ func updateAllChannelsBalance() error { continue } // TODO: support Azure - if channel.Type != common.ChannelTypeOpenAI && channel.Type != common.ChannelTypeCustom { - continue - } + //if channel.Type != common.ChannelTypeOpenAI && channel.Type != common.ChannelTypeCustom { + // continue + //} balance, err := updateChannelBalance(channel) if err != nil { continue From f5be2868df041c1cea6587714924fbfca5fa5a07 Mon Sep 17 00:00:00 2001 From: mango Date: Tue, 7 Jan 2025 12:40:36 +0800 Subject: [PATCH 2/3] feat(channel model list): modify fetching model list in add channel to fetch by type --- controller/channel.go | 3 ++- web/src/pages/Channel/EditChannel.js | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/controller/channel.go b/controller/channel.go index b1fdd0c3..62f5bc69 100644 --- a/controller/channel.go +++ b/controller/channel.go @@ -510,6 +510,7 @@ func UpdateChannel(c *gin.Context) { func FetchModels(c *gin.Context) { var req struct { BaseURL string `json:"base_url"` + Type int `json:"type"` Key string `json:"key"` } @@ -523,7 +524,7 @@ func FetchModels(c *gin.Context) { baseURL := req.BaseURL if baseURL == "" { - baseURL = "https://api.openai.com" + baseURL = common.ChannelBaseURLs[req.Type] } client := &http.Client{} diff --git a/web/src/pages/Channel/EditChannel.js b/web/src/pages/Channel/EditChannel.js index 457dff42..6f576344 100644 --- a/web/src/pages/Channel/EditChannel.js +++ b/web/src/pages/Channel/EditChannel.js @@ -218,6 +218,7 @@ const EditChannel = (props) => { try { const res = await API.post('/api/channel/fetch_models', { base_url: inputs['base_url'], + type: inputs['type'], key: inputs['key'] }); @@ -885,7 +886,7 @@ const EditChannel = (props) => {