Commit fd943659 by CaIon

Merge remote-tracking branch 'origin/alpha' into alpha

parents bf30adcd 0d51f07d
...@@ -76,6 +76,7 @@ func GetStatus(c *gin.Context) { ...@@ -76,6 +76,7 @@ func GetStatus(c *gin.Context) {
"demo_site_enabled": operation_setting.DemoSiteEnabled, "demo_site_enabled": operation_setting.DemoSiteEnabled,
"self_use_mode_enabled": operation_setting.SelfUseModeEnabled, "self_use_mode_enabled": operation_setting.SelfUseModeEnabled,
"default_use_auto_group": setting.DefaultUseAutoGroup, "default_use_auto_group": setting.DefaultUseAutoGroup,
"pay_methods": setting.PayMethods,
// 面板启用开关 // 面板启用开关
"api_info_enabled": cs.ApiInfoEnabled, "api_info_enabled": cs.ApiInfoEnabled,
......
...@@ -53,6 +53,7 @@ type GeneralOpenAIRequest struct { ...@@ -53,6 +53,7 @@ type GeneralOpenAIRequest struct {
Modalities json.RawMessage `json:"modalities,omitempty"` Modalities json.RawMessage `json:"modalities,omitempty"`
Audio json.RawMessage `json:"audio,omitempty"` Audio json.RawMessage `json:"audio,omitempty"`
EnableThinking any `json:"enable_thinking,omitempty"` // ali EnableThinking any `json:"enable_thinking,omitempty"` // ali
THINKING json.RawMessage `json:"thinking,omitempty"` // doubao
ExtraBody json.RawMessage `json:"extra_body,omitempty"` ExtraBody json.RawMessage `json:"extra_body,omitempty"`
WebSearchOptions *WebSearchOptions `json:"web_search_options,omitempty"` WebSearchOptions *WebSearchOptions `json:"web_search_options,omitempty"`
// OpenRouter Params // OpenRouter Params
......
...@@ -79,6 +79,7 @@ func InitOptionMap() { ...@@ -79,6 +79,7 @@ func InitOptionMap() {
common.OptionMap["Chats"] = setting.Chats2JsonString() common.OptionMap["Chats"] = setting.Chats2JsonString()
common.OptionMap["AutoGroups"] = setting.AutoGroups2JsonString() common.OptionMap["AutoGroups"] = setting.AutoGroups2JsonString()
common.OptionMap["DefaultUseAutoGroup"] = strconv.FormatBool(setting.DefaultUseAutoGroup) common.OptionMap["DefaultUseAutoGroup"] = strconv.FormatBool(setting.DefaultUseAutoGroup)
common.OptionMap["PayMethods"] = setting.PayMethods2JsonString()
common.OptionMap["GitHubClientId"] = "" common.OptionMap["GitHubClientId"] = ""
common.OptionMap["GitHubClientSecret"] = "" common.OptionMap["GitHubClientSecret"] = ""
common.OptionMap["TelegramBotToken"] = "" common.OptionMap["TelegramBotToken"] = ""
...@@ -388,6 +389,8 @@ func updateOptionMap(key string, value string) (err error) { ...@@ -388,6 +389,8 @@ func updateOptionMap(key string, value string) (err error) {
operation_setting.AutomaticDisableKeywordsFromString(value) operation_setting.AutomaticDisableKeywordsFromString(value)
case "StreamCacheQueueLength": case "StreamCacheQueueLength":
setting.StreamCacheQueueLength, _ = strconv.Atoi(value) setting.StreamCacheQueueLength, _ = strconv.Atoi(value)
case "PayMethods":
err = setting.UpdatePayMethodsByJsonString(value)
} }
return err return err
} }
......
...@@ -374,8 +374,10 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon ...@@ -374,8 +374,10 @@ func CovertGemini2OpenAI(textRequest dto.GeneralOpenAIRequest, info *relaycommon
if content.Role == "assistant" { if content.Role == "assistant" {
content.Role = "model" content.Role = "model"
} }
if len(content.Parts) > 0 {
geminiRequest.Contents = append(geminiRequest.Contents, content) geminiRequest.Contents = append(geminiRequest.Contents, content)
} }
}
if len(system_content) > 0 { if len(system_content) > 0 {
geminiRequest.SystemInstructions = &GeminiChatContent{ geminiRequest.SystemInstructions = &GeminiChatContent{
......
package setting package setting
import "encoding/json"
var PayAddress = "" var PayAddress = ""
var CustomCallbackAddress = "" var CustomCallbackAddress = ""
var EpayId = "" var EpayId = ""
var EpayKey = "" var EpayKey = ""
var Price = 7.3 var Price = 7.3
var MinTopUp = 1 var MinTopUp = 1
var PayMethods = []map[string]string{
{
"name": "支付宝",
"color": "rgba(var(--semi-blue-5), 1)",
"type": "zfb",
},
{
"name": "微信",
"color": "rgba(var(--semi-green-5), 1)",
"type": "wx",
},
}
func UpdatePayMethodsByJsonString(jsonString string) error {
PayMethods = make([]map[string]string, 0)
return json.Unmarshal([]byte(jsonString), &PayMethods)
}
func PayMethods2JsonString() string {
jsonBytes, err := json.Marshal(PayMethods)
if err != nil {
return "[]"
}
return string(jsonBytes)
}
func ContainsPayMethod(method string) bool {
for _, payMethod := range PayMethods {
if payMethod["type"] == method {
return true
}
}
return false
}
...@@ -17,7 +17,7 @@ import { ...@@ -17,7 +17,7 @@ import {
removeTrailingSlash, removeTrailingSlash,
showError, showError,
showSuccess, showSuccess,
verifyJSON verifyJSON,
} from '../../helpers'; } from '../../helpers';
import axios from 'axios'; import axios from 'axios';
...@@ -73,6 +73,7 @@ const SystemSetting = () => { ...@@ -73,6 +73,7 @@ const SystemSetting = () => {
LinuxDOOAuthEnabled: '', LinuxDOOAuthEnabled: '',
LinuxDOClientId: '', LinuxDOClientId: '',
LinuxDOClientSecret: '', LinuxDOClientSecret: '',
PayMethods: '',
}); });
const [originInputs, setOriginInputs] = useState({}); const [originInputs, setOriginInputs] = useState({});
...@@ -230,6 +231,12 @@ const SystemSetting = () => { ...@@ -230,6 +231,12 @@ const SystemSetting = () => {
return; return;
} }
} }
if (originInputs['PayMethods'] !== inputs.PayMethods) {
if (!verifyJSON(inputs.PayMethods)) {
showError('充值方式设置不是合法的 JSON 字符串');
return;
}
}
const options = [ const options = [
{ key: 'PayAddress', value: removeTrailingSlash(inputs.PayAddress) }, { key: 'PayAddress', value: removeTrailingSlash(inputs.PayAddress) },
...@@ -256,6 +263,9 @@ const SystemSetting = () => { ...@@ -256,6 +263,9 @@ const SystemSetting = () => {
if (originInputs['TopupGroupRatio'] !== inputs.TopupGroupRatio) { if (originInputs['TopupGroupRatio'] !== inputs.TopupGroupRatio) {
options.push({ key: 'TopupGroupRatio', value: inputs.TopupGroupRatio }); options.push({ key: 'TopupGroupRatio', value: inputs.TopupGroupRatio });
} }
if (originInputs['PayMethods'] !== inputs.PayMethods) {
options.push({ key: 'PayMethods', value: inputs.PayMethods });
}
await updateOptions(options); await updateOptions(options);
}; };
...@@ -658,6 +668,12 @@ const SystemSetting = () => { ...@@ -658,6 +668,12 @@ const SystemSetting = () => {
placeholder='为一个 JSON 文本,键为组名称,值为倍率' placeholder='为一个 JSON 文本,键为组名称,值为倍率'
autosize autosize
/> />
<Form.TextArea
field='PayMethods'
label='充值方式设置'
placeholder='为一个 JSON 文本'
autosize
/>
<Button onClick={submitPayAddress}>更新支付设置</Button> <Button onClick={submitPayAddress}>更新支付设置</Button>
</Form.Section> </Form.Section>
</Card> </Card>
......
...@@ -96,20 +96,8 @@ const renderTimestamp = (timestampInSeconds) => { ...@@ -96,20 +96,8 @@ const renderTimestamp = (timestampInSeconds) => {
}; };
function renderDuration(submit_time, finishTime) { function renderDuration(submit_time, finishTime) {
// 确保startTime和finishTime都是有效的时间戳
if (!submit_time || !finishTime) return 'N/A'; if (!submit_time || !finishTime) return 'N/A';
const durationSec = finishTime - submit_time;
// 将时间戳转换为Date对象
const start = new Date(submit_time);
const finish = new Date(finishTime);
// 计算时间差(毫秒)
const durationMs = finish - start;
// 将时间差转换为秒,并保留一位小数
const durationSec = (durationMs / 1000).toFixed(1);
// 设置颜色:大于60秒则为红色,小于等于60秒则为绿色
const color = durationSec > 60 ? 'red' : 'green'; const color = durationSec > 60 ? 'red' : 'green';
// 返回带有样式的颜色标签 // 返回带有样式的颜色标签
......
...@@ -9,6 +9,7 @@ export function setStatusData(data) { ...@@ -9,6 +9,7 @@ export function setStatusData(data) {
localStorage.setItem('enable_task', data.enable_task); localStorage.setItem('enable_task', data.enable_task);
localStorage.setItem('enable_data_export', data.enable_data_export); localStorage.setItem('enable_data_export', data.enable_data_export);
localStorage.setItem('chats', JSON.stringify(data.chats)); localStorage.setItem('chats', JSON.stringify(data.chats));
localStorage.setItem('pay_methods', JSON.stringify(data.pay_methods));
localStorage.setItem( localStorage.setItem(
'data_export_default_time', 'data_export_default_time',
data.data_export_default_time, data.data_export_default_time,
......
...@@ -298,18 +298,27 @@ const EditChannel = (props) => { ...@@ -298,18 +298,27 @@ const EditChannel = (props) => {
} }
}; };
useEffect(() => { useEffect(() => {
let localModelOptions = [...originModelOptions]; // 使用 Map 来避免重复,以 value 为键
inputs.models.forEach((model) => { const modelMap = new Map();
if (!localModelOptions.find((option) => option.label === model)) {
localModelOptions.push({ // 先添加原始模型选项
originModelOptions.forEach(option => {
modelMap.set(option.value, option);
});
// 再添加当前选中的模型(如果不存在)
inputs.models.forEach(model => {
if (!modelMap.has(model)) {
modelMap.set(model, {
label: model, label: model,
value: model, value: model,
}); });
} }
}); });
setModelOptions(localModelOptions);
}, [originModelOptions, inputs.models]); setModelOptions(Array.from(modelMap.values()));
}, [originModelOptions, inputs.models]);
useEffect(() => { useEffect(() => {
fetchModels().then(); fetchModels().then();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment