mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
v4.5.1 (#417)
This commit is contained in:
120
packages/service/common/api/plusRequest.ts
Normal file
120
packages/service/common/api/plusRequest.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import axios, { Method, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
|
||||
interface ConfigType {
|
||||
headers?: { [key: string]: string };
|
||||
hold?: boolean;
|
||||
timeout?: number;
|
||||
}
|
||||
interface ResponseDataType {
|
||||
code: number;
|
||||
message: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求开始
|
||||
*/
|
||||
function requestStart(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
|
||||
if (config.headers) {
|
||||
config.headers.rootkey = process.env.ROOT_KEY;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求成功,检查请求头
|
||||
*/
|
||||
function responseSuccess(response: AxiosResponse<ResponseDataType>) {
|
||||
return response;
|
||||
}
|
||||
/**
|
||||
* 响应数据检查
|
||||
*/
|
||||
function checkRes(data: ResponseDataType) {
|
||||
if (data === undefined) {
|
||||
console.log('error->', data, 'data is empty');
|
||||
return Promise.reject('服务器异常');
|
||||
} else if (data?.code && (data.code < 200 || data.code >= 400)) {
|
||||
return Promise.reject(data);
|
||||
}
|
||||
return data.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应错误
|
||||
*/
|
||||
function responseError(err: any) {
|
||||
if (!err) {
|
||||
return Promise.reject({ message: '未知错误' });
|
||||
}
|
||||
if (typeof err === 'string') {
|
||||
return Promise.reject({ message: err });
|
||||
}
|
||||
|
||||
if (err?.response?.data) {
|
||||
return Promise.reject(err?.response?.data);
|
||||
}
|
||||
return Promise.reject(err);
|
||||
}
|
||||
|
||||
/* 创建请求实例 */
|
||||
const instance = axios.create({
|
||||
timeout: 60000, // 超时时间
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
/* 请求拦截 */
|
||||
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
|
||||
/* 响应拦截 */
|
||||
instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err));
|
||||
|
||||
export function request(url: string, data: any, config: ConfigType, method: Method): any {
|
||||
if (!global.systemEnv?.pluginBaseUrl) {
|
||||
return Promise.reject('商业版插件加载中...');
|
||||
}
|
||||
|
||||
/* 去空 */
|
||||
for (const key in data) {
|
||||
if (data[key] === null || data[key] === undefined) {
|
||||
delete data[key];
|
||||
}
|
||||
}
|
||||
|
||||
return instance
|
||||
.request({
|
||||
baseURL: global.systemEnv.pluginBaseUrl,
|
||||
url,
|
||||
method,
|
||||
data: ['POST', 'PUT'].includes(method) ? data : null,
|
||||
params: !['POST', 'PUT'].includes(method) ? data : null,
|
||||
...config // 用户自定义配置,可以覆盖前面的配置
|
||||
})
|
||||
.then((res) => checkRes(res.data))
|
||||
.catch((err) => responseError(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* api请求方式
|
||||
* @param {String} url
|
||||
* @param {Any} params
|
||||
* @param {Object} config
|
||||
* @returns
|
||||
*/
|
||||
export function GET<T>(url: string, params = {}, config: ConfigType = {}): Promise<T> {
|
||||
return request(url, params, config, 'GET');
|
||||
}
|
||||
|
||||
export function POST<T>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
||||
return request(url, data, config, 'POST');
|
||||
}
|
||||
|
||||
export function PUT<T>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
||||
return request(url, data, config, 'PUT');
|
||||
}
|
||||
|
||||
export function DELETE<T>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
|
||||
return request(url, data, config, 'DELETE');
|
||||
}
|
19
packages/service/common/middle/cors.ts
Normal file
19
packages/service/common/middle/cors.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { NextApiResponse, NextApiHandler, NextApiRequest } from 'next';
|
||||
import NextCors from 'nextjs-cors';
|
||||
|
||||
export function withNextCors(handler: NextApiHandler): NextApiHandler {
|
||||
return async function nextApiHandlerWrappedWithNextCors(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const methods = ['GET', 'eHEAD', 'PUT', 'PATCH', 'POST', 'DELETE'];
|
||||
const origin = req.headers.origin;
|
||||
await NextCors(req, res, {
|
||||
methods,
|
||||
origin: origin,
|
||||
optionsSuccessStatus: 200
|
||||
});
|
||||
|
||||
return handler(req, res);
|
||||
};
|
||||
}
|
13
packages/service/common/middle/httpAgent.ts
Normal file
13
packages/service/common/middle/httpAgent.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import tunnel from 'tunnel';
|
||||
|
||||
export function initHttpAgent() {
|
||||
// proxy obj
|
||||
if (process.env.AXIOS_PROXY_HOST && process.env.AXIOS_PROXY_PORT) {
|
||||
global.httpsAgent = tunnel.httpsOverHttp({
|
||||
proxy: {
|
||||
host: process.env.AXIOS_PROXY_HOST,
|
||||
port: +process.env.AXIOS_PROXY_PORT
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
6
packages/service/common/mongo/index.ts
Normal file
6
packages/service/common/mongo/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
export default mongoose;
|
||||
export * from 'mongoose';
|
||||
|
||||
export const connectionMongo = global.mongodb || mongoose;
|
76
packages/service/common/mongo/init.ts
Normal file
76
packages/service/common/mongo/init.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import mongoose from './index';
|
||||
import 'winston-mongodb';
|
||||
import { createLogger, format, transports } from 'winston';
|
||||
|
||||
/**
|
||||
* connect MongoDB and init data
|
||||
*/
|
||||
export async function connectMongo({
|
||||
beforeHook,
|
||||
afterHook
|
||||
}: {
|
||||
beforeHook?: () => any;
|
||||
afterHook?: () => any;
|
||||
}): Promise<void> {
|
||||
if (global.mongodb) {
|
||||
return;
|
||||
}
|
||||
global.mongodb = mongoose;
|
||||
|
||||
beforeHook && (await beforeHook());
|
||||
|
||||
// logger
|
||||
initLogger();
|
||||
|
||||
console.log('mongo start connect');
|
||||
try {
|
||||
mongoose.set('strictQuery', true);
|
||||
await mongoose.connect(process.env.MONGODB_URI as string, {
|
||||
bufferCommands: true,
|
||||
maxConnecting: Number(process.env.DB_MAX_LINK || 5),
|
||||
maxPoolSize: Number(process.env.DB_MAX_LINK || 5),
|
||||
minPoolSize: 2,
|
||||
connectTimeoutMS: 20000,
|
||||
waitQueueTimeoutMS: 20000
|
||||
});
|
||||
|
||||
console.log('mongo connected');
|
||||
|
||||
afterHook && (await afterHook());
|
||||
} catch (error) {
|
||||
console.log('error->', 'mongo connect error', error);
|
||||
global.mongodb = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function initLogger() {
|
||||
global.logger = createLogger({
|
||||
transports: [
|
||||
new transports.MongoDB({
|
||||
db: process.env.MONGODB_URI as string,
|
||||
collection: 'server_logs',
|
||||
options: {
|
||||
useUnifiedTopology: true
|
||||
},
|
||||
cappedSize: 500000000,
|
||||
tryReconnect: true,
|
||||
metaKey: 'meta',
|
||||
format: format.combine(format.timestamp(), format.json())
|
||||
}),
|
||||
new transports.Console({
|
||||
format: format.combine(
|
||||
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
||||
format.printf((info) => {
|
||||
if (info.level === 'error') {
|
||||
console.log(info.meta);
|
||||
return `[${info.level.toLocaleUpperCase()}]: ${[info.timestamp]}: ${info.message}`;
|
||||
}
|
||||
return `[${info.level.toLocaleUpperCase()}]: ${[info.timestamp]}: ${info.message}${
|
||||
info.meta ? `: ${JSON.stringify(info.meta)}` : ''
|
||||
}`;
|
||||
})
|
||||
)
|
||||
})
|
||||
]
|
||||
});
|
||||
}
|
39
packages/service/common/mongo/sessionRun.ts
Normal file
39
packages/service/common/mongo/sessionRun.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import mongoose from './index';
|
||||
|
||||
export class MongoSession {
|
||||
tasks: (() => Promise<any>)[] = [];
|
||||
session: mongoose.mongo.ClientSession | null = null;
|
||||
opts: {
|
||||
session: mongoose.mongo.ClientSession;
|
||||
new: boolean;
|
||||
} | null = null;
|
||||
|
||||
constructor() {}
|
||||
async init() {
|
||||
this.session = await mongoose.startSession();
|
||||
this.opts = { session: this.session, new: true };
|
||||
}
|
||||
push(
|
||||
tasks: ((opts: {
|
||||
session: mongoose.mongo.ClientSession;
|
||||
new: boolean;
|
||||
}) => () => Promise<any>)[] = []
|
||||
) {
|
||||
if (!this.opts) return;
|
||||
// this.tasks = this.tasks.concat(tasks.map((item) => item(this.opts)));
|
||||
}
|
||||
async run() {
|
||||
if (!this.session || !this.opts) return;
|
||||
try {
|
||||
this.session.startTransaction();
|
||||
|
||||
const opts = { session: this.session, new: true };
|
||||
|
||||
await this.session.commitTransaction();
|
||||
} catch (error) {
|
||||
await this.session.abortTransaction();
|
||||
console.error(error);
|
||||
}
|
||||
this.session.endSession();
|
||||
}
|
||||
}
|
7
packages/service/common/mongo/type.d.ts
vendored
Normal file
7
packages/service/common/mongo/type.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { Mongoose } from 'mongoose';
|
||||
import type { Logger } from 'winston';
|
||||
|
||||
declare global {
|
||||
var mongodb: Mongoose | undefined;
|
||||
var logger: Logger;
|
||||
}
|
39
packages/service/common/response/index.ts
Normal file
39
packages/service/common/response/index.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { NextApiResponse } from 'next';
|
||||
|
||||
export function responseWriteController({
|
||||
res,
|
||||
readStream
|
||||
}: {
|
||||
res: NextApiResponse;
|
||||
readStream: any;
|
||||
}) {
|
||||
res.on('drain', () => {
|
||||
readStream.resume();
|
||||
});
|
||||
|
||||
return (text: string | Buffer) => {
|
||||
const writeResult = res.write(text);
|
||||
if (!writeResult) {
|
||||
readStream?.pause();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function responseWrite({
|
||||
res,
|
||||
write,
|
||||
event,
|
||||
data
|
||||
}: {
|
||||
res?: NextApiResponse;
|
||||
write?: (text: string) => void;
|
||||
event?: string;
|
||||
data: string;
|
||||
}) {
|
||||
const Write = write || res?.write;
|
||||
|
||||
if (!Write) return;
|
||||
|
||||
event && Write(`event: ${event}\n`);
|
||||
Write(`data: ${data}\n\n`);
|
||||
}
|
Reference in New Issue
Block a user