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 '@/web/support/openapi/api'; import type { EditApiKeyProps } from '@/global/support/openapi/api.d'; import { useQuery, useMutation } from '@tanstack/react-query'; import { useLoading } from '@/web/common/hooks/useLoading'; import dayjs from 'dayjs'; import { AddIcon, QuestionOutlineIcon } from '@chakra-ui/icons'; import { useCopyData } from '@/web/common/hooks/useCopyData'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useTranslation } from 'next-i18next'; import MyIcon from '@fastgpt/web/components/common/Icon'; import MyModal from '@/components/MyModal'; import { useForm } from 'react-hook-form'; import { useRequest } from '@/web/common/hooks/useRequest'; import MyTooltip from '@/components/MyTooltip'; import { getDocPath } from '@/web/common/system/doc'; import MyMenu from '@/components/MyMenu'; 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 { feConfigs } = useSystemStore(); const [baseUrl, setBaseUrl] = useState('https://fastgpt.in/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(feConfigs?.customApiDomain || `${location.origin}/api`); }, []); return ( {t('support.openapi.Api manager')} {feConfigs?.docUrl && ( {t('common.Read document')} )} {tips} copyData(baseUrl, t('support.openapi.Copy success'))} > {t('support.openapi.Api baseurl')} {baseUrl} {feConfigs?.isPlus && ( <> )} {apiKeys.map(({ _id, name, usage, limit, apiKey, createTime, lastUsedTime }) => ( {feConfigs?.isPlus && ( <> )} ))}
{t('Name')} Api Key {t('support.openapi.Usage')}{t('support.openapi.Max usage')} {t('common.Expired Time')}{t('common.Create Time')} {t('common.Last use time')}
{name} {apiKey} {usage} {limit?.credit && limit?.credit > -1 ? `${limit?.credit}` : t('common.Unlimited')} {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') : t('common.Un used')} } menuList={[ { label: t('common.Edit'), icon: 'edit', onClick: () => setEditData({ _id, name, limit, appId }) }, { label: t('common.Delete'), icon: 'delete', onClick: () => onclickRemove(_id) } ]} />
{!!editData && ( setEditData(undefined)} onCreate={(id) => { setApiKey(id); refetch(); setEditData(undefined); }} onEdit={() => { refetch(); setEditData(undefined); }} /> )} {t('support.openapi.New api key')} {t('support.openapi.New api key tip')} } onClose={() => setApiKey('')} > 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 { feConfigs } = useSystemStore(); 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)); }} /> )} ); }