perf: bill

This commit is contained in:
archer
2023-07-17 13:35:30 +08:00
parent f546068354
commit 60a9dfb55f
10 changed files with 129 additions and 56 deletions

View File

@@ -8,6 +8,7 @@ import { ChatRoleEnum } from '@/constants/chat';
import { getOpenAIApi, axiosConfig } from '@/service/ai/openai';
import type { RecognizeIntentionAgentItemType } from '@/types/app';
import { countModelPrice, pushTaskBillListItem } from '@/service/events/pushBill';
import { getModel } from '@/service/utils/data';
export type Props = {
systemPrompt?: string;
@@ -115,7 +116,7 @@ export async function classifyQuestion({
billId,
moduleName: 'Recognize Intention',
amount: countModelPrice({ model: agentModel, tokens: totalTokens }),
model: agentModel,
model: getModel(agentModel)?.name,
tokenLen: totalTokens
});

View File

@@ -31,21 +31,10 @@ export type Response = { [SpecificInputEnum.answerText]: string; totalTokens: nu
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
let { model, temperature = 0, stream } = req.body as Props;
try {
// temperature adapt
const modelConstantsData = getChatModel(model);
if (!modelConstantsData) {
throw new Error('The chat model is undefined');
}
// FastGpt temperature range: 1~10
temperature = +(modelConstantsData.maxTemperature * (temperature / 10)).toFixed(2);
const response = await chatCompletion({
...req.body,
res,
model,
temperature
model
});
if (stream) {
@@ -88,6 +77,16 @@ export async function chatCompletion({
limitPrompt = '',
billId
}: Props & { res: NextApiResponse }): Promise<Response> {
// temperature adapt
const modelConstantsData = getChatModel(model);
if (!modelConstantsData) {
return Promise.reject('The chat model is undefined');
}
// FastGpt temperature range: 1~10
temperature = +(modelConstantsData.maxTemperature * (temperature / 10)).toFixed(2);
const messages: ChatItemType[] = [
...(quotePrompt
? [
@@ -189,7 +188,7 @@ export async function chatCompletion({
billId,
moduleName: 'AI Chat',
amount: countModelPrice({ model, tokens: totalTokens }),
model,
model: modelConstantsData.name,
tokenLen: totalTokens
});

View File

@@ -7,6 +7,7 @@ import { ChatRoleEnum } from '@/constants/chat';
import { modelToolMap } from '@/utils/plugin';
import { getVector } from '../../plugin/vector';
import { countModelPrice, pushTaskBillListItem } from '@/service/events/pushBill';
import { getModel } from '@/service/utils/data';
export type QuoteItemType = {
id: string;
@@ -95,7 +96,7 @@ export async function kbSearch({
billId,
moduleName: 'Vector Generate',
amount: countModelPrice({ model: vectorModel, tokens: tokenLen }),
model: vectorModel,
model: getModel(vectorModel)?.name,
tokenLen
})
]);

View File

@@ -9,7 +9,7 @@ import { UserUpdateParams } from '@/types/user';
/* 更新一些基本信息 */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
const { openaiKey, avatar } = req.body as UserUpdateParams;
const { avatar } = req.body as UserUpdateParams;
const { userId } = await authUser({ req, authToken: true });
@@ -20,8 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
_id: userId
},
{
...(avatar && { avatar }),
...(openaiKey !== undefined && { openaiKey })
...(avatar && { avatar })
}
);

View File

@@ -0,0 +1,83 @@
import React from 'react';
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
Flex,
Box,
Table,
Thead,
Tbody,
Tr,
Th,
Td,
TableContainer
} from '@chakra-ui/react';
import { UserBillType } from '@/types/user';
import dayjs from 'dayjs';
import { BillSourceMap } from '@/constants/user';
import { formatPrice } from '@/utils/user';
const BillDetail = ({ bill, onClose }: { bill: UserBillType; onClose: () => void }) => {
return (
<Modal isOpen={true} onClose={onClose} isCentered>
<ModalOverlay />
<ModalContent minW={'min(90vw,600px)'}>
<ModalHeader></ModalHeader>
<ModalBody>
<Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 80px'}>:</Box>
<Box>{bill.id}</Box>
</Flex>
<Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 80px'}>:</Box>
<Box>{dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss')}</Box>
</Flex>
<Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 80px'}>:</Box>
<Box>{bill.appName}</Box>
</Flex>
<Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 80px'}>:</Box>
<Box>{BillSourceMap[bill.source]}</Box>
</Flex>
<Flex alignItems={'center'} pb={4}>
<Box flex={'0 0 80px'}>:</Box>
<Box fontWeight={'bold'}>{bill.total}</Box>
</Flex>
<Box pb={4}>
<Box flex={'0 0 80px'} mb={1}>
</Box>
<TableContainer>
<Table>
<Thead>
<Tr>
<Th></Th>
<Th>AI模型</Th>
<Th>Token长度</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{bill.list.map((item, i) => (
<Tr key={i}>
<Td>{item.moduleName}</Td>
<Td>{item.model}</Td>
<Td>{item.tokenLen}</Td>
<Td>{formatPrice(item.amount)}</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Box>
</ModalBody>
</ModalContent>
</Modal>
);
};
export default BillDetail;

View File

@@ -1,5 +1,16 @@
import React, { useState } from 'react';
import { Table, Thead, Tbody, Tr, Th, Td, TableContainer, Flex, Box } from '@chakra-ui/react';
import {
Table,
Thead,
Tbody,
Tr,
Th,
Td,
TableContainer,
Flex,
Box,
Button
} from '@chakra-ui/react';
import { BillSourceMap } from '@/constants/user';
import { getUserBills } from '@/api/user';
import type { UserBillType } from '@/types/user';
@@ -9,6 +20,9 @@ import dayjs from 'dayjs';
import MyIcon from '@/components/Icon';
import DateRangePicker, { type DateRangeType } from '@/components/DateRangePicker';
import { addDays } from 'date-fns';
import dynamic from 'next/dynamic';
const BillDetail = dynamic(() => import('./BillDetail'));
const BillTable = () => {
const { Loading } = useLoading();
@@ -30,6 +44,8 @@ const BillTable = () => {
}
});
const [billDetail, setBillDetail] = useState<UserBillType>();
return (
<>
<TableContainer position={'relative'} minH={'100px'}>
@@ -39,7 +55,8 @@ const BillTable = () => {
<Th></Th>
<Th></Th>
<Th></Th>
<Th></Th>
<Th></Th>
<Th></Th>
</Tr>
</Thead>
<Tbody fontSize={'sm'}>
@@ -49,6 +66,11 @@ const BillTable = () => {
<Td>{BillSourceMap[item.source]}</Td>
<Td>{item.appName || '-'}</Td>
<Td>{item.total}</Td>
<Td>
<Button size={'sm'} variant={'base'} onClick={() => setBillDetail(item)}>
</Button>
</Td>
</Tr>
))}
</Tbody>
@@ -75,6 +97,7 @@ const BillTable = () => {
</Box>
</Flex>
<Loading loading={isLoading} fixed={false} />
{!!billDetail && <BillDetail bill={billDetail} onClose={() => setBillDetail(undefined)} />}
</>
);
};

View File

@@ -83,20 +83,10 @@ const NumberSetting = ({ tableType }: { tableType: `${TableEnum}` }) => {
async (data: UserUpdateParams) => {
setLoading(true);
try {
if (data.openaiKey) {
const text = await authOpenAiKey(data.openaiKey);
text &&
toast({
title: text,
status: 'warning'
});
}
await putUserInfo({
openaiKey: data.openaiKey,
avatar: data.avatar
});
updateUserInfo({
openaiKey: data.openaiKey,
avatar: data.avatar
});
reset(data);
@@ -193,25 +183,7 @@ const NumberSetting = ({ tableType }: { tableType: `${TableEnum}` }) => {
</Button>
</Flex>
<Box fontSize={'xs'} color={'blackAlpha.500'}>
openai openai
</Box>
</Box>
<Flex mt={6} alignItems={'center'}>
<Box flex={'0 0 85px'}>openaiKey:</Box>
<Input
{...register(`openaiKey`)}
maxW={'350px'}
placeholder={'openai账号。回车或失去焦点保存'}
size={'sm'}
onBlur={handleSubmit(onclickSave)}
onKeyDown={(e) => {
if (e.keyCode === 13) {
handleSubmit(onclickSave)();
}
}}
></Input>
</Flex>
</Card>
<Card px={6} py={4}>
<Box fontSize={'xl'} fontWeight={'bold'}>
@@ -220,7 +192,6 @@ const NumberSetting = ({ tableType }: { tableType: `${TableEnum}` }) => {
{[
{ label: '佣金比例', value: `${userInfo?.promotion.rate || 15}%` },
{ label: '已注册用户数', value: `${invitedAmount}` },
{ label: '累计佣金', value: `${historyAmount}` },
{ label: '可用佣金', value: `${residueAmount}` }
].map((item) => (
<Flex key={item.label} alignItems={'center'} mt={4} justifyContent={'space-between'}>

View File

@@ -42,10 +42,6 @@ const UserSchema = new Schema({
default: 15
}
},
openaiKey: {
type: String,
default: ''
},
limit: {
exportKbTime: {
// Every half hour

View File

@@ -4,7 +4,6 @@ export interface UserType {
_id: string;
username: string;
avatar: string;
openaiKey: string;
balance: number;
promotion: {
rate: number;
@@ -14,7 +13,6 @@ export interface UserType {
export interface UserUpdateParams {
balance?: number;
avatar?: string;
openaiKey?: string;
}
export interface UserBillType {
@@ -23,4 +21,5 @@ export interface UserBillType {
appName: string;
source: BillSchema['source'];
total: number;
list: BillSchema['list'];
}

View File

@@ -18,7 +18,8 @@ export const adaptBill = (bill: BillSchema): UserBillType => {
source: bill.source,
time: bill.time,
total: formatPrice(bill.total),
appName: bill.appName
appName: bill.appName,
list: bill.list
};
};