From 60a9dfb55f503488abb03a972336344343e95dfa Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Mon, 17 Jul 2023 13:35:30 +0800 Subject: [PATCH] perf: bill --- .../modules/agent/recognizeIntention.ts | 3 +- .../src/pages/api/openapi/modules/chat/gpt.ts | 25 +++--- .../pages/api/openapi/modules/kb/search.ts | 3 +- client/src/pages/api/user/update.ts | 5 +- .../pages/number/components/BillDetail.tsx | 83 +++++++++++++++++++ .../src/pages/number/components/BillTable.tsx | 27 +++++- client/src/pages/number/index.tsx | 29 ------- client/src/service/models/user.ts | 4 - client/src/types/user.d.ts | 3 +- client/src/utils/adapt.ts | 3 +- 10 files changed, 129 insertions(+), 56 deletions(-) create mode 100644 client/src/pages/number/components/BillDetail.tsx diff --git a/client/src/pages/api/openapi/modules/agent/recognizeIntention.ts b/client/src/pages/api/openapi/modules/agent/recognizeIntention.ts index 63196c2cf..84161e2c8 100644 --- a/client/src/pages/api/openapi/modules/agent/recognizeIntention.ts +++ b/client/src/pages/api/openapi/modules/agent/recognizeIntention.ts @@ -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 }); diff --git a/client/src/pages/api/openapi/modules/chat/gpt.ts b/client/src/pages/api/openapi/modules/chat/gpt.ts index b12e8ae4b..7bdc49a8d 100644 --- a/client/src/pages/api/openapi/modules/chat/gpt.ts +++ b/client/src/pages/api/openapi/modules/chat/gpt.ts @@ -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 { + // 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 }); diff --git a/client/src/pages/api/openapi/modules/kb/search.ts b/client/src/pages/api/openapi/modules/kb/search.ts index eee998c77..64a5809f0 100644 --- a/client/src/pages/api/openapi/modules/kb/search.ts +++ b/client/src/pages/api/openapi/modules/kb/search.ts @@ -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 }) ]); diff --git a/client/src/pages/api/user/update.ts b/client/src/pages/api/user/update.ts index 0490e68bc..397ee56ff 100644 --- a/client/src/pages/api/user/update.ts +++ b/client/src/pages/api/user/update.ts @@ -9,7 +9,7 @@ import { UserUpdateParams } from '@/types/user'; /* 更新一些基本信息 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { 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 }) } ); diff --git a/client/src/pages/number/components/BillDetail.tsx b/client/src/pages/number/components/BillDetail.tsx new file mode 100644 index 000000000..14d2ab9ae --- /dev/null +++ b/client/src/pages/number/components/BillDetail.tsx @@ -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 ( + + + + 账单详情 + + + 订单号: + {bill.id} + + + 生成时间: + {dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss')} + + + 应用名: + {bill.appName} + + + 来源: + {BillSourceMap[bill.source]} + + + 总金额: + {bill.total}元 + + + + 扣费模块 + + + + + + + + + + + + + {bill.list.map((item, i) => ( + + + + + + + ))} + +
模块名AI模型Token长度费用
{item.moduleName}{item.model}{item.tokenLen}{formatPrice(item.amount)}
+
+
+
+
+
+ ); +}; + +export default BillDetail; diff --git a/client/src/pages/number/components/BillTable.tsx b/client/src/pages/number/components/BillTable.tsx index 1d65150d3..5117d2ac9 100644 --- a/client/src/pages/number/components/BillTable.tsx +++ b/client/src/pages/number/components/BillTable.tsx @@ -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(); + return ( <> @@ -39,7 +55,8 @@ const BillTable = () => { 时间 来源 应用名 - 金额 + 总金额 + @@ -49,6 +66,11 @@ const BillTable = () => { {BillSourceMap[item.source]} {item.appName || '-'} {item.total}元 + + + ))} @@ -75,6 +97,7 @@ const BillTable = () => { + {!!billDetail && setBillDetail(undefined)} />} ); }; diff --git a/client/src/pages/number/index.tsx b/client/src/pages/number/index.tsx index a7cb51aab..87ddc745e 100644 --- a/client/src/pages/number/index.tsx +++ b/client/src/pages/number/index.tsx @@ -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}` }) => { 充值 - - 如果填写了自己的 openai 账号,网页上 openai 模型对话不会计费。 - - - openaiKey: - { - if (e.keyCode === 13) { - handleSubmit(onclickSave)(); - } - }} - > - @@ -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) => ( diff --git a/client/src/service/models/user.ts b/client/src/service/models/user.ts index c5b50ea6f..61db5f1e7 100644 --- a/client/src/service/models/user.ts +++ b/client/src/service/models/user.ts @@ -42,10 +42,6 @@ const UserSchema = new Schema({ default: 15 } }, - openaiKey: { - type: String, - default: '' - }, limit: { exportKbTime: { // Every half hour diff --git a/client/src/types/user.d.ts b/client/src/types/user.d.ts index ca0433938..db0670296 100644 --- a/client/src/types/user.d.ts +++ b/client/src/types/user.d.ts @@ -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']; } diff --git a/client/src/utils/adapt.ts b/client/src/utils/adapt.ts index d6dc4ff21..a85ea1562 100644 --- a/client/src/utils/adapt.ts +++ b/client/src/utils/adapt.ts @@ -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 }; };