import React, { useEffect, useMemo, useState } from 'react'; import { Box, Button, Flex, ModalFooter, ModalBody, Table, Thead, Tbody, Tr, Th, Td, TableContainer, useTheme, Link, Input, MenuList, MenuItem, MenuButton, Menu } from '@chakra-ui/react'; import { getOpenApiKeys, createAOpenApiKey, delOpenApiById, putOpenApiKey } from '@/api/support/openapi'; import type { EditApiKeyProps } from '@/api/support/openapi/index.d'; import { useQuery, useMutation } from '@tanstack/react-query'; import { useLoading } from '@/hooks/useLoading'; import dayjs from 'dayjs'; import { AddIcon, QuestionOutlineIcon } from '@chakra-ui/icons'; import { useCopyData } from '@/hooks/useCopyData'; import { feConfigs } from '@/store/static'; import { useTranslation } from 'react-i18next'; import MyIcon from '@/components/Icon'; import MyModal from '@/components/MyModal'; import { useForm } from 'react-hook-form'; import { useRequest } from '@/hooks/useRequest'; import MyTooltip from '@/components/MyTooltip'; type EditProps = EditApiKeyProps & { _id?: string }; const defaultEditData: EditProps = { name: '', limit: { credit: -1 } }; const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => { const { t } = useTranslation(); const { Loading } = useLoading(); const theme = useTheme(); const { copyData } = useCopyData(); const [baseUrl, setBaseUrl] = useState('https://fastgpt.run/api'); const [editData, setEditData] = useState(); const [apiKey, setApiKey] = useState(''); const { mutate: onclickRemove, isLoading: isDeleting } = useMutation({ mutationFn: async (id: string) => delOpenApiById(id), onSuccess() { refetch(); } }); const { data: apiKeys = [], isLoading: isGetting, refetch } = useQuery(['getOpenApiKeys', appId], () => getOpenApiKeys({ appId })); useEffect(() => { setBaseUrl(`${location.origin}/api`); }, []); return ( API 秘钥管理 查看文档 {tips} copyData(baseUrl, '已复制 API 地址')} > API地址 {baseUrl} {feConfigs?.isPlus && ( <> )} {apiKeys.map(({ _id, name, usage, limit, apiKey, createTime, lastUsedTime }) => ( {feConfigs?.isPlus && ( <> )} ))}
{t('Name')} Api Key 已用额度(¥)最大额度(¥) 过期时间创建时间 最后一次使用时间
{name} {apiKey} {usage}{limit?.credit && limit?.credit > -1 ? `${limit?.credit}` : '无限制'} {limit?.expiredTime ? dayjs(limit?.expiredTime).format('YYYY/MM/DD\nHH:mm') : '-'} {dayjs(createTime).format('YYYY/MM/DD\nHH:mm:ss')} {lastUsedTime ? dayjs(lastUsedTime).format('YYYY/MM/DD\nHH:mm:ss') : '没有使用过'} setEditData({ _id, name, limit, appId }) } py={[2, 3]} > {t('common.Edit')} onclickRemove(_id)} py={[2, 3]}> {t('common.Delete')}
{!!editData && ( setEditData(undefined)} onCreate={(id) => { setApiKey(id); refetch(); setEditData(undefined); }} onEdit={() => { refetch(); setEditData(undefined); }} /> )} setApiKey('')}> 新的 API 秘钥 请保管好你的秘钥,秘钥不会再次展示~ copyData(apiKey)} > {apiKey}
); }; export default React.memo(ApiKeyTable); // edit link modal function EditKeyModal({ defaultData, onClose, onCreate, onEdit }: { defaultData: EditProps; onClose: () => void; onCreate: (id: string) => void; onEdit: () => void; }) { const { t } = useTranslation(); const isEdit = useMemo(() => !!defaultData._id, [defaultData]); const { register, setValue, handleSubmit: submitShareChat } = useForm({ defaultValues: defaultData }); const { mutate: onclickCreate, isLoading: creating } = useRequest({ mutationFn: async (e: EditProps) => createAOpenApiKey(e), errorToast: '创建链接异常', onSuccess: onCreate }); const { mutate: onclickUpdate, isLoading: updating } = useRequest({ mutationFn: (e: EditProps) => { //@ts-ignore return putOpenApiKey(e); }, errorToast: '更新链接异常', onSuccess: onEdit }); return ( {t('Name')}: {feConfigs?.isPlus && ( <> {t('common.Max credit')}: {t('common.Expired Time')}: { setValue('limit.expiredTime', new Date(e.target.value)); }} /> )} ); }