update: charge icons and add event source panic recover

This commit is contained in:
Zhang Minghan 2023-12-12 13:48:32 +08:00
parent 8b3041ded1
commit 208e18c2bf
5 changed files with 68 additions and 9 deletions

View File

@ -18,6 +18,7 @@ import {
Eraser, Eraser,
EyeOff, EyeOff,
Minus, Minus,
PencilLine,
Plus, Plus,
RotateCw, RotateCw,
Search, Search,
@ -350,8 +351,17 @@ function ChargeEditor({
onClick={post} onClick={post}
className={`whitespace-nowrap shrink-0`} className={`whitespace-nowrap shrink-0`}
> >
{form.id === -1 ? (
<>
<Plus className={`w-4 h-4 mr-2`} /> <Plus className={`w-4 h-4 mr-2`} />
{t("admin.charge.add-rule")} {t("admin.charge.add-rule")}
</>
) : (
<>
<PencilLine className={`w-4 h-4 mr-2`} />
{t("admin.charge.update-rule")}
</>
)}
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -21,7 +21,7 @@ import { Button } from "@/components/ui/button.tsx";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useMemo, useReducer, useState } from "react"; import { useMemo, useReducer, useState } from "react";
import Required from "@/components/Require.tsx"; import Required from "@/components/Require.tsx";
import { X } from "lucide-react"; import { Search, X } from "lucide-react";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -285,7 +285,10 @@ function ChannelEditor({ display, id, setEnabled }: ChannelEditorProps) {
<div className={`channel-model-action mt-4`}> <div className={`channel-model-action mt-4`}>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button>{t("admin.channels.add-model")}</Button> <Button>
<Search className={`h-4 w-4 mr-2`} />
{t("admin.channels.add-model")}
</Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align={`start`} asChild> <DropdownMenuContent align={`start`} asChild>
<Command> <Command>

View File

@ -365,10 +365,7 @@ export const planModels: PlanModel[] = [
{ id: "midjourney-fast", level: 2 }, { id: "midjourney-fast", level: 2 },
]; ];
export const expensiveModels = [ export const expensiveModels = ["midjourney-turbo", "gpt-4-32k-0613"];
"midjourney-turbo",
"gpt-4-32k-0613",
];
export const modelAvatars: Record<string, string> = { export const modelAvatars: Record<string, string> = {
"gpt-3.5-turbo-0613": "gpt35turbo.png", "gpt-3.5-turbo-0613": "gpt35turbo.png",

View File

@ -420,6 +420,7 @@ const resources = {
"input-count": "输入点数", "input-count": "输入点数",
"output-count": "输出点数", "output-count": "输出点数",
"add-rule": "添加规则", "add-rule": "添加规则",
"update-rule": "更新规则",
}, },
}, },
mask: { mask: {
@ -843,6 +844,25 @@ const resources = {
"add-model": "Add Model", "add-model": "Add Model",
"clear-models": "Clear All Models", "clear-models": "Clear All Models",
}, },
charge: {
id: "ID",
type: "Type",
model: "Model",
quota: "Quota",
action: "Action",
input: "Input",
output: "Output",
"support-anonymous": "Support Anonymous",
"non-billing": "Non Billing",
"times-billing": "Times Billing",
"token-billing": "Token Billing",
anonymous: "Support Anonymous Call",
"time-count": "Single Request Quota",
"input-count": "Input Quota",
"output-count": "Output Quota",
"add-rule": "Add Rule",
"update-rule": "Update Rule",
},
}, },
mask: { mask: {
title: "Mask Settings", title: "Mask Settings",
@ -1268,6 +1288,25 @@ const resources = {
"add-model": "Добавить модель", "add-model": "Добавить модель",
"clear-models": "Очистить все модели", "clear-models": "Очистить все модели",
}, },
charge: {
id: "ID",
type: "Тип",
model: "Модель",
quota: "Квота",
action: "Действие",
input: "Вход",
output: "Выход",
"support-anonymous": "Поддержка анонимных вызовов",
"non-billing": "Не тарифицируется",
"times-billing": "Тарификация по времени",
"token-billing": "Тарификация по токену",
anonymous: "Поддержка анонимных вызовов",
"time-count": "Квота одного запроса",
"input-count": "Квота входа",
"output-count": "Квота выхода",
"add-rule": "Добавить правило",
"update-rule": "Обновить правило",
},
}, },
mask: { mask: {
title: "Настройки маски", title: "Настройки маски",

View File

@ -2,6 +2,7 @@ package utils
import ( import (
"bytes" "bytes"
"chat/globals"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/goccy/go-json" "github.com/goccy/go-json"
@ -105,6 +106,13 @@ func PostForm(uri string, body map[string]interface{}) (data map[string]interfac
} }
func EventSource(method string, uri string, headers map[string]string, body interface{}, callback func(string) error) error { func EventSource(method string, uri string, headers map[string]string, body interface{}, callback func(string) error) error {
// panic recovery
defer func() {
if err := recover(); err != nil {
globals.Warn(fmt.Sprintf("event source panic: %s (uri: %s, method: %s)", err, uri, method))
}
}()
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{} client := &http.Client{}
@ -120,11 +128,13 @@ func EventSource(method string, uri string, headers map[string]string, body inte
if err != nil { if err != nil {
return err return err
} }
defer res.Body.Close()
if res.StatusCode >= 400 { if res.StatusCode >= 400 {
return fmt.Errorf("request failed with status: %s", res.Status) return fmt.Errorf("request failed with status: %s", res.Status)
} }
defer res.Body.Close()
for { for {
buf := make([]byte, 20480) buf := make([]byte, 20480)
n, err := res.Body.Read(buf) n, err := res.Body.Read(buf)