perf: 文件结构
This commit is contained in:
parent
caf31faf31
commit
6c4026ccef
@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
|||||||
import { createParser, ParsedEvent, ReconnectInterval } from 'eventsource-parser';
|
import { createParser, ParsedEvent, ReconnectInterval } from 'eventsource-parser';
|
||||||
import { connectToDatabase } from '@/service/mongo';
|
import { connectToDatabase } from '@/service/mongo';
|
||||||
import { getOpenAIApi, authChat } from '@/service/utils/chat';
|
import { getOpenAIApi, authChat } from '@/service/utils/chat';
|
||||||
import { httpsAgent } from '@/service/utils/tools';
|
import { httpsAgent, openaiChatFilter } from '@/service/utils/tools';
|
||||||
import { ChatCompletionRequestMessage, ChatCompletionRequestMessageRoleEnum } from 'openai';
|
import { ChatCompletionRequestMessage, ChatCompletionRequestMessageRoleEnum } from 'openai';
|
||||||
import { ChatItemType } from '@/types/chat';
|
import { ChatItemType } from '@/types/chat';
|
||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
@ -10,7 +10,6 @@ import type { ModelSchema } from '@/types/mongoSchema';
|
|||||||
import { PassThrough } from 'stream';
|
import { PassThrough } from 'stream';
|
||||||
import { modelList } from '@/constants/model';
|
import { modelList } from '@/constants/model';
|
||||||
import { pushChatBill } from '@/service/events/pushBill';
|
import { pushChatBill } from '@/service/events/pushBill';
|
||||||
import { openaiChatFilter } from '@/service/utils/tools';
|
|
||||||
|
|
||||||
/* 发送提示词 */
|
/* 发送提示词 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
import { Chat, Model, Training, connectToDatabase } from '@/service/mongo';
|
import { Chat, Model, Training, connectToDatabase } from '@/service/mongo';
|
||||||
import { authToken, getUserApiOpenai } from '@/service/utils/tools';
|
import { authToken } from '@/service/utils/tools';
|
||||||
|
import { getUserApiOpenai } from '@/service/utils/openai';
|
||||||
import { TrainingStatusEnum } from '@/constants/model';
|
import { TrainingStatusEnum } from '@/constants/model';
|
||||||
import { TrainingItemType } from '@/types/training';
|
import { TrainingItemType } from '@/types/training';
|
||||||
import { httpsAgent } from '@/service/utils/tools';
|
import { httpsAgent } from '@/service/utils/tools';
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
import { connectToDatabase, Model, Training } from '@/service/mongo';
|
import { connectToDatabase, Model, Training } from '@/service/mongo';
|
||||||
import { getOpenAIApi } from '@/service/utils/chat';
|
import { authToken } from '@/service/utils/tools';
|
||||||
import { authToken, getUserApiOpenai } from '@/service/utils/tools';
|
import { getUserApiOpenai } from '@/service/utils/openai';
|
||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
import { TrainingItemType } from '@/types/training';
|
import { TrainingItemType } from '@/types/training';
|
||||||
import { ModelStatusEnum, TrainingStatusEnum } from '@/constants/model';
|
import { ModelStatusEnum, TrainingStatusEnum } from '@/constants/model';
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import type { NextApiRequest, NextApiResponse } from 'next';
|
|||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
import { connectToDatabase, Model, Training } from '@/service/mongo';
|
import { connectToDatabase, Model, Training } from '@/service/mongo';
|
||||||
import formidable from 'formidable';
|
import formidable from 'formidable';
|
||||||
import { authToken, getUserApiOpenai } from '@/service/utils/tools';
|
import { authToken } from '@/service/utils/tools';
|
||||||
|
import { getUserApiOpenai } from '@/service/utils/openai';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import type { ModelSchema } from '@/types/mongoSchema';
|
import type { ModelSchema } from '@/types/mongoSchema';
|
||||||
|
|||||||
@ -4,8 +4,7 @@ import { jsonRes } from '@/service/response';
|
|||||||
import { connectToDatabase, Training, Model } from '@/service/mongo';
|
import { connectToDatabase, Training, Model } from '@/service/mongo';
|
||||||
import type { TrainingItemType } from '@/types/training';
|
import type { TrainingItemType } from '@/types/training';
|
||||||
import { TrainingStatusEnum, ModelStatusEnum } from '@/constants/model';
|
import { TrainingStatusEnum, ModelStatusEnum } from '@/constants/model';
|
||||||
import { getOpenAIApi } from '@/service/utils/chat';
|
import { getUserApiOpenai } from '@/service/utils/openai';
|
||||||
import { getUserApiOpenai } from '@/service/utils/tools';
|
|
||||||
import { OpenAiTuneStatusEnum } from '@/service/constants/training';
|
import { OpenAiTuneStatusEnum } from '@/service/constants/training';
|
||||||
import { sendTrainSucceed } from '@/service/utils/sendEmail';
|
import { sendTrainSucceed } from '@/service/utils/sendEmail';
|
||||||
import { httpsAgent } from '@/service/utils/tools';
|
import { httpsAgent } from '@/service/utils/tools';
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { DataItem } from '@/service/mongo';
|
import { DataItem } from '@/service/mongo';
|
||||||
import { getOpenAIApi } from '@/service/utils/chat';
|
import { getOpenAIApi } from '@/service/utils/chat';
|
||||||
import { httpsAgent, getOpenApiKey } from '@/service/utils/tools';
|
import { httpsAgent } from '@/service/utils/tools';
|
||||||
|
import { getOpenApiKey } from '../utils/openai';
|
||||||
import type { ChatCompletionRequestMessage } from 'openai';
|
import type { ChatCompletionRequestMessage } from 'openai';
|
||||||
import { DataItemSchema } from '@/types/mongoSchema';
|
import { DataItemSchema } from '@/types/mongoSchema';
|
||||||
import { ChatModelNameEnum } from '@/constants/model';
|
import { ChatModelNameEnum } from '@/constants/model';
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { SplitData } from '@/service/mongo';
|
import { SplitData } from '@/service/mongo';
|
||||||
import { getOpenAIApi } from '@/service/utils/chat';
|
import { getOpenAIApi } from '@/service/utils/chat';
|
||||||
import { httpsAgent, getOpenApiKey } from '@/service/utils/tools';
|
import { httpsAgent } from '@/service/utils/tools';
|
||||||
|
import { getOpenApiKey } from '../utils/openai';
|
||||||
import type { ChatCompletionRequestMessage } from 'openai';
|
import type { ChatCompletionRequestMessage } from 'openai';
|
||||||
import { ChatModelNameEnum } from '@/constants/model';
|
import { ChatModelNameEnum } from '@/constants/model';
|
||||||
import { pushSplitDataBill } from '@/service/events/pushBill';
|
import { pushSplitDataBill } from '@/service/events/pushBill';
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { Configuration, OpenAIApi } from 'openai';
|
import { Configuration, OpenAIApi } from 'openai';
|
||||||
import { Chat } from '../mongo';
|
import { Chat } from '../mongo';
|
||||||
import type { ChatPopulate } from '@/types/mongoSchema';
|
import type { ChatPopulate } from '@/types/mongoSchema';
|
||||||
import { authToken, getOpenApiKey } from './tools';
|
import { authToken } from './tools';
|
||||||
|
import { getOpenApiKey } from './openai';
|
||||||
|
|
||||||
export const getOpenAIApi = (apiKey: string) => {
|
export const getOpenAIApi = (apiKey: string) => {
|
||||||
const configuration = new Configuration({
|
const configuration = new Configuration({
|
||||||
|
|||||||
89
src/service/utils/openai.ts
Normal file
89
src/service/utils/openai.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
import { getOpenAIApi } from '@/service/utils/chat';
|
||||||
|
import { httpsAgent } from './tools';
|
||||||
|
import { User } from '../models/user';
|
||||||
|
import { formatPrice } from '@/utils/user';
|
||||||
|
|
||||||
|
/* 判断 apikey 是否还有余额 */
|
||||||
|
export const checkKeyGrant = async (apiKey: string) => {
|
||||||
|
const grant = await axios.get('https://api.openai.com/dashboard/billing/credit_grants', {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${apiKey}`
|
||||||
|
},
|
||||||
|
httpsAgent
|
||||||
|
});
|
||||||
|
if (grant.data?.total_available <= 0.2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 获取用户 api 的 openai 信息 */
|
||||||
|
export const getUserApiOpenai = async (userId: string) => {
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
|
||||||
|
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
||||||
|
|
||||||
|
if (!userApiKey) {
|
||||||
|
return Promise.reject('缺少ApiKey, 无法请求');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 余额校验
|
||||||
|
const hasGrant = await checkKeyGrant(userApiKey);
|
||||||
|
if (!hasGrant) {
|
||||||
|
return Promise.reject({
|
||||||
|
code: 501,
|
||||||
|
message: 'API 余额不足'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
openai: getOpenAIApi(userApiKey),
|
||||||
|
apiKey: userApiKey
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 获取 open api key,如果用户没有自己的key,就用平台的,用平台记得加账单 */
|
||||||
|
export const getOpenApiKey = async (userId: string, checkGrant = false) => {
|
||||||
|
const user = await User.findById(userId);
|
||||||
|
if (!user) {
|
||||||
|
return Promise.reject('找不到用户');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
||||||
|
|
||||||
|
// 有自己的key
|
||||||
|
if (userApiKey) {
|
||||||
|
// api 余额校验
|
||||||
|
if (checkGrant) {
|
||||||
|
const hasGrant = await checkKeyGrant(userApiKey);
|
||||||
|
if (!hasGrant) {
|
||||||
|
return Promise.reject({
|
||||||
|
code: 501,
|
||||||
|
message: 'API 余额不足'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
userApiKey,
|
||||||
|
systemKey: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 平台账号余额校验
|
||||||
|
if (formatPrice(user.balance) <= 0) {
|
||||||
|
return Promise.reject({
|
||||||
|
code: 501,
|
||||||
|
message: '账号余额不足'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
userApiKey: '',
|
||||||
|
systemKey: process.env.OPENAIKEY as string
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,12 +1,8 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import { User } from '../models/user';
|
|
||||||
import tunnel from 'tunnel';
|
import tunnel from 'tunnel';
|
||||||
import { formatPrice } from '@/utils/user';
|
|
||||||
import { ChatItemType } from '@/types/chat';
|
import { ChatItemType } from '@/types/chat';
|
||||||
import { encode } from 'gpt-token-utils';
|
import { encode } from 'gpt-token-utils';
|
||||||
import { getOpenAIApi } from '@/service/utils/chat';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
/* 密码加密 */
|
/* 密码加密 */
|
||||||
export const hashPassword = (psw: string) => {
|
export const hashPassword = (psw: string) => {
|
||||||
@ -56,90 +52,6 @@ export const httpsAgent =
|
|||||||
})
|
})
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
/* 判断 apikey 是否还有余额 */
|
|
||||||
export const checkKeyGrant = async (apiKey: string) => {
|
|
||||||
const grant = await axios.get('https://api.openai.com/dashboard/billing/credit_grants', {
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${apiKey}`
|
|
||||||
},
|
|
||||||
httpsAgent
|
|
||||||
});
|
|
||||||
if (grant.data?.total_available <= 0.2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 获取用户 api 的 openai 信息 */
|
|
||||||
export const getUserApiOpenai = async (userId: string) => {
|
|
||||||
const user = await User.findById(userId);
|
|
||||||
|
|
||||||
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
|
||||||
|
|
||||||
if (!userApiKey) {
|
|
||||||
return Promise.reject('缺少ApiKey, 无法请求');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 余额校验
|
|
||||||
const hasGrant = await checkKeyGrant(userApiKey);
|
|
||||||
if (!hasGrant) {
|
|
||||||
return Promise.reject({
|
|
||||||
code: 501,
|
|
||||||
message: 'API 余额不足'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
openai: getOpenAIApi(userApiKey),
|
|
||||||
apiKey: userApiKey
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 获取 open api key,如果用户没有自己的key,就用平台的,用平台记得加账单 */
|
|
||||||
export const getOpenApiKey = async (userId: string, checkGrant = false) => {
|
|
||||||
const user = await User.findById(userId);
|
|
||||||
if (!user) {
|
|
||||||
return Promise.reject('找不到用户');
|
|
||||||
}
|
|
||||||
|
|
||||||
const userApiKey = user?.accounts?.find((item: any) => item.type === 'openai')?.value;
|
|
||||||
|
|
||||||
// 有自己的key
|
|
||||||
if (userApiKey) {
|
|
||||||
// api 余额校验
|
|
||||||
if (checkGrant) {
|
|
||||||
const hasGrant = await checkKeyGrant(userApiKey);
|
|
||||||
if (!hasGrant) {
|
|
||||||
return Promise.reject({
|
|
||||||
code: 501,
|
|
||||||
message: 'API 余额不足'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
userApiKey,
|
|
||||||
systemKey: ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 平台账号余额校验
|
|
||||||
if (formatPrice(user.balance) <= 0) {
|
|
||||||
return Promise.reject({
|
|
||||||
code: 501,
|
|
||||||
message: '账号余额不足'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
user,
|
|
||||||
userApiKey: '',
|
|
||||||
systemKey: process.env.OPENAIKEY as string
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tokens 截断 */
|
/* tokens 截断 */
|
||||||
export const openaiChatFilter = (prompts: ChatItemType[], maxTokens: number) => {
|
export const openaiChatFilter = (prompts: ChatItemType[], maxTokens: number) => {
|
||||||
let res: ChatItemType[] = [];
|
let res: ChatItemType[] = [];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user