🔖 chore: English translation and other improvements (#163)

* chore: improve english translation

* fix: typo of error message

* chore: improve frontend icon

* chore: improve English translation

* chore: update PaperProps width to minWidth in TableRow.js files

* chore: Add Docker image workflow for one-api in English

---------

Co-authored-by: Martial BE <me@xiao5.info>
This commit is contained in:
Miraz Hossain 2024-04-23 14:25:40 +06:00 committed by GitHub
parent d1369eb5c6
commit a76b3f6ac2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 1232 additions and 409 deletions

111
.github/workflows/docker-image-en.yml vendored Normal file
View File

@ -0,0 +1,111 @@
name: one-api docker image
on:
push:
branches:
- main
tags:
- "v*"
paths-ignore:
- "README.md"
env:
# github.repository as <account>/<repo>
DOCKER_HUB_USERNAME: martialbe
DOCKER_HUB_REPO: one-api-en
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Check out the repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Save dev version info
run: |
HASH=$(git rev-parse --short=7 HEAD)
echo "dev-$HASH" > VERSION
- name: Save Tag version info
if: startsWith(github.ref, 'refs/tags/')
run: |
git describe --tags > VERSION
- name: Translate
run: |
python ./i18n/translate.py --repository_path . --json_file_path ./i18n/en.json
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Build Frontend
env:
CI: ""
run: |
export VERSION=$(cat VERSION)
cd web
yarn install
REACT_APP_VERSION=$VERSION yarn run build
cd ..
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: ">=1.18.0"
- name: Build Backend (amd64)
run: |
go mod download
go build -ldflags "-s -w -X 'one-api/common.Version=$(cat VERSION)' -extldflags '-static'" -o one-api-amd64
- name: Build Backend (arm64)
run: |
sudo apt-get update
sudo apt-get install gcc-aarch64-linux-gnu
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'one-api/common.Version=$(cat VERSION)' -extldflags '-static'" -o one-api-arm64
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
registry: docker.io
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }} # Replace with your Docker Hub password secret
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |
ghcr.io/${{ github.repository }}-en
docker.io/${{ env.DOCKER_HUB_USERNAME }}/${{ env.DOCKER_HUB_REPO }}
# generate Docker tags based on the following events/attributes
tags: |
type=raw,value=dev,enable=${{ github.ref == 'refs/heads/main' }}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=pep440,pattern={{raw}},enable=${{ startsWith(github.ref, 'refs/tags/') }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
build-args: |
COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
file: Dockerfile-action

114
README.en.md Normal file
View File

@ -0,0 +1,114 @@
<p align="right">
<strong>English</strong> | <a href="./README.md">中文</a>
</p>
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/MartialBE/one-api/assets/42402987/c4125d1a-5577-446d-ba15-2a71c52140c1">
<img height="90" src="https://raw.githubusercontent.com/MartialBE/one-api/main/web/src/assets/images/logo.svg">
</picture>
</p>
<div align="center">
# One API
_This project is based on [one-api](https://github.com/songquanpeng/one-api) and has been developed for the second time. The main purpose is to separate the module code in the original project, modularize it, and modify the front-end interface. This project also follows the MIT protocol._
<p align="center">
<a href="https://raw.githubusercontent.com/MartialBE/one-api/main/LICENSE">
<img src="https://img.shields.io/github/license/MartialBE/one-api?color=brightgreen" alt="license">
</a>
<a href="https://github.com/MartialBE/one-api/releases/latest">
<img src="https://img.shields.io/github/v/release/MartialBE/one-api?color=brightgreen&include_prereleases" alt="release">
</a>
<a href="https://github.com/users/MartialBE/packages/container/package/one-api">
<img src="https://img.shields.io/badge/docker-ghcr.io-blue" alt="docker">
</a>
<a href="https://hub.docker.com/r/martialbe/one-api">
<img src="https://img.shields.io/badge/docker-dockerHub-blue" alt="docker">
</a>
<a href="https://goreportcard.com/report/github.com/MartialBE/one-api">
<img src="https://goreportcard.com/badge/github.com/MartialBE/one-api" alt="GoReportCard">
</a>
</p>
**Please do not mix with the original version, because the new functions, the database is not compatible with the original version**
**For the sake of simplicity, after this project, except for updating the model list built into the program when adding a new supplier, the model list built into the program will not be updated under normal circumstances.**
If you find that a new model is missing, please update the newly added model in `Backend-Model Price-Update Price`
[Demo Site](https://one-api-martialbe.vercel.app/)
</div>
## Functional Changes
- Brand new UI interface
- Added user dashboard
- Added administrator data analysis and statistics interface
- Refactored the intermediary `supplier` module
- Support for using `Azure Speech` to simulate `TTS` function
- Channels can be configured with separate http/socks5 proxies
- Support for dynamically returning user model lists
- Support for custom speed testing models
- Logs now include request duration
- Support and optimize function calls for non-OpenAI models (supported models can be used directly in Lobe-Chat)
- Support for custom completion rates
- Support for full pagination and sorting
- Support for `Telegram bot`
- Support for models charged per use
- Support for model wildcards
- Support for starting the program using a configuration file
## Documentation
Please refer to the [documentation](https://github.com/MartialBE/one-api/wiki).
## Current Supported Providers
| Provider | Chat | Embeddings | Audio | Images | Other |
| --------------------------------------------------------------------- | ------------------------ | ---------- | ------ | ----------- | ---------------------------------------------------------------- |
| [OpenAI](https://platform.openai.com/docs/api-reference/introduction) | ✅ | ✅ | ✅ | ✅ | - |
| [Azure OpenAI](https://oai.azure.com/) | ✅ | ✅ | ✅ | ✅ | - |
| [Azure Speech](https://portal.azure.com/) | - | - | ⚠️ tts | - | - |
| [Anthropic](https://www.anthropic.com/) | ✅ | - | - | - | - |
| [Gemini](https://aistudio.google.com/) | ✅ | - | - | - | - |
| [百度文心](https://console.bce.baidu.com/qianfan/overview) | ✅ | ✅ | - | - | - |
| [通义千问](https://dashscope.console.aliyun.com/overview) | ✅ | ✅ | - | - | - |
| [讯飞星火](https://console.xfyun.cn/) | ✅ | - | - | - | - |
| [智谱](https://open.bigmodel.cn/overview) | ✅ | ✅ | - | ⚠️ image | - |
| [腾讯混元](https://cloud.tencent.com/product/hunyuan) | ✅ | - | - | - | - |
| [百川](https://platform.baichuan-ai.com/console/apikey) | ✅ | ✅ | - | - | - |
| [MiniMax](https://www.minimaxi.com/user-center/basic-information) | ✅ | ✅ | - | - | - |
| [Deepseek](https://platform.deepseek.com/usage) | ✅ | - | - | - | - |
| [Moonshot](https://moonshot.ai/) | ✅ | - | - | - | - |
| [Mistral](https://mistral.ai/) | ✅ | ✅ | - | - | - |
| [Groq](https://console.groq.com/keys) | ✅ | - | - | - | - |
| [Amazon Bedrock](https://console.aws.amazon.com/bedrock/home) | ⚠️ Only support Anthropic models | - | - | - | - |
| [零一万物](https://platform.lingyiwanwu.com/details) | ✅ | - | - | - | - |
| [Cloudflare AI](https://ai.cloudflare.com/) | ✅ | - | ⚠️ stt | ⚠️ image | - |
| [Midjourney](https://www.midjourney.com/) | - | - | - | - | [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) |
| [Cohere](https://cohere.com/) | ✅ | - | - | - | - |
| [Stability AI](https://platform.stability.ai/account/credits) | - | - | - | ⚠️ image | - |
| [Coze](https://www.coze.com/open/docs/chat?_lang=zh) | ✅ | - | - | - | - |
## Acknowledgements
- This program utilizes the following open-source projects:
- [one-api](https://github.com/songquanpeng/one-api) serves as the foundation of this project.
- [Berry Free React Admin Template](https://github.com/codedthemes/berry-free-react-admin-template) provides the frontend interface for this project.
- [minimal-ui-kit](https://github.com/minimal-ui-kit/material-kit-react), some styles from this project were used.
- [new api](https://github.com/Calcium-Ion/new-api), the code for the Midjourney module is sourced from here.
Special thanks to the authors and contributors of the above projects.
## Others
<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history?repo_id=689214770" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=689214770&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star History of MartialBE/one-api" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-history/thumbnail.png?repo_id=689214770&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>

View File

@ -1,3 +1,7 @@
<p align="right">
<strong>中文</strong> | <a href="./README.en.md">English</a>
</p>
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/MartialBE/one-api/assets/42402987/c4125d1a-5577-446d-ba15-2a71c52140c1">

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ import (
// 定义供应商工厂
type AzureSpeechProviderFactory struct{}
// 创建 AliProvider
// 创建 AzureSpeechProvider
func (f AzureSpeechProviderFactory) Create(channel *model.Channel) base.ProviderInterface {
return &AzureSpeechProvider{
BaseProvider: base.BaseProvider{

View File

@ -13,7 +13,7 @@ import (
type GeminiProviderFactory struct{}
// 创建 ClaudeProvider
// 创建 GeminiProvider
func (f GeminiProviderFactory) Create(channel *model.Channel) base.ProviderInterface {
return &GeminiProvider{
BaseProvider: base.BaseProvider{

View File

@ -61,7 +61,7 @@ func (p *PalmProvider) getChatRequest(request *types.ChatCompletionRequest) (*ht
// 获取请求地址
fullRequestURL := p.GetFullRequestURL(url, request.Model)
if fullRequestURL == "" {
return nil, common.ErrorWrapper(nil, "invalid_baidu_config", http.StatusInternalServerError)
return nil, common.ErrorWrapper(nil, "invalid_palm_config", http.StatusInternalServerError)
}
// 获取请求头

View File

@ -69,7 +69,7 @@ func (p *TencentProvider) getChatRequest(request *types.ChatCompletionRequest) (
// 获取请求地址
fullRequestURL := p.GetFullRequestURL(url, request.Model)
if fullRequestURL == "" {
return nil, common.ErrorWrapper(nil, "invalid_baidu_config", http.StatusInternalServerError)
return nil, common.ErrorWrapper(nil, "invalid_tencent_config", http.StatusInternalServerError)
}
// 获取请求头

View File

@ -4,12 +4,12 @@ import {
IconSitemap,
IconArticle,
IconCoin,
IconAdjustments,
IconSettingsCog,
IconKey,
IconGardenCart,
IconCreditCard,
IconUser,
IconUserScan,
IconActivity,
IconChartHistogram,
IconBrandTelegram,
IconReceipt2,
IconBrush,
@ -22,12 +22,12 @@ const icons = {
IconSitemap,
IconArticle,
IconCoin,
IconAdjustments,
IconSettingsCog,
IconKey,
IconGardenCart,
IconCreditCard,
IconUser,
IconUserScan,
IconActivity,
IconChartHistogram,
IconBrandTelegram,
IconReceipt2,
IconBrush,
@ -54,7 +54,7 @@ const panel = {
title: '分析',
type: 'item',
url: '/panel/analytics',
icon: icons.IconActivity,
icon: icons.IconChartHistogram,
breadcrumbs: false,
isAdmin: true
},
@ -97,7 +97,7 @@ const panel = {
title: '充值',
type: 'item',
url: '/panel/topup',
icon: icons.IconGardenCart,
icon: icons.IconCreditCard,
breadcrumbs: false
},
{
@ -149,7 +149,7 @@ const panel = {
title: '设置',
type: 'item',
url: '/panel/setting',
icon: icons.IconAdjustments,
icon: icons.IconSettingsCog,
breadcrumbs: false,
isAdmin: true
},

View File

@ -1,7 +1,7 @@
import { useState } from 'react';
import { Grid, TextField, InputAdornment, Checkbox, Button, FormControlLabel, IconButton, Alert } from '@mui/material';
import { gridSpacing } from 'store/constant';
import { IconSearch, IconHttpDelete } from '@tabler/icons-react';
import { IconSearch, IconTrash } from '@tabler/icons-react';
import { fetchChannelData } from '../index';
import { API } from 'utils/api';
import { showError, showSuccess } from 'utils/common';
@ -112,7 +112,7 @@ const BatchDelModel = () => {
))}
</Grid>
<Grid item xs={12}>
<Button variant="contained" color="primary" startIcon={<IconHttpDelete />} onClick={handleSubmit} disabled={loadding}>
<Button variant="contained" color="primary" startIcon={<IconTrash />} onClick={handleSubmit} disabled={loadding}>
删除
</Button>
</Grid>

View File

@ -309,7 +309,7 @@ export default function ChannelTableRow({ item, manageChannel, handleOpenModal,
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
<MenuItem

View File

@ -17,7 +17,7 @@ import { Button, IconButton, Card, Box, Stack, Container, Typography, Divider }
import ChannelTableRow from './component/TableRow';
import KeywordTableHead from 'ui-component/TableHead';
import { API } from 'utils/api';
import { IconRefresh, IconHttpDelete, IconPlus, IconMenu2, IconBrandSpeedtest, IconCoinYuan, IconSearch } from '@tabler/icons-react';
import { IconRefresh, IconTrash, IconPlus, IconMenu2, IconBrandSpeedtest, IconCoinYuan, IconSearch } from '@tabler/icons-react';
import EditeModal from './component/EditModal';
import { ITEMS_PER_PAGE } from 'constants';
import TableToolBar from './component/TableToolBar';
@ -340,7 +340,7 @@ export default function ChannelPage() {
<Button onClick={updateAllChannelsBalance} startIcon={<IconCoinYuan width={'18px'} />}>
更新启用余额
</Button>
<Button onClick={deleteAllDisabledChannels} startIcon={<IconHttpDelete width={'18px'} />}>
<Button onClick={deleteAllDisabledChannels} startIcon={<IconTrash width={'18px'} />}>
删除禁用渠道
</Button>
</ButtonGroup>
@ -365,7 +365,7 @@ export default function ChannelPage() {
<IconCoinYuan />
</IconButton>
<IconButton onClick={deleteAllDisabledChannels} size="large">
<IconHttpDelete />
<IconTrash />
</IconButton>
</Stack>
)}

View File

@ -133,7 +133,7 @@ export default function LogTableRow({ item, userIsAdmin }) {
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
<MenuList>

View File

@ -111,7 +111,7 @@ export default function PricesTableRow({ item, managePrices, handleOpenModal, se
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
<MenuItem

View File

@ -103,7 +103,7 @@ export default function RedemptionTableRow({ item, manageRedemption, handleOpenM
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
<MenuItem

View File

@ -1,7 +1,7 @@
import { useState, useEffect, useMemo } from 'react';
import PropTypes from 'prop-types';
import { Tabs, Tab, Box, Card } from '@mui/material';
import { IconSettings2, IconActivity, IconSettings } from '@tabler/icons-react';
import { IconWorldCog, IconCpu, IconServerCog } from '@tabler/icons-react';
import OperationSetting from './component/OperationSetting';
import SystemSetting from './component/SystemSetting';
import OtherSetting from './component/OtherSetting';
@ -69,9 +69,9 @@ const Setting = () => {
<Box sx={{ width: '100%' }}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={value} onChange={handleChange} variant="scrollable" scrollButtons="auto">
<Tab label="运营设置" {...a11yProps(0)} icon={<IconActivity />} iconPosition="start" />
<Tab label="系统设置" {...a11yProps(1)} icon={<IconSettings />} iconPosition="start" />
<Tab label="其他设置" {...a11yProps(2)} icon={<IconSettings2 />} iconPosition="start" />
<Tab label="运营设置" {...a11yProps(0)} icon={<IconCpu />} iconPosition="start" />
<Tab label="系统设置" {...a11yProps(1)} icon={<IconServerCog />} iconPosition="start" />
<Tab label="其他设置" {...a11yProps(2)} icon={<IconWorldCog />} iconPosition="start" />
</Tabs>
</Box>
<CustomTabPanel value={value} index={0}>

View File

@ -71,7 +71,7 @@ export default function TelegramTableRow({ item, manageAction, handleOpenModal,
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
<MenuItem

View File

@ -246,7 +246,7 @@ export default function TokensTableRow({ item, manageToken, handleOpenModal, set
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
{menuItems}

View File

@ -1,5 +1,5 @@
import { Typography, Stack, OutlinedInput, InputAdornment, Button, InputLabel, FormControl } from '@mui/material';
import { IconWallet } from '@tabler/icons-react';
import { IconBuildingBank } from '@tabler/icons-react';
import { useTheme } from '@mui/material/styles';
import SubCard from 'ui-component/cards/SubCard';
import UserCard from 'ui-component/cards/UserCard';
@ -78,7 +78,7 @@ const TopupCard = () => {
return (
<UserCard>
<Stack direction="row" alignItems="center" justifyContent="center" spacing={2} paddingTop={'20px'}>
<IconWallet color={theme.palette.primary.main} />
<IconBuildingBank color={theme.palette.primary.main} />
<Typography variant="h4">当前额度:</Typography>
<Typography variant="h4">{renderQuota(userQuota)}</Typography>
</Stack>

View File

@ -138,7 +138,7 @@ export default function UsersTableRow({ item, manageUser, handleOpenModal, setMo
anchorOrigin={{ vertical: 'top', horizontal: 'left' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: { width: 140 }
sx: { minWidth: 140 }
}}
>
{item.role !== 100 && (