perf: 生成对话框时机

This commit is contained in:
archer
2023-04-23 14:07:17 +08:00
parent 9682c82713
commit c2c73ed23c
25 changed files with 299 additions and 327 deletions

View File

@@ -1,5 +1,5 @@
import { DataItem } from '@/service/mongo';
import { getOpenAIApi } from '@/service/utils/chat';
import { getOpenAIApi } from '@/service/utils/auth';
import { httpsAgent } from '@/service/utils/tools';
import { getOpenApiKey } from '../utils/openai';
import type { ChatCompletionRequestMessage } from 'openai';

View File

@@ -1,5 +1,5 @@
import { SplitData } from '@/service/mongo';
import { getOpenAIApi } from '@/service/utils/chat';
import { getOpenAIApi } from '@/service/utils/auth';
import { httpsAgent } from '@/service/utils/tools';
import { getOpenApiKey } from '../utils/openai';
import type { ChatCompletionRequestMessage } from 'openai';

View File

@@ -14,7 +14,7 @@ export const pushChatBill = async ({
isPay: boolean;
modelName: string;
userId: string;
chatId?: string;
chatId?: '' | string;
text: string;
}) => {
let billId;
@@ -42,7 +42,7 @@ export const pushChatBill = async ({
userId,
type: 'chat',
modelName,
chatId,
chatId: chatId ? chatId : undefined,
textLen: text.length,
tokenLen: tokens,
price

View File

@@ -53,11 +53,6 @@ const ModelSchema = new Schema({
}
},
service: {
company: {
type: String,
required: true,
enum: ['openai']
},
trainId: {
// 训练时需要的 ID 不能训练的模型没有这个值。
type: String,

70
src/service/utils/auth.ts Normal file
View File

@@ -0,0 +1,70 @@
import { Configuration, OpenAIApi } from 'openai';
import { Chat, Model } from '../mongo';
import type { ModelSchema } from '@/types/mongoSchema';
import { authToken } from './tools';
import { getOpenApiKey } from './openai';
import type { ChatItemType } from '@/types/chat';
export const getOpenAIApi = (apiKey: string) => {
const configuration = new Configuration({
apiKey
});
return new OpenAIApi(configuration, undefined);
};
// 模型使用权校验
export const authModel = async (modelId: string, userId: string) => {
// 获取 model 数据
const model = await Model.findById<ModelSchema>(modelId);
if (!model) {
return Promise.reject('模型不存在');
}
// 凭证校验
if (userId !== String(model.userId)) {
return Promise.reject('无权使用该模型');
}
return { model };
};
// 获取对话校验
export const authChat = async ({
modelId,
chatId,
authorization
}: {
modelId: string;
chatId: '' | string;
authorization?: string;
}) => {
const userId = await authToken(authorization);
// 获取 model 数据
const { model } = await authModel(modelId, userId);
// 聊天内容
let content: ChatItemType[] = [];
if (chatId) {
// 获取 chat 数据
const chat = await Chat.findById(chatId);
if (!chat) {
return Promise.reject('对话不存在');
}
// filter 掉被 deleted 的内容
content = chat.content.filter((item) => item.deleted !== true);
}
// 获取 user 的 apiKey
const { userApiKey, systemKey } = await getOpenApiKey(userId);
return {
userApiKey,
systemKey,
content,
userId,
model
};
};

View File

@@ -1,46 +0,0 @@
import { Configuration, OpenAIApi } from 'openai';
import { Chat } from '../mongo';
import type { ChatPopulate } from '@/types/mongoSchema';
import { authToken } from './tools';
import { getOpenApiKey } from './openai';
export const getOpenAIApi = (apiKey: string) => {
const configuration = new Configuration({
apiKey
});
return new OpenAIApi(configuration, undefined);
};
export const authChat = async (chatId: string, authorization?: string) => {
// 获取 chat 数据
const chat = await Chat.findById<ChatPopulate>(chatId).populate({
path: 'modelId',
options: {
strictPopulate: false
}
});
if (!chat || !chat.modelId || !chat.userId) {
return Promise.reject('模型不存在');
}
// 凭证校验
const userId = await authToken(authorization);
if (userId !== String(chat.userId._id)) {
return Promise.reject('无权使用该对话');
}
// 获取 user 的 apiKey
const { user, userApiKey, systemKey } = await getOpenApiKey(chat.userId as unknown as string);
// filter 掉被 deleted 的内容
chat.content = chat.content.filter((item) => item.deleted !== true);
return {
userApiKey,
systemKey,
chat,
userId: user._id
};
};

View File

@@ -1,7 +1,7 @@
import type { NextApiResponse } from 'next';
import type { PassThrough } from 'stream';
import { createParser, ParsedEvent, ReconnectInterval } from 'eventsource-parser';
import { getOpenAIApi } from '@/service/utils/chat';
import { getOpenAIApi } from '@/service/utils/auth';
import { httpsAgent } from './tools';
import { User } from '../models/user';
import { formatPrice } from '@/utils/user';