mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-28 09:03:53 +00:00
feat: openapi crd
This commit is contained in:
@@ -3,14 +3,14 @@ import { UserOpenApiKey } from '@/types/openapi';
|
|||||||
/**
|
/**
|
||||||
* crete a api key
|
* crete a api key
|
||||||
*/
|
*/
|
||||||
export const createAApiKey = () => POST('/openapi/postKey');
|
export const createAOpenApiKey = () => POST<string>('/openapi/postKey');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get api keys
|
* get api keys
|
||||||
*/
|
*/
|
||||||
export const getApiKeys = () => GET<UserOpenApiKey[]>('/openapi/getKeys');
|
export const getOpenApiKeys = () => GET<UserOpenApiKey[]>('/openapi/getKeys');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete api by id
|
* delete api by id
|
||||||
*/
|
*/
|
||||||
export const delApiById = (id: string) => DELETE(`/openapi/delKet?id=${id}`);
|
export const delOpenApiById = (id: string) => DELETE(`/openapi/delKet?id=${id}`);
|
||||||
|
@@ -17,16 +17,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
|
|
||||||
await connectToDatabase();
|
await connectToDatabase();
|
||||||
|
|
||||||
const findResponse = await OpenApi.find({ userId });
|
const findResponse = await OpenApi.find({ userId }).sort({ _id: -1 });
|
||||||
|
|
||||||
// jus save four data
|
// jus save four data
|
||||||
const apiKeys = findResponse.map<UserOpenApiKey>((item) => {
|
const apiKeys = findResponse.map<UserOpenApiKey>(
|
||||||
const key = item.apiKey;
|
({ _id, apiKey, createTime, lastUsedTime }) => {
|
||||||
return {
|
return {
|
||||||
id: item._id,
|
id: _id,
|
||||||
apiKey: `${key.substring(0, 2)}******${key.substring(key.length - 2)}`
|
apiKey: `${apiKey.substring(0, 2)}******${apiKey.substring(apiKey.length - 2)}`,
|
||||||
|
createTime,
|
||||||
|
lastUsedTime
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
jsonRes(res, {
|
jsonRes(res, {
|
||||||
data: apiKeys
|
data: apiKeys
|
||||||
|
@@ -4,7 +4,7 @@ import { jsonRes } from '@/service/response';
|
|||||||
import { connectToDatabase, OpenApi } from '@/service/mongo';
|
import { connectToDatabase, OpenApi } from '@/service/mongo';
|
||||||
import { authToken } from '@/service/utils/tools';
|
import { authToken } from '@/service/utils/tools';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890-', 20);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890');
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
try {
|
try {
|
||||||
|
@@ -1,11 +1,120 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Card, Box, Flex, Button, Input } from '@chakra-ui/react';
|
import {
|
||||||
|
Card,
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Table,
|
||||||
|
Thead,
|
||||||
|
Tbody,
|
||||||
|
Tr,
|
||||||
|
Th,
|
||||||
|
Td,
|
||||||
|
TableContainer,
|
||||||
|
IconButton,
|
||||||
|
Modal,
|
||||||
|
ModalOverlay,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalBody
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { getOpenApiKeys, createAOpenApiKey, delOpenApiById } from '@/api/openapi';
|
||||||
|
import { useQuery, useMutation } from '@tanstack/react-query';
|
||||||
|
import { useLoading } from '@/hooks/useLoading';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { DeleteIcon } from '@chakra-ui/icons';
|
||||||
|
import { useCopyData } from '@/utils/tools';
|
||||||
|
|
||||||
const OpenApi = () => {
|
const OpenApi = () => {
|
||||||
|
const { Loading } = useLoading();
|
||||||
|
const {
|
||||||
|
data: apiKeys = [],
|
||||||
|
isLoading: isGetting,
|
||||||
|
refetch
|
||||||
|
} = useQuery([getOpenApiKeys], getOpenApiKeys);
|
||||||
|
const [apiKey, setApiKey] = useState('');
|
||||||
|
const { copyData } = useCopyData();
|
||||||
|
|
||||||
|
const { mutate: onclickCreateApiKey, isLoading: isCreating } = useMutation({
|
||||||
|
mutationFn: () => createAOpenApiKey(),
|
||||||
|
onSuccess(res) {
|
||||||
|
setApiKey(res);
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { mutate: onclickRemove, isLoading: isDeleting } = useMutation({
|
||||||
|
mutationFn: async (id: string) => delOpenApiById(id),
|
||||||
|
onSuccess() {
|
||||||
|
refetch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card px={6} py={4}>
|
<>
|
||||||
ss
|
<Card px={6} py={4} position={'relative'}>
|
||||||
|
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||||
|
Open Api Key
|
||||||
|
</Box>
|
||||||
|
<Box fontSize={'sm'} mt={2}>
|
||||||
|
请注意保管你的 key,不要泄露!
|
||||||
|
</Box>
|
||||||
|
<TableContainer mt={2} position={'relative'}>
|
||||||
|
<Table>
|
||||||
|
<Thead>
|
||||||
|
<Tr>
|
||||||
|
<Th>Api Key</Th>
|
||||||
|
<Th>创建时间</Th>
|
||||||
|
<Th>最后一次使用时间</Th>
|
||||||
|
<Th />
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody fontSize={'sm'}>
|
||||||
|
{apiKeys.map(({ id, apiKey, createTime, lastUsedTime }) => (
|
||||||
|
<Tr key={id}>
|
||||||
|
<Td>{apiKey}</Td>
|
||||||
|
<Td>{dayjs(createTime).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
||||||
|
<Td>{dayjs(lastUsedTime).format('YYYY/MM/DD HH:mm:ss')}</Td>
|
||||||
|
<Td>
|
||||||
|
<IconButton
|
||||||
|
icon={<DeleteIcon />}
|
||||||
|
size={'xs'}
|
||||||
|
aria-label={'delete'}
|
||||||
|
variant={'outline'}
|
||||||
|
colorScheme={'gray'}
|
||||||
|
onClick={() => onclickRemove(id)}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
<Button
|
||||||
|
mt={5}
|
||||||
|
isLoading={isCreating}
|
||||||
|
isDisabled={apiKeys.length >= 5}
|
||||||
|
title={apiKeys.length >= 5 ? '最多五组 Api Key' : ''}
|
||||||
|
onClick={() => onclickCreateApiKey()}
|
||||||
|
>
|
||||||
|
添加新的 Api Key
|
||||||
|
</Button>
|
||||||
|
</TableContainer>
|
||||||
|
<Loading loading={isGetting || isDeleting} fixed={false} />
|
||||||
</Card>
|
</Card>
|
||||||
|
<Modal isOpen={!!apiKey} onClose={() => setApiKey('')}>
|
||||||
|
<ModalOverlay />
|
||||||
|
<ModalContent>
|
||||||
|
<ModalHeader>Api Key</ModalHeader>
|
||||||
|
<ModalCloseButton />
|
||||||
|
<ModalBody mb={5}>
|
||||||
|
请保管好你的Api Key
|
||||||
|
<Box userSelect={'all'} onClick={() => copyData(apiKey)}>
|
||||||
|
{apiKey}
|
||||||
|
</Box>
|
||||||
|
</ModalBody>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2
src/types/openapi.d.ts
vendored
2
src/types/openapi.d.ts
vendored
@@ -1,4 +1,6 @@
|
|||||||
export interface UserOpenApiKey {
|
export interface UserOpenApiKey {
|
||||||
id: string;
|
id: string;
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
|
createTime: Date;
|
||||||
|
lastUsedTime: Date;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user