Просмотр исходного кода

feat: add support for updating balance of channel typpe OpenAI-SB (#146, close #125)

* Add support for updating channel balance in OpenAISB

* fix: handel error

---------

Co-authored-by: JustSong <songquanpeng@foxmail.com>
quzard 2 лет назад
Родитель
Сommit
47ca449e32
2 измененных файлов с 64 добавлено и 31 удалено
  1. 56 30
      controller/channel-billing.go
  2. 8 1
      web/src/components/ChannelsTable.js

+ 56 - 30
controller/channel-billing.go

@@ -37,6 +37,58 @@ type OpenAIUsageResponse struct {
 	TotalUsage float64 `json:"total_usage"` // unit: 0.01 dollar
 }
 
+type OpenAISBUsageResponse struct {
+	Msg  string `json:"msg"`
+	Data *struct {
+		Credit string `json:"credit"`
+	} `json:"data"`
+}
+
+func GetResponseBody(method, url string, channel *model.Channel) ([]byte, error) {
+	client := &http.Client{}
+	req, err := http.NewRequest(method, url, nil)
+	if err != nil {
+		return nil, err
+	}
+	auth := fmt.Sprintf("Bearer %s", channel.Key)
+	req.Header.Add("Authorization", auth)
+	res, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	body, err := io.ReadAll(res.Body)
+	if err != nil {
+		return nil, err
+	}
+	err = res.Body.Close()
+	if err != nil {
+		return nil, err
+	}
+	return body, nil
+}
+
+func updateChannelOpenAISBBalance(channel *model.Channel) (float64, error) {
+	url := fmt.Sprintf("https://api.openai-sb.com/sb-api/user/status?api_key=%s", channel.Key)
+	body, err := GetResponseBody("GET", url, channel)
+	if err != nil {
+		return 0, err
+	}
+	response := OpenAISBUsageResponse{}
+	err = json.Unmarshal(body, &response)
+	if err != nil {
+		return 0, err
+	}
+	if response.Data == nil {
+		return 0, errors.New(response.Msg)
+	}
+	balance, err := strconv.ParseFloat(response.Data.Credit, 64)
+	if err != nil {
+		return 0, err
+	}
+	channel.UpdateBalance(balance)
+	return balance, nil
+}
+
 func updateChannelBalance(channel *model.Channel) (float64, error) {
 	baseURL := common.ChannelBaseURLs[channel.Type]
 	switch channel.Type {
@@ -48,27 +100,14 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
 		return 0, errors.New("尚未实现")
 	case common.ChannelTypeCustom:
 		baseURL = channel.BaseURL
+	case common.ChannelTypeOpenAISB:
+		return updateChannelOpenAISBBalance(channel)
 	default:
 		return 0, errors.New("尚未实现")
 	}
 	url := fmt.Sprintf("%s/v1/dashboard/billing/subscription", baseURL)
 
-	client := &http.Client{}
-	req, err := http.NewRequest("GET", url, nil)
-	if err != nil {
-		return 0, err
-	}
-	auth := fmt.Sprintf("Bearer %s", channel.Key)
-	req.Header.Add("Authorization", auth)
-	res, err := client.Do(req)
-	if err != nil {
-		return 0, err
-	}
-	body, err := io.ReadAll(res.Body)
-	if err != nil {
-		return 0, err
-	}
-	err = res.Body.Close()
+	body, err := GetResponseBody("GET", url, channel)
 	if err != nil {
 		return 0, err
 	}
@@ -84,20 +123,7 @@ func updateChannelBalance(channel *model.Channel) (float64, error) {
 		startDate = now.AddDate(0, 0, -100).Format("2006-01-02")
 	}
 	url = fmt.Sprintf("%s/v1/dashboard/billing/usage?start_date=%s&end_date=%s", baseURL, startDate, endDate)
-	req, err = http.NewRequest("GET", url, nil)
-	if err != nil {
-		return 0, err
-	}
-	req.Header.Add("Authorization", auth)
-	res, err = client.Do(req)
-	if err != nil {
-		return 0, err
-	}
-	body, err = io.ReadAll(res.Body)
-	if err != nil {
-		return 0, err
-	}
-	err = res.Body.Close()
+	body, err = GetResponseBody("GET", url, channel)
 	if err != nil {
 		return 0, err
 	}

+ 8 - 1
web/src/components/ChannelsTable.js

@@ -27,6 +27,13 @@ function renderType(type) {
   return <Label basic color={type2label[type].color}>{type2label[type].text}</Label>;
 }
 
+function renderBalance(type, balance) {
+  if (type === 5) {
+    return <span>{balance.toFixed(2)}</span>
+  }
+  return <span>${balance.toFixed(2)}</span>
+}
+
 const ChannelsTable = () => {
   const [channels, setChannels] = useState([]);
   const [loading, setLoading] = useState(true);
@@ -336,7 +343,7 @@ const ChannelsTable = () => {
                     <Popup
                       content={channel.balance_updated_time ? renderTimestamp(channel.balance_updated_time) : '未更新'}
                       key={channel.id}
-                      trigger={<span>${channel.balance.toFixed(2)}</span>}
+                      trigger={renderBalance(channel.type, channel.balance)}
                       basic
                     />
                   </Table.Cell>