diff --git a/README.md b/README.md index efb04b6c..2dcdbd4f 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ _✨ 通过标准的 OpenAI API 格式访问所有的大模型,开箱即用 5. 支持**多机部署**,[详见此处](#多机部署)。 6. 支持**令牌管理**,设置令牌的过期时间和额度。 7. 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为账户进行充值。 -8. 支持**通道管理**,批量创建通道。 +8. 支持**渠道管理**,批量创建渠道。 9. 支持**用户分组**以及**渠道分组**,支持为不同分组设置不同的倍率。 10. 支持渠道**设置模型列表**。 11. 支持**查看额度明细**。 @@ -421,7 +421,7 @@ https://openai.justsong.cn + 检查你的接口地址和 API Key 有没有填对。 + 检查是否启用了 HTTPS,浏览器会拦截 HTTPS 域名下的 HTTP 请求。 6. 报错:`当前分组负载已饱和,请稍后再试` - + 上游通道 429 了。 + + 上游渠道 429 了。 7. 升级之后我的数据会丢失吗? + 如果使用 MySQL,不会。 + 如果使用 SQLite,需要按照我所给的部署命令挂载 volume 持久化 one-api.db 数据库文件,否则容器重启后数据会丢失。 @@ -429,8 +429,8 @@ https://openai.justsong.cn + 一般情况下不需要,系统将在初始化的时候自动调整。 + 如果需要的话,我会在更新日志中说明,并给出脚本。 9. 手动修改数据库后报错:`数据库一致性已被破坏,请联系管理员`? - + 这是检测到 ability 表里有些记录的通道 id 是不存在的,这大概率是因为你删了 channel 表里的记录但是没有同步在 ability 表里清理无效的通道。 - + 对于每一个通道,其所支持的模型都需要有一个专门的 ability 表的记录,表示该通道支持该模型。 + + 这是检测到 ability 表里有些记录的渠道 id 是不存在的,这大概率是因为你删了 channel 表里的记录但是没有同步在 ability 表里清理无效的渠道。 + + 对于每一个渠道,其所支持的模型都需要有一个专门的 ability 表的记录,表示该渠道支持该模型。 ## 相关项目 * [FastGPT](https://github.com/labring/FastGPT): 基于 LLM 大语言模型的知识库问答系统 diff --git a/controller/channel-test.go b/controller/channel-test.go index 67ac91d0..95f4d769 100644 --- a/controller/channel-test.go +++ b/controller/channel-test.go @@ -197,7 +197,7 @@ func testChannels(notify bool, scope string) error { testAllChannelsRunning = false testAllChannelsLock.Unlock() if notify { - err := message.Notify(message.ByAll, "通道测试完成", "", "通道测试完成,如果没有收到禁用通知,说明所有通道都正常") + err := message.Notify(message.ByAll, "渠道测试完成", "", "渠道测试完成,如果没有收到禁用通知,说明所有渠道都正常") if err != nil { logger.SysError(fmt.Sprintf("failed to send email: %s", err.Error())) } diff --git a/i18n/en.json b/i18n/en.json index 54728e2f..b7f1bd3e 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -8,12 +8,12 @@ "确认删除": "Confirm Delete", "确认绑定": "Confirm Binding", "您正在删除自己的帐户,将清空所有数据且不可恢复": "You are deleting your account, all data will be cleared and unrecoverable.", - "\"通道「%s」(#%d)已被禁用\"": "\"Channel %s (#%d) has been disabled\"", - "通道「%s」(#%d)已被禁用,原因:%s": "Channel %s (#%d) has been disabled, reason: %s", + "\"渠道「%s」(#%d)已被禁用\"": "\"Channel %s (#%d) has been disabled\"", + "渠道「%s」(#%d)已被禁用,原因:%s": "Channel %s (#%d) has been disabled, reason: %s", "测试已在运行中": "Test is already running", "响应时间 %.2fs 超过阈值 %.2fs": "Response time %.2fs exceeds threshold %.2fs", - "通道测试完成": "Channel test completed", - "通道测试完成,如果没有收到禁用通知,说明所有通道都正常": "Channel test completed, if you have not received the disable notification, it means that all channels are normal", + "渠道测试完成": "Channel test completed", + "渠道测试完成,如果没有收到禁用通知,说明所有渠道都正常": "Channel test completed, if you have not received the disable notification, it means that all channels are normal", "无法连接至 GitHub 服务器,请稍后重试!": "Unable to connect to GitHub server, please try again later!", "返回值非法,用户字段为空,请稍后重试!": "The return value is illegal, the user field is empty, please try again later!", "管理员未开启通过 GitHub 登录以及注册": "The administrator did not turn on login and registration via GitHub", @@ -119,11 +119,11 @@ " 个月 ": " M ", " 年 ": " y ", "未测试": "Not tested", - "通道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。": "Channel ${name} test succeeded, time consumed ${time.toFixed(2)} s.", - "已成功开始测试所有通道,请刷新页面查看结果。": "All channels have been successfully tested, please refresh the page to view the results.", - "已成功开始测试所有已启用通道,请刷新页面查看结果。": "All enabled channels have been successfully tested, please refresh the page to view the results.", - "通道 ${name} 余额更新成功!": "Channel ${name} balance updated successfully!", - "已更新完毕所有已启用通道余额!": "The balance of all enabled channels has been updated!", + "渠道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。": "Channel ${name} test succeeded, time consumed ${time.toFixed(2)} s.", + "已成功开始测试所有渠道,请刷新页面查看结果。": "All channels have been successfully tested, please refresh the page to view the results.", + "已成功开始测试所有已启用渠道,请刷新页面查看结果。": "All enabled channels have been successfully tested, please refresh the page to view the results.", + "渠道 ${name} 余额更新成功!": "Channel ${name} balance updated successfully!", + "已更新完毕所有已启用渠道余额!": "The balance of all enabled channels has been updated!", "搜索渠道的 ID,名称和密钥 ...": "Search for channel ID, name and key ...", "名称": "Name", "分组": "Group", @@ -141,9 +141,9 @@ "启用": "Enable", "编辑": "Edit", "添加新的渠道": "Add a new channel", - "测试所有通道": "Test all channels", - "测试所有已启用通道": "Test all enabled channels", - "更新所有已启用通道余额": "Update the balance of all enabled channels", + "测试所有渠道": "Test all channels", + "测试所有已启用渠道": "Test all enabled channels", + "更新所有已启用渠道余额": "Update the balance of all enabled channels", "刷新": "Refresh", "处理中...": "Processing...", "绑定成功!": "Binding succeeded!", @@ -207,11 +207,11 @@ "监控设置": "Monitoring Settings", "最长响应时间": "Longest Response Time", "单位秒": "Unit in seconds", - "当运行通道全部测试时": "When all operating channels are tested", - "超过此时间将自动禁用通道": "Channels will be automatically disabled if this time is exceeded", + "当运行渠道全部测试时": "When all operating channels are tested", + "超过此时间将自动禁用渠道": "Channels will be automatically disabled if this time is exceeded", "额度提醒阈值": "Quota reminder threshold", "低于此额度时将发送邮件提醒用户": "Email will be sent to remind users when the quota is below this", - "失败时自动禁用通道": "Automatically disable the channel when it fails", + "失败时自动禁用渠道": "Automatically disable the channel when it fails", "保存监控设置": "Save Monitoring Settings", "额度设置": "Quota Settings", "新用户初始额度": "Initial quota for new users", @@ -405,7 +405,7 @@ "镜像": "Mirror", "请输入镜像站地址,格式为:https://domain.com,可不填,不填则使用渠道默认值": "Please enter the mirror site address, the format is: https://domain.com, it can be left blank, if left blank, the default value of the channel will be used", "模型": "Model", - "请选择该通道所支持的模型": "Please select the model supported by the channel", + "请选择该渠道所支持的模型": "Please select the model supported by the channel", "填入基础模型": "Fill in the basic model", "填入所有模型": "Fill in all models", "清除所有模型": "Clear all models", @@ -515,7 +515,7 @@ "请输入自定义渠道的 Base URL": "Please enter the Base URL of the custom channel", "Homepage URL 填": "Fill in the Homepage URL", "Authorization callback URL 填": "Fill in the Authorization callback URL", - "请为通道命名": "Please name the channel", + "请为渠道命名": "Please name the channel", "此项可选,用于修改请求体中的模型名称,为一个 JSON 字符串,键为请求中模型名称,值为要替换的模型名称,例如:": "This is optional, used to modify the model name in the request body, it's a JSON string, the key is the model name in the request, and the value is the model name to be replaced, for example:", "模型重定向": "Model redirection", "请输入渠道对应的鉴权密钥": "Please enter the authentication key corresponding to the channel", diff --git a/monitor/channel.go b/monitor/channel.go index 597ab11a..ad82d2f5 100644 --- a/monitor/channel.go +++ b/monitor/channel.go @@ -31,17 +31,17 @@ func notifyRootUser(subject string, content string) { func DisableChannel(channelId int, channelName string, reason string) { model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled) logger.SysLog(fmt.Sprintf("channel #%d has been disabled: %s", channelId, reason)) - subject := fmt.Sprintf("通道「%s」(#%d)已被禁用", channelName, channelId) - content := fmt.Sprintf("通道「%s」(#%d)已被禁用,原因:%s", channelName, channelId, reason) + subject := fmt.Sprintf("渠道「%s」(#%d)已被禁用", channelName, channelId) + content := fmt.Sprintf("渠道「%s」(#%d)已被禁用,原因:%s", channelName, channelId, reason) notifyRootUser(subject, content) } func MetricDisableChannel(channelId int, successRate float64) { model.UpdateChannelStatusById(channelId, common.ChannelStatusAutoDisabled) logger.SysLog(fmt.Sprintf("channel #%d has been disabled due to low success rate: %.2f", channelId, successRate*100)) - subject := fmt.Sprintf("通道 #%d 已被禁用", channelId) - content := fmt.Sprintf("该渠道在最近 %d 次调用中成功率为 %.2f%%,低于阈值 %.2f%%,因此被系统自动禁用。", - config.MetricQueueSize, successRate*100, config.MetricSuccessRateThreshold*100) + subject := fmt.Sprintf("渠道 #%d 已被禁用", channelId) + content := fmt.Sprintf("该渠道(#%d)在最近 %d 次调用中成功率为 %.2f%%,低于阈值 %.2f%%,因此被系统自动禁用。", + channelId, config.MetricQueueSize, successRate*100, config.MetricSuccessRateThreshold*100) notifyRootUser(subject, content) } @@ -49,7 +49,7 @@ func MetricDisableChannel(channelId int, successRate float64) { func EnableChannel(channelId int, channelName string) { model.UpdateChannelStatusById(channelId, common.ChannelStatusEnabled) logger.SysLog(fmt.Sprintf("channel #%d has been enabled", channelId)) - subject := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) - content := fmt.Sprintf("通道「%s」(#%d)已被启用", channelName, channelId) + subject := fmt.Sprintf("渠道「%s」(#%d)已被启用", channelName, channelId) + content := fmt.Sprintf("渠道「%s」(#%d)已被启用", channelName, channelId) notifyRootUser(subject, content) } diff --git a/web/air/src/components/ChannelsTable.js b/web/air/src/components/ChannelsTable.js index dee21a01..c384d50c 100644 --- a/web/air/src/components/ChannelsTable.js +++ b/web/air/src/components/ChannelsTable.js @@ -437,7 +437,7 @@ const ChannelsTable = () => { if (success) { record.response_time = time * 1000; record.test_time = Date.now() / 1000; - showInfo(`通道 ${record.name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); + showInfo(`渠道 ${record.name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); } else { showError(message); } @@ -447,7 +447,7 @@ const ChannelsTable = () => { const res = await API.get(`/api/channel/test?scope=${scope}`); const { success, message } = res.data; if (success) { - showInfo('已成功开始测试通道,请刷新页面查看结果。'); + showInfo('已成功开始测试渠道,请刷新页面查看结果。'); } else { showError(message); } @@ -470,7 +470,7 @@ const ChannelsTable = () => { if (success) { record.balance = balance; record.balance_updated_time = Date.now() / 1000; - showInfo(`通道 ${record.name} 余额更新成功!`); + showInfo(`渠道 ${record.name} 余额更新成功!`); } else { showError(message); } @@ -481,7 +481,7 @@ const ChannelsTable = () => { const res = await API.get(`/api/channel/update_balance`); const { success, message } = res.data; if (success) { - showInfo('已更新完毕所有已启用通道余额!'); + showInfo('已更新完毕所有已启用渠道余额!'); } else { showError(message); } @@ -490,7 +490,7 @@ const ChannelsTable = () => { const batchDeleteChannels = async () => { if (selectedChannels.length === 0) { - showError('请先选择要删除的通道!'); + showError('请先选择要删除的渠道!'); return; } setLoading(true); @@ -501,7 +501,7 @@ const ChannelsTable = () => { const res = await API.post(`/api/channel/batch`, { ids: ids }); const { success, message, data } = res.data; if (success) { - showSuccess(`已删除 ${data} 个通道!`); + showSuccess(`已删除 ${data} 个渠道!`); await refresh(); } else { showError(message); @@ -513,7 +513,7 @@ const ChannelsTable = () => { const res = await API.post(`/api/channel/fix`); const { success, message, data } = res.data; if (success) { - showSuccess(`已修复 ${data} 个通道!`); + showSuccess(`已修复 ${data} 个渠道!`); await refresh(); } else { showError(message); @@ -633,7 +633,7 @@ const ChannelsTable = () => { onConfirm={() => { testChannels("all") }} position={isMobile() ? 'top' : 'left'} > - + { okType={'secondary'} onConfirm={updateAllChannelsBalance} > - + */} - + @@ -673,7 +673,7 @@ const ChannelsTable = () => { setEnableBatchDelete(v); }}> { position={'top'} > + style={{ marginRight: 8 }}>删除所选渠道 { value={inputs.ChannelDisableThreshold} type='number' min='0' - placeholder='单位秒,当运行通道全部测试时,超过此时间将自动禁用通道' + placeholder='单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道' /> { diff --git a/web/berry/src/views/Channel/component/TableRow.js b/web/berry/src/views/Channel/component/TableRow.js index f7acb92e..1e58b678 100644 --- a/web/berry/src/views/Channel/component/TableRow.js +++ b/web/berry/src/views/Channel/component/TableRow.js @@ -93,7 +93,7 @@ export default function ChannelTableRow({ test_time: Date.now() / 1000, response_time: time * 1000, }); - showInfo(`通道 ${item.name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); + showInfo(`渠道 ${item.name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); } }; @@ -243,9 +243,9 @@ export default function ChannelTableRow({ - 删除通道 + 删除渠道 - 是否删除通道 {item.name}? + 是否删除渠道 {item.name}? diff --git a/web/berry/src/views/Channel/index.js b/web/berry/src/views/Channel/index.js index e801a8c3..c12ff3ba 100644 --- a/web/berry/src/views/Channel/index.js +++ b/web/berry/src/views/Channel/index.js @@ -135,7 +135,7 @@ export default function ChannelPage() { const res = await API.get(`/api/channel/test`); const { success, message } = res.data; if (success) { - showInfo('已成功开始测试所有通道,请刷新页面查看结果。'); + showInfo('已成功开始测试所有渠道,请刷新页面查看结果。'); } else { showError(message); } @@ -159,7 +159,7 @@ export default function ChannelPage() { const res = await API.get(`/api/channel/update_balance`); const { success, message } = res.data; if (success) { - showInfo('已更新完毕所有已启用通道余额!'); + showInfo('已更新完毕所有已启用渠道余额!'); } else { showError(message); } diff --git a/web/berry/src/views/Setting/component/OperationSetting.js b/web/berry/src/views/Setting/component/OperationSetting.js index d91298b2..2bed715b 100644 --- a/web/berry/src/views/Setting/component/OperationSetting.js +++ b/web/berry/src/views/Setting/component/OperationSetting.js @@ -371,7 +371,7 @@ const OperationSetting = () => { value={inputs.ChannelDisableThreshold} onChange={handleInputChange} label="最长响应时间" - placeholder="单位秒,当运行通道全部测试时,超过此时间将自动禁用通道" + placeholder="单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道" disabled={loading} /> @@ -392,7 +392,7 @@ const OperationSetting = () => { { } /> { newChannels[realIdx].response_time = time * 1000; newChannels[realIdx].test_time = Date.now() / 1000; setChannels(newChannels); - showInfo(`通道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); + showInfo(`渠道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。`); } else { showError(message); } @@ -244,7 +244,7 @@ const ChannelsTable = () => { const res = await API.get(`/api/channel/test?scope=${scope}`); const { success, message } = res.data; if (success) { - showInfo('已成功开始测试通道,请刷新页面查看结果。'); + showInfo('已成功开始测试渠道,请刷新页面查看结果。'); } else { showError(message); } @@ -270,7 +270,7 @@ const ChannelsTable = () => { newChannels[realIdx].balance = balance; newChannels[realIdx].balance_updated_time = Date.now() / 1000; setChannels(newChannels); - showInfo(`通道 ${name} 余额更新成功!`); + showInfo(`渠道 ${name} 余额更新成功!`); } else { showError(message); } @@ -281,7 +281,7 @@ const ChannelsTable = () => { const res = await API.get(`/api/channel/update_balance`); const { success, message } = res.data; if (success) { - showInfo('已更新完毕所有已启用通道余额!'); + showInfo('已更新完毕所有已启用渠道余额!'); } else { showError(message); } diff --git a/web/default/src/components/OperationSetting.js b/web/default/src/components/OperationSetting.js index b823bb28..6356ac66 100644 --- a/web/default/src/components/OperationSetting.js +++ b/web/default/src/components/OperationSetting.js @@ -261,7 +261,7 @@ const OperationSetting = () => { value={inputs.ChannelDisableThreshold} type='number' min='0' - placeholder='单位秒,当运行通道全部测试时,超过此时间将自动禁用通道' + placeholder='单位秒,当运行渠道全部测试时,超过此时间将自动禁用渠道' /> {