From 984baf60f0859615480151b4f05e50730fb3fcfe Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Tue, 21 Mar 2023 23:47:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20share=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/chat.ts | 3 ++- src/api/fetch.ts | 4 +++- src/pages/api/chat/chatGpt.ts | 3 ++- src/pages/api/chat/generate.ts | 6 +++++- src/pages/api/chat/gpt3.ts | 3 ++- src/pages/chat/components/SlideBar.tsx | 4 ++-- src/service/models/bill.ts | 4 ++-- src/service/models/chat.ts | 4 ++++ src/service/utils/chat.ts | 10 ++++++++-- src/types/mongoSchema.d.ts | 3 ++- src/utils/adapt.ts | 2 +- 11 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/api/chat.ts b/src/api/chat.ts index 9c4d6b6aa..c324f0207 100644 --- a/src/api/chat.ts +++ b/src/api/chat.ts @@ -5,7 +5,8 @@ import type { InitChatResponse } from './response/chat'; /** * 获取一个聊天框的ID */ -export const getChatSiteId = (modelId: string) => GET(`/chat/generate?modelId=${modelId}`); +export const getChatSiteId = (modelId: string, isShare = false) => + GET(`/chat/generate?modelId=${modelId}&isShare=${isShare ? 'true' : 'false'}`); /** * 获取初始化聊天内容 diff --git a/src/api/fetch.ts b/src/api/fetch.ts index 23d6b3538..89ebba06a 100644 --- a/src/api/fetch.ts +++ b/src/api/fetch.ts @@ -1,3 +1,4 @@ +import { getToken } from '../utils/user'; interface StreamFetchProps { url: string; data: any; @@ -9,7 +10,8 @@ export const streamFetch = ({ url, data, onMessage }: StreamFetchProps) => const res = await fetch(url, { method: 'POST', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + Authorization: getToken() || '' }, body: JSON.stringify(data) }); diff --git a/src/pages/api/chat/chatGpt.ts b/src/pages/api/chat/chatGpt.ts index 9cdf33118..f041d5e36 100644 --- a/src/pages/api/chat/chatGpt.ts +++ b/src/pages/api/chat/chatGpt.ts @@ -17,6 +17,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) prompt: ChatItemType; chatId: string; }; + const { authorization } = req.headers; try { if (!chatId || !prompt) { @@ -25,7 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) await connectToDatabase(); - const { chat, userApiKey, systemKey, userId } = await authChat(chatId); + const { chat, userApiKey, systemKey, userId } = await authChat(chatId, authorization); const model: ModelSchema = chat.modelId; diff --git a/src/pages/api/chat/generate.ts b/src/pages/api/chat/generate.ts index c9e87695d..65aff4186 100644 --- a/src/pages/api/chat/generate.ts +++ b/src/pages/api/chat/generate.ts @@ -7,7 +7,10 @@ import type { ModelSchema } from '@/types/mongoSchema'; /* 获取我的模型 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { - const { modelId } = req.query; + const { modelId, isShare = 'false' } = req.query as { + modelId: string; + isShare?: 'true' | 'false'; + }; const { authorization } = req.headers; if (!authorization) { @@ -40,6 +43,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< expiredTime: Date.now() + model.security.expiredTime, loadAmount: model.security.maxLoadAmount, updateTime: Date.now(), + isShare: isShare === 'true', content: [] }); diff --git a/src/pages/api/chat/gpt3.ts b/src/pages/api/chat/gpt3.ts index 7d86abac2..a8e87a049 100644 --- a/src/pages/api/chat/gpt3.ts +++ b/src/pages/api/chat/gpt3.ts @@ -12,6 +12,7 @@ import { pushBill } from '@/service/events/bill'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { const { prompt, chatId } = req.body as { prompt: ChatItemType[]; chatId: string }; + const { authorization } = req.headers; if (!prompt || !chatId) { throw new Error('缺少参数'); @@ -19,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) await connectToDatabase(); - const { chat, userApiKey, systemKey, userId } = await authChat(chatId); + const { chat, userApiKey, systemKey, userId } = await authChat(chatId, authorization); const model = chat.modelId; diff --git a/src/pages/chat/components/SlideBar.tsx b/src/pages/chat/components/SlideBar.tsx index 7e40e3006..d29f5cd18 100644 --- a/src/pages/chat/components/SlideBar.tsx +++ b/src/pages/chat/components/SlideBar.tsx @@ -281,7 +281,7 @@ const SlideBar = ({ mr={3} onClick={async () => { copyData( - `${location.origin}/chat?chatId=${await getChatSiteId(modelId)}`, + `${location.origin}/chat?chatId=${await getChatSiteId(modelId, true)}`, '已复制分享链接' ); onCloseShare(); @@ -299,7 +299,7 @@ const SlideBar = ({ onClose(); }} > - 分享当前对话 + 分享聊天记录 diff --git a/src/service/models/bill.ts b/src/service/models/bill.ts index 51d00e6ba..8cbd26c26 100644 --- a/src/service/models/bill.ts +++ b/src/service/models/bill.ts @@ -12,8 +12,8 @@ const BillSchema = new Schema({ required: true }, time: { - type: Number, - default: () => Date.now() + type: Date, + default: () => new Date() }, textLen: { // 提示词+响应的总字数 diff --git a/src/service/models/chat.ts b/src/service/models/chat.ts index a0e5a5689..9a022282e 100644 --- a/src/service/models/chat.ts +++ b/src/service/models/chat.ts @@ -25,6 +25,10 @@ const ChatSchema = new Schema({ type: Number, required: true }, + isShare: { + type: Boolean, + default: false + }, content: { type: [ { diff --git a/src/service/utils/chat.ts b/src/service/utils/chat.ts index 890826000..e708e14ab 100644 --- a/src/service/utils/chat.ts +++ b/src/service/utils/chat.ts @@ -2,6 +2,7 @@ import { Configuration, OpenAIApi } from 'openai'; import { Chat } from '../mongo'; import type { ChatPopulate } from '@/types/mongoSchema'; import { formatPrice } from '@/utils/user'; +import { authToken } from './tools'; export const getOpenAIApi = (apiKey: string) => { const configuration = new Configuration({ @@ -11,7 +12,7 @@ export const getOpenAIApi = (apiKey: string) => { return new OpenAIApi(configuration, undefined); }; -export const authChat = async (chatId: string) => { +export const authChat = async (chatId: string, authorization?: string) => { // 获取 chat 数据 const chat = await Chat.findById(chatId) .populate({ @@ -36,12 +37,17 @@ export const authChat = async (chatId: string) => { return Promise.reject('聊天框已过期'); } + // 分享校验 + if (!chat.isShare) { + await authToken(authorization); + } + // 获取 user 的 apiKey const user = chat.userId; const userApiKey = user.accounts?.find((item: any) => item.type === 'openai')?.value; - if (!userApiKey && formatPrice(user.balance) <= -1) { + if (!userApiKey && formatPrice(user.balance) <= 0) { return Promise.reject('该账号余额不足'); } diff --git a/src/types/mongoSchema.d.ts b/src/types/mongoSchema.d.ts index d69dcbfa2..91e4fd64b 100644 --- a/src/types/mongoSchema.d.ts +++ b/src/types/mongoSchema.d.ts @@ -69,6 +69,7 @@ export interface ChatSchema { expiredTime: number; loadAmount: number; updateTime: number; + isShare: boolean; content: ChatItemType[]; } export interface ChatPopulate extends ChatSchema { @@ -80,7 +81,7 @@ export interface BillSchema { _id: string; userId: string; chatId: string; - time: number; + time: Date; textLen: number; price: number; } diff --git a/src/utils/adapt.ts b/src/utils/adapt.ts index f821ccea7..aa4b9acbb 100644 --- a/src/utils/adapt.ts +++ b/src/utils/adapt.ts @@ -8,7 +8,7 @@ export const adaptBill = (bill: BillSchema): UserBillType => { id: bill._id, userId: bill.userId, chatId: bill.chatId, - time: dayjs(bill.time).format('YYYY/MM/DD hh:mm:ss'), + time: dayjs(bill.time).format('YYYY/MM/DD HH:mm:ss'), textLen: bill.textLen, price: formatPrice(bill.price) };