New license (#4809)

* feat: new-license

* perf: volumn watch

* Set use client
This commit is contained in:
Archer
2025-05-14 13:55:09 +08:00
committed by GitHub
parent bd93f28d6f
commit cba8f773fe
34 changed files with 227 additions and 93 deletions

View File

@@ -2,13 +2,28 @@ import { type ErrType } from '../errorCode';
import { i18nT } from '../../../../web/i18n/utils';
/* dataset: 509000 */
export enum SystemErrEnum {
communityVersionNumLimit = 'communityVersionNumLimit'
communityVersionNumLimit = 'communityVersionNumLimit',
licenseAppAmountLimit = 'licenseAppAmountLimit',
licenseDatasetAmountLimit = 'licenseDatasetAmountLimit',
licenseUserAmountLimit = 'licenseUserAmountLimit'
}
const systemErr = [
{
statusText: SystemErrEnum.communityVersionNumLimit,
message: i18nT('common:code_error.system_error.community_version_num_limit')
},
{
statusText: SystemErrEnum.licenseAppAmountLimit,
message: i18nT('common:code_error.system_error.license_app_amount_limit')
},
{
statusText: SystemErrEnum.licenseDatasetAmountLimit,
message: i18nT('common:code_error.system_error.license_dataset_amount_limit')
},
{
statusText: SystemErrEnum.licenseUserAmountLimit,
message: i18nT('common:code_error.system_error.license_user_amount_limit')
}
];

View File

@@ -70,6 +70,9 @@ export type FastGPTFeConfigsType = {
show_publish_dingtalk?: boolean;
show_publish_offiaccount?: boolean;
show_dataset_enhance?: boolean;
show_batch_eval?: boolean;
concatMd?: string;
docUrl?: string;
openAPIDocUrl?: string;
@@ -142,3 +145,21 @@ export type customPdfParseType = {
doc2xKey?: string;
price?: number;
};
export type LicenseDataType = {
startTime: string;
expiredTime: string;
company: string;
description?: string; // 描述
hosts?: string[]; // 管理端有效域名
maxUsers?: number; // 最大用户数,不填默认不上限
maxApps?: number; // 最大应用数,不填默认不上限
maxDatasets?: number; // 最大数据集数,不填默认不上限
functions: {
sso: boolean;
pay: boolean;
customTemplates: boolean;
datasetEnhance: boolean;
batchEval: boolean;
};
};

View File

@@ -2,26 +2,44 @@ import { SystemConfigsTypeEnum } from '@fastgpt/global/common/system/config/cons
import { MongoSystemConfigs } from './schema';
import { type FastGPTConfigFileType } from '@fastgpt/global/common/system/types';
import { FastGPTProUrl } from '../constants';
import { type LicenseDataType } from '@fastgpt/global/common/system/types';
export const getFastGPTConfigFromDB = async () => {
export const getFastGPTConfigFromDB = async (): Promise<{
fastgptConfig: FastGPTConfigFileType;
licenseData?: LicenseDataType;
}> => {
if (!FastGPTProUrl) {
return {
config: {} as FastGPTConfigFileType
fastgptConfig: {} as FastGPTConfigFileType
};
}
const res = await MongoSystemConfigs.findOne({
type: SystemConfigsTypeEnum.fastgpt
}).sort({
createTime: -1
});
const [fastgptConfig, licenseConfig] = await Promise.all([
MongoSystemConfigs.findOne({
type: SystemConfigsTypeEnum.fastgpt
}).sort({
createTime: -1
}),
MongoSystemConfigs.findOne({
type: SystemConfigsTypeEnum.license
}).sort({
createTime: -1
})
]);
const config = res?.value || {};
const config = fastgptConfig?.value || {};
const licenseData = licenseConfig?.value?.data as LicenseDataType | undefined;
const fastgptConfigTime = fastgptConfig?.createTime.getTime().toString();
const licenseConfigTime = licenseConfig?.createTime.getTime().toString();
// 利用配置文件的创建时间(更新时间)来做缓存,如果前端命中缓存,则不需要再返回配置文件
global.systemInitBufferId = res ? res.createTime.getTime().toString() : undefined;
global.systemInitBufferId = fastgptConfigTime
? `${fastgptConfigTime}-${licenseConfigTime}`
: undefined;
return {
config: config as FastGPTConfigFileType
fastgptConfig: config as FastGPTConfigFileType,
licenseData
};
};

View File

@@ -119,6 +119,7 @@ const AppSchema = new Schema({
defaultPermission: Number
});
AppSchema.index({ type: 1 });
AppSchema.index({ teamId: 1, updateTime: -1 });
AppSchema.index({ teamId: 1, type: 1 });
AppSchema.index(

View File

@@ -123,6 +123,7 @@ const DatasetSchema = new Schema({
try {
DatasetSchema.index({ teamId: 1 });
DatasetSchema.index({ type: 1 });
} catch (error) {
console.log(error);
}

View File

@@ -54,23 +54,50 @@ export const checkTeamDatasetLimit = async (teamId: string) => {
})
]);
// User check
if (standardConstants && datasetCount >= standardConstants.maxDatasetAmount) {
return Promise.reject(TeamErrEnum.datasetAmountNotEnough);
}
// System check
if (global?.licenseData?.maxDatasets && typeof global?.licenseData?.maxDatasets === 'number') {
const totalDatasets = await MongoDataset.countDocuments({
type: { $ne: DatasetTypeEnum.folder }
});
if (totalDatasets >= global.licenseData.maxDatasets) {
return Promise.reject(SystemErrEnum.licenseDatasetAmountLimit);
}
}
// Open source check
if (!global.feConfigs.isPlus && datasetCount >= 30) {
return Promise.reject(SystemErrEnum.communityVersionNumLimit);
}
};
export const checkTeamAppLimit = async (teamId: string, amount = 1) => {
const [{ standardConstants }, appCount] = await Promise.all([
getTeamStandPlan({ teamId }),
MongoApp.countDocuments({
teamId,
type: { $in: [AppTypeEnum.simple, AppTypeEnum.workflow, AppTypeEnum.plugin] }
type: {
$in: [AppTypeEnum.simple, AppTypeEnum.workflow, AppTypeEnum.plugin, AppTypeEnum.tool]
}
})
]);
if (standardConstants && appCount + amount >= standardConstants.maxAppAmount) {
return Promise.reject(TeamErrEnum.appAmountNotEnough);
}
// System check
if (global?.licenseData?.maxApps && typeof global?.licenseData?.maxApps === 'number') {
const totalApps = await MongoApp.countDocuments({
type: {
$in: [AppTypeEnum.simple, AppTypeEnum.workflow, AppTypeEnum.plugin, AppTypeEnum.tool]
}
});
if (totalApps >= global.licenseData.maxApps) {
return Promise.reject(SystemErrEnum.licenseAppAmountLimit);
}
}
};

View File

@@ -1,4 +1,8 @@
import type { FastGPTFeConfigsType, SystemEnvType } from '@fastgpt/global/common/system/types';
import type {
FastGPTFeConfigsType,
LicenseDataType,
SystemEnvType
} from '@fastgpt/global/common/system/types';
import {
TTSModelType,
RerankModelItemType,
@@ -17,6 +21,7 @@ declare global {
var feConfigs: FastGPTFeConfigsType;
var systemEnv: SystemEnvType;
var subPlans: SubPlanType | undefined;
var licenseData: LicenseDataType | undefined;
var workerPoll: Record<WorkerNameEnum, WorkerPool>;
}

View File

@@ -148,6 +148,9 @@
"code_error.plugin_error.not_exist": "Plugin Does Not Exist",
"code_error.plugin_error.un_auth": "Unauthorized to Operate This Plugin",
"code_error.system_error.community_version_num_limit": "Exceeded Open Source Version Limit, Please Upgrade to Commercial Version: https://tryfastgpt.ai",
"code_error.system_error.license_app_amount_limit": "Exceed the maximum number of applications in the system",
"code_error.system_error.license_dataset_amount_limit": "Exceed the maximum number of knowledge bases in the system",
"code_error.system_error.license_user_amount_limit": "Exceed the maximum number of users in the system",
"code_error.team_error.ai_points_not_enough": "Insufficient AI Points",
"code_error.team_error.app_amount_not_enough": "Application Limit Reached",
"code_error.team_error.cannot_delete_default_group": "Cannot delete default group",

View File

@@ -148,6 +148,9 @@
"code_error.plugin_error.not_exist": "插件不存在",
"code_error.plugin_error.un_auth": "无权操作该插件",
"code_error.system_error.community_version_num_limit": "超出开源版数量限制,请升级商业版: https://fastgpt.in",
"code_error.system_error.license_app_amount_limit": "超出系统最大应用数量",
"code_error.system_error.license_dataset_amount_limit": "超出系统最大知识库数量",
"code_error.system_error.license_user_amount_limit": "超出系统最大用户数量",
"code_error.team_error.ai_points_not_enough": "AI 积分不足",
"code_error.team_error.app_amount_not_enough": "应用数量已达上限~",
"code_error.team_error.cannot_delete_default_group": "不能删除默认群组",

View File

@@ -147,6 +147,9 @@
"code_error.plugin_error.not_exist": "外掛程式不存在",
"code_error.plugin_error.un_auth": "無權操作此外掛程式",
"code_error.system_error.community_version_num_limit": "超出開源版數量限制請升級商業版https://tryfastgpt.ai",
"code_error.system_error.license_app_amount_limit": "超出系統最大應用數量",
"code_error.system_error.license_dataset_amount_limit": "超出系統最大知識庫數量",
"code_error.system_error.license_user_amount_limit": "超出系統最大用戶數量",
"code_error.team_error.ai_points_not_enough": "AI 點數不足",
"code_error.team_error.app_amount_not_enough": "已達應用程式數量上限",
"code_error.team_error.cannot_delete_default_group": "無法刪除預設群組",