mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
perf: 账号api结构
This commit is contained in:
@@ -9,7 +9,7 @@ import { UserUpdateParams } from '@/types/user';
|
|||||||
/* 更新一些基本信息 */
|
/* 更新一些基本信息 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
try {
|
try {
|
||||||
const { accounts } = req.body as UserUpdateParams;
|
const { openaiKey } = req.body as UserUpdateParams;
|
||||||
const { authorization } = req.headers;
|
const { authorization } = req.headers;
|
||||||
|
|
||||||
if (!authorization) {
|
if (!authorization) {
|
||||||
@@ -26,8 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
_id: userId
|
_id: userId
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 限定字段
|
openaiKey
|
||||||
...(accounts ? { accounts } : {})
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -1,22 +1,6 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import {
|
import { Card, Box, Flex, Button, Input } from '@chakra-ui/react';
|
||||||
Card,
|
import { useForm } from 'react-hook-form';
|
||||||
Box,
|
|
||||||
Flex,
|
|
||||||
Button,
|
|
||||||
Table,
|
|
||||||
Thead,
|
|
||||||
Tbody,
|
|
||||||
Tr,
|
|
||||||
Th,
|
|
||||||
Td,
|
|
||||||
TableContainer,
|
|
||||||
Select,
|
|
||||||
Input,
|
|
||||||
IconButton
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { DeleteIcon } from '@chakra-ui/icons';
|
|
||||||
import { useForm, useFieldArray } from 'react-hook-form';
|
|
||||||
import { UserUpdateParams } from '@/types/user';
|
import { UserUpdateParams } from '@/types/user';
|
||||||
import { putUserInfo } from '@/api/user';
|
import { putUserInfo } from '@/api/user';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
@@ -34,22 +18,15 @@ const PayModal = dynamic(() => import('./components/PayModal'));
|
|||||||
const NumberSetting = () => {
|
const NumberSetting = () => {
|
||||||
const { userInfo, updateUserInfo, initUserInfo } = useUserStore();
|
const { userInfo, updateUserInfo, initUserInfo } = useUserStore();
|
||||||
const { setLoading } = useGlobalStore();
|
const { setLoading } = useGlobalStore();
|
||||||
const { register, handleSubmit, control } = useForm<UserUpdateParams>({
|
const { register, handleSubmit } = useForm<UserUpdateParams>({
|
||||||
defaultValues: userInfo as UserType
|
defaultValues: userInfo as UserType
|
||||||
});
|
});
|
||||||
const [showPay, setShowPay] = useState(false);
|
const [showPay, setShowPay] = useState(false);
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const {
|
|
||||||
fields: accounts,
|
|
||||||
append: appendAccount,
|
|
||||||
remove: removeAccount
|
|
||||||
} = useFieldArray({
|
|
||||||
control,
|
|
||||||
name: 'accounts'
|
|
||||||
});
|
|
||||||
|
|
||||||
const onclickSave = useCallback(
|
const onclickSave = useCallback(
|
||||||
async (data: UserUpdateParams) => {
|
async (data: UserUpdateParams) => {
|
||||||
|
if (data.openaiKey === userInfo?.openaiKey) return;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
await putUserInfo(data);
|
await putUserInfo(data);
|
||||||
@@ -61,7 +38,7 @@ const NumberSetting = () => {
|
|||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
},
|
},
|
||||||
[setLoading, toast, updateUserInfo]
|
[setLoading, toast, updateUserInfo, userInfo?.openaiKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
useQuery(['init'], initUserInfo);
|
useQuery(['init'], initUserInfo);
|
||||||
@@ -73,12 +50,10 @@ const NumberSetting = () => {
|
|||||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||||
账号信息
|
账号信息
|
||||||
</Box>
|
</Box>
|
||||||
<Box mt={6}>
|
<Flex mt={6} alignItems={'center'}>
|
||||||
<Flex alignItems={'center'}>
|
<Box flex={'0 0 60px'}>邮箱:</Box>
|
||||||
<Box flex={'0 0 60px'}>邮箱:</Box>
|
<Box>{userInfo?.email}</Box>
|
||||||
<Box>{userInfo?.email}</Box>
|
</Flex>
|
||||||
</Flex>
|
|
||||||
</Box>
|
|
||||||
<Box mt={6}>
|
<Box mt={6}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 60px'}>余额:</Box>
|
<Box flex={'0 0 60px'}>余额:</Box>
|
||||||
@@ -93,76 +68,23 @@ const NumberSetting = () => {
|
|||||||
如果填写了自己的 openai 账号,将不会计费
|
如果填写了自己的 openai 账号,将不会计费
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
<Flex mt={6} alignItems={'center'}>
|
||||||
{/* 账号信息 */}
|
<Box flex={'0 0 85px'}>openaiKey:</Box>
|
||||||
<Card mt={6} px={6} py={4}>
|
<Input
|
||||||
<Flex mb={5} justifyContent={'space-between'}>
|
{...register(`openaiKey`)}
|
||||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
maxW={'300px'}
|
||||||
关联账号
|
placeholder={'openai账号。回车或失去焦点保存'}
|
||||||
</Box>
|
size={'sm'}
|
||||||
<Box>
|
onBlur={handleSubmit(onclickSave)}
|
||||||
{accounts.length === 0 && (
|
onKeyDown={(e) => {
|
||||||
<Button
|
if (e.keyCode === 13) {
|
||||||
mr={5}
|
handleSubmit(onclickSave)();
|
||||||
variant="outline"
|
}
|
||||||
onClick={() =>
|
}}
|
||||||
appendAccount({
|
></Input>
|
||||||
type: 'openai',
|
|
||||||
value: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
新增
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button onClick={handleSubmit(onclickSave)}>保存</Button>
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
<TableContainer>
|
|
||||||
<Table>
|
|
||||||
<Thead>
|
|
||||||
<Tr>
|
|
||||||
<Th>账号类型</Th>
|
|
||||||
<Th>值</Th>
|
|
||||||
<Th></Th>
|
|
||||||
</Tr>
|
|
||||||
</Thead>
|
|
||||||
<Tbody>
|
|
||||||
{accounts.map((item, i) => (
|
|
||||||
<Tr key={item.id}>
|
|
||||||
<Td minW={'200px'}>
|
|
||||||
<Select
|
|
||||||
{...register(`accounts.${i}.type`, {
|
|
||||||
required: '类型不能为空'
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<option value="openai">openai</option>
|
|
||||||
</Select>
|
|
||||||
</Td>
|
|
||||||
<Td minW={'200px'} whiteSpace="pre-wrap" wordBreak={'break-all'}>
|
|
||||||
<Input
|
|
||||||
{...register(`accounts.${i}.value`, {
|
|
||||||
required: '账号不能为空'
|
|
||||||
})}
|
|
||||||
></Input>
|
|
||||||
</Td>
|
|
||||||
<Td>
|
|
||||||
<IconButton
|
|
||||||
aria-label="删除账号"
|
|
||||||
icon={<DeleteIcon />}
|
|
||||||
colorScheme={'red'}
|
|
||||||
onClick={() => {
|
|
||||||
removeAccount(i);
|
|
||||||
handleSubmit(onclickSave)();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
|
||||||
))}
|
|
||||||
</Tbody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* 充值记录 */}
|
{/* 充值记录 */}
|
||||||
<PayRecordTable />
|
<PayRecordTable />
|
||||||
{/* 账单表 */}
|
{/* 账单表 */}
|
||||||
|
@@ -19,6 +19,10 @@ const UserSchema = new Schema({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0.5 * PRICE_SCALE
|
default: 0.5 * PRICE_SCALE
|
||||||
},
|
},
|
||||||
|
openaiKey: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
accounts: [
|
accounts: [
|
||||||
{
|
{
|
||||||
type: {
|
type: {
|
||||||
|
@@ -12,7 +12,7 @@ import { pushGenerateVectorBill } from '../events/pushBill';
|
|||||||
export const getUserApiOpenai = async (userId: string) => {
|
export const getUserApiOpenai = async (userId: string) => {
|
||||||
const user = await User.findById(userId);
|
const user = await User.findById(userId);
|
||||||
|
|
||||||
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
const userApiKey = user?.openaiKey;
|
||||||
|
|
||||||
if (!userApiKey) {
|
if (!userApiKey) {
|
||||||
return Promise.reject('缺少ApiKey, 无法请求');
|
return Promise.reject('缺少ApiKey, 无法请求');
|
||||||
@@ -35,7 +35,7 @@ export const getOpenApiKey = async (userId: string) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
const userApiKey = user?.openaiKey;
|
||||||
|
|
||||||
// 有自己的key
|
// 有自己的key
|
||||||
if (userApiKey) {
|
if (userApiKey) {
|
||||||
|
2
src/types/mongoSchema.d.ts
vendored
2
src/types/mongoSchema.d.ts
vendored
@@ -9,7 +9,7 @@ export interface UserModelSchema {
|
|||||||
email: string;
|
email: string;
|
||||||
password: string;
|
password: string;
|
||||||
balance: number;
|
balance: number;
|
||||||
accounts: { type: 'openai'; value: string }[];
|
openaiKey: string;
|
||||||
createTime: number;
|
createTime: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/types/user.d.ts
vendored
10
src/types/user.d.ts
vendored
@@ -6,19 +6,13 @@ export enum UserNumberEnum {
|
|||||||
export interface UserType {
|
export interface UserType {
|
||||||
_id: string;
|
_id: string;
|
||||||
email: string;
|
email: string;
|
||||||
accounts: {
|
openaiKey: string;
|
||||||
type: string;
|
|
||||||
value: string;
|
|
||||||
}[];
|
|
||||||
balance: number;
|
balance: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserUpdateParams {
|
export interface UserUpdateParams {
|
||||||
balance?: number;
|
balance?: number;
|
||||||
accounts?: {
|
openaiKey: string;
|
||||||
type: string;
|
|
||||||
value: string;
|
|
||||||
}[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserBillType {
|
export interface UserBillType {
|
||||||
|
Reference in New Issue
Block a user