mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-24 22:03:54 +00:00
feat translation of the user module
Signed-off-by: jingyang <3161362058@qq.com>
This commit is contained in:
@@ -39,6 +39,21 @@
|
||||
"Set OpenAI Account Failed": "Set OpenAI account failed",
|
||||
"Update Password": "Update Password",
|
||||
"Update password failed": "Update password failed",
|
||||
"Update password succseful": "Update password succseful"
|
||||
"Update password succseful": "Update password succseful",
|
||||
"Personal Information": "Personal",
|
||||
"Usage Record": "Usage",
|
||||
"Recharge Record": "Recharge",
|
||||
"Notice": "Notice",
|
||||
"Sign Out": "Sign Out",
|
||||
"Avatar": "Avatar",
|
||||
"Account": "Account",
|
||||
"Balance": "Balance",
|
||||
"Time": "Time",
|
||||
"Source": "Source",
|
||||
"Application Name": "Application Name",
|
||||
"Total Amount": "Total Amount",
|
||||
"Change": "Change",
|
||||
"Password": "Password",
|
||||
"Replace": "Replace"
|
||||
}
|
||||
}
|
||||
}
|
@@ -39,6 +39,21 @@
|
||||
"Set OpenAI Account Failed": "设置 OpenAI 账号异常",
|
||||
"Update Password": "修改密码",
|
||||
"Update password failed": "修改密码异常",
|
||||
"Update password succseful": "修改密码成功"
|
||||
"Update password succseful": "修改密码成功",
|
||||
"Personal Information": "个人信息",
|
||||
"Usage Record": "使用记录",
|
||||
"Recharge Record": "充值记录",
|
||||
"Notice": "通知",
|
||||
"Sign Out": "登出",
|
||||
"Avatar": "头像",
|
||||
"Account": "账号",
|
||||
"Balance": "余额",
|
||||
"Time": "时间",
|
||||
"Source": "来源",
|
||||
"Application Name": "应用名",
|
||||
"Total Amount": "总金额",
|
||||
"Change": "变更",
|
||||
"Password": "密码",
|
||||
"Replace": "更换"
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
||||
import { Box, Flex, useTheme } from '@chakra-ui/react';
|
||||
import type { GridProps } from '@chakra-ui/react';
|
||||
import MyIcon, { type IconName } from '../Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
// @ts-ignore
|
||||
export interface Props extends GridProps {
|
||||
@@ -12,6 +13,7 @@ export interface Props extends GridProps {
|
||||
}
|
||||
|
||||
const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const sizeMap = useMemo(() => {
|
||||
switch (size) {
|
||||
case 'sm':
|
||||
@@ -61,7 +63,7 @@ const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =>
|
||||
}}
|
||||
>
|
||||
<MyIcon mr={2} name={item.icon as IconName} w={'16px'} />
|
||||
{item.label}
|
||||
{t(item.label)}
|
||||
</Flex>
|
||||
))}
|
||||
</Box>
|
||||
|
@@ -22,10 +22,11 @@ import DateRangePicker, { type DateRangeType } from '@/components/DateRangePicke
|
||||
import { addDays } from 'date-fns';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
import { useTranslation } from 'next-i18next';
|
||||
const BillDetail = dynamic(() => import('./BillDetail'));
|
||||
|
||||
const BillTable = () => {
|
||||
const { t } = useTranslation();
|
||||
const { Loading } = useLoading();
|
||||
const [dateRange, setDateRange] = useState<DateRangeType>({
|
||||
from: addDays(new Date(), -7),
|
||||
@@ -55,10 +56,10 @@ const BillTable = () => {
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>时间</Th>
|
||||
<Th>来源</Th>
|
||||
<Th>应用名</Th>
|
||||
<Th>总金额</Th>
|
||||
<Th>{t('user.Time')}</Th>
|
||||
<Th>{t('user.Source')}</Th>
|
||||
<Th>{t('user.Application Name')}</Th>
|
||||
<Th>{t('user.Total Amount')}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
|
@@ -10,8 +10,7 @@ import dynamic from 'next/dynamic';
|
||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||
import { compressImg } from '@/utils/file';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Loading from '@/components/Loading';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import MyIcon from '@/components/Icon';
|
||||
@@ -125,7 +124,7 @@ const UserInfo = () => {
|
||||
|
||||
<Flex alignItems={'center'} fontSize={'sm'} color={'myGray.600'}>
|
||||
<MyIcon mr={1} name={'edit'} w={'14px'} />
|
||||
更换
|
||||
{t('user.Replace')}
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Box
|
||||
@@ -136,26 +135,26 @@ const UserInfo = () => {
|
||||
mt={[6, 0]}
|
||||
>
|
||||
<Flex alignItems={'center'} w={['85%', '300px']}>
|
||||
<Box flex={'0 0 50px'}>账号:</Box>
|
||||
<Box flex={'0 0 50px'}>{t('user.Account')}: </Box>
|
||||
<Box flex={1}>{userInfo?.username}</Box>
|
||||
</Flex>
|
||||
<Flex mt={6} alignItems={'center'} w={['85%', '300px']}>
|
||||
<Box flex={'0 0 50px'}>密码:</Box>
|
||||
<Box flex={'0 0 50px'}>{t('user.Password')}: </Box>
|
||||
<Box flex={1}>*****</Box>
|
||||
<Button size={['sm', 'md']} variant={'base'} ml={5} onClick={onOpenUpdatePsw}>
|
||||
变更
|
||||
{t('user.Change')}
|
||||
</Button>
|
||||
</Flex>
|
||||
{feConfigs?.show_userDetail && (
|
||||
<>
|
||||
<Box mt={6} whiteSpace={'nowrap'} w={['85%', '300px']}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'0 0 50px'}>余额:</Box>
|
||||
<Box flex={'0 0 50px'}>{t('user.Balance')}: </Box>
|
||||
<Box flex={1}>
|
||||
<strong>{userInfo?.balance.toFixed(3)}</strong> 元
|
||||
</Box>
|
||||
<Button size={['sm', 'md']} ml={5} onClick={onOpenPayModal}>
|
||||
充值
|
||||
{t('user.Pay')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
@@ -32,11 +32,36 @@ enum TabEnum {
|
||||
|
||||
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
const tabList = useRef([
|
||||
{ icon: 'meLight', label: '个人信息', id: TabEnum.info, Component: <BillTable /> },
|
||||
{ icon: 'billRecordLight', label: '使用记录', id: TabEnum.bill, Component: <BillTable /> },
|
||||
{ icon: 'payRecordLight', label: '充值记录', id: TabEnum.pay, Component: <PayRecordTable /> },
|
||||
{ icon: 'informLight', label: '通知', id: TabEnum.inform, Component: <InformTable /> },
|
||||
{ icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <></> }
|
||||
{
|
||||
icon: 'meLight',
|
||||
label: 'user.Personal Information',
|
||||
id: TabEnum.info,
|
||||
Component: <BillTable />
|
||||
},
|
||||
{
|
||||
icon: 'billRecordLight',
|
||||
label: 'user.Usage Record',
|
||||
id: TabEnum.bill,
|
||||
Component: <BillTable />
|
||||
},
|
||||
{
|
||||
icon: 'payRecordLight',
|
||||
label: 'user.Recharge Record',
|
||||
id: TabEnum.pay,
|
||||
Component: <PayRecordTable />
|
||||
},
|
||||
{
|
||||
icon: 'informLight',
|
||||
label: 'user.Notice',
|
||||
id: TabEnum.inform,
|
||||
Component: <InformTable />
|
||||
},
|
||||
{
|
||||
icon: 'loginoutLight',
|
||||
label: 'user.Sign Out',
|
||||
id: TabEnum.loginout,
|
||||
Component: () => <></>
|
||||
}
|
||||
]);
|
||||
|
||||
const { openConfirm, ConfirmModal } = useConfirm({
|
||||
|
@@ -13,7 +13,7 @@ import { TrainingModeEnum } from '@/constants/plugin';
|
||||
import FileSelect from './FileSelect';
|
||||
import { useRouter } from 'next/router';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
||||
import { readCsvContent } from '@/utils/file';
|
||||
import { fileDownload, readCsvContent } from '@/utils/file';
|
||||
|
||||
const fileExtension = '.csv';
|
||||
|
||||
@@ -137,6 +137,7 @@ const CsvImport = ({ kbId }: { kbId: string }) => {
|
||||
isLoading={selecting}
|
||||
tipText={'如果导入文件乱码,请将 CSV 转成 utf-8 编码格式'}
|
||||
py={emptyFiles ? '100px' : 5}
|
||||
isCsv
|
||||
/>
|
||||
|
||||
{!emptyFiles && (
|
||||
|
@@ -4,16 +4,26 @@ import { useLoading } from '@/hooks/useLoading';
|
||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { fileDownload } from '@/utils/file';
|
||||
|
||||
interface Props extends BoxProps {
|
||||
fileExtension: string;
|
||||
tipText?: string;
|
||||
onSelectFile: (files: File[]) => Promise<void>;
|
||||
isLoading?: boolean;
|
||||
isCsv?: boolean;
|
||||
}
|
||||
|
||||
const FileSelect = ({ fileExtension, onSelectFile, isLoading, tipText, ...props }: Props) => {
|
||||
const FileSelect = ({
|
||||
fileExtension,
|
||||
onSelectFile,
|
||||
isLoading,
|
||||
tipText,
|
||||
isCsv = false,
|
||||
...props
|
||||
}: Props) => {
|
||||
const { Loading: FileSelectLoading } = useLoading();
|
||||
const csvTemplate = `question,answer\n"什么是 laf","laf 是一个云函数开发平台……"\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
|
||||
|
||||
const { File, onOpen } = useSelectFile({
|
||||
fileType: fileExtension,
|
||||
@@ -47,6 +57,24 @@ const FileSelect = ({ fileExtension, onSelectFile, isLoading, tipText, ...props
|
||||
{tipText}
|
||||
</Box>
|
||||
)}
|
||||
{isCsv && (
|
||||
<Box
|
||||
my={3}
|
||||
cursor={'pointer'}
|
||||
textDecoration={'underline'}
|
||||
color={'myBlue.600'}
|
||||
fontSize={'12px'}
|
||||
onClick={() =>
|
||||
fileDownload({
|
||||
text: csvTemplate,
|
||||
type: 'text/csv',
|
||||
filename: 'template.csv'
|
||||
})
|
||||
}
|
||||
>
|
||||
点击下载csv模板
|
||||
</Box>
|
||||
)}
|
||||
<FileSelectLoading loading={isLoading} fixed={false} />
|
||||
<File onSelect={onSelectFile} />
|
||||
</Box>
|
||||
|
Reference in New Issue
Block a user