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