diff --git a/app/src/components/admin/ChargeWidget.tsx b/app/src/components/admin/ChargeWidget.tsx
index 1124a8b..3927412 100644
--- a/app/src/components/admin/ChargeWidget.tsx
+++ b/app/src/components/admin/ChargeWidget.tsx
@@ -18,6 +18,7 @@ import {
Eraser,
EyeOff,
Minus,
+ PencilLine,
Plus,
RotateCw,
Search,
@@ -350,8 +351,17 @@ function ChargeEditor({
onClick={post}
className={`whitespace-nowrap shrink-0`}
>
-
- {t("admin.charge.add-rule")}
+ {form.id === -1 ? (
+ <>
+
+ {t("admin.charge.add-rule")}
+ >
+ ) : (
+ <>
+
+ {t("admin.charge.update-rule")}
+ >
+ )}
diff --git a/app/src/components/admin/assemblies/ChannelEditor.tsx b/app/src/components/admin/assemblies/ChannelEditor.tsx
index 1f38026..8f07afb 100644
--- a/app/src/components/admin/assemblies/ChannelEditor.tsx
+++ b/app/src/components/admin/assemblies/ChannelEditor.tsx
@@ -21,7 +21,7 @@ import { Button } from "@/components/ui/button.tsx";
import { useTranslation } from "react-i18next";
import { useMemo, useReducer, useState } from "react";
import Required from "@/components/Require.tsx";
-import { X } from "lucide-react";
+import { Search, X } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
@@ -285,7 +285,10 @@ function ChannelEditor({ display, id, setEnabled }: ChannelEditorProps) {
-
+
diff --git a/app/src/conf.ts b/app/src/conf.ts
index 235677e..19900a6 100644
--- a/app/src/conf.ts
+++ b/app/src/conf.ts
@@ -365,10 +365,7 @@ export const planModels: PlanModel[] = [
{ id: "midjourney-fast", level: 2 },
];
-export const expensiveModels = [
- "midjourney-turbo",
- "gpt-4-32k-0613",
-];
+export const expensiveModels = ["midjourney-turbo", "gpt-4-32k-0613"];
export const modelAvatars: Record = {
"gpt-3.5-turbo-0613": "gpt35turbo.png",
diff --git a/app/src/i18n.ts b/app/src/i18n.ts
index 6adcde6..27b0850 100644
--- a/app/src/i18n.ts
+++ b/app/src/i18n.ts
@@ -420,6 +420,7 @@ const resources = {
"input-count": "输入点数",
"output-count": "输出点数",
"add-rule": "添加规则",
+ "update-rule": "更新规则",
},
},
mask: {
@@ -843,6 +844,25 @@ const resources = {
"add-model": "Add Model",
"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: {
title: "Mask Settings",
@@ -1268,6 +1288,25 @@ const resources = {
"add-model": "Добавить модель",
"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: {
title: "Настройки маски",
diff --git a/utils/net.go b/utils/net.go
index e5da6ff..9418b18 100644
--- a/utils/net.go
+++ b/utils/net.go
@@ -2,6 +2,7 @@ package utils
import (
"bytes"
+ "chat/globals"
"crypto/tls"
"fmt"
"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 {
+ // 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}
client := &http.Client{}
@@ -120,11 +128,13 @@ func EventSource(method string, uri string, headers map[string]string, body inte
if err != nil {
return err
}
+
+ defer res.Body.Close()
+
if res.StatusCode >= 400 {
return fmt.Errorf("request failed with status: %s", res.Status)
}
- defer res.Body.Close()
for {
buf := make([]byte, 20480)
n, err := res.Body.Read(buf)